Создаем блог на Svelte. Часть 8: Лайки

Создаем блог на Svelte. Часть 8: Лайки

Добавляем в наш блок простейшую возможность оценить работу авторов.

Предыдущий материал: Создаем блог на Svelte. Часть 7: Загрузка картинок в оглавление статьи

Создаем новую колонку в Supabase

Начнем с того, что нам необходимо создать раздел в базе данных, в котором будут копиться лайки. Логичнее всего привязать такой раздел непосредственно к статьям. Так будет проще их менять, а еще они будут четко связаны с конкретным материалом. 

Вполне логичным способом реализации такого раздела кажется создание числового значения в базе данных, которое можно кликом в программе менять на более высокое значение. Чтобы это сделать создадим в Supabase колонку likes, в которой будут храниться значения в формате int8. Нам необязательно делать их уникальными или запрещать с помощью NULL. Нужно лишь выставить значение по умолчанию. В нашем случае – это 0. 

Колонка в базе данных

Пока что нам подойдет такая запись. Переходим к следующему этапу разработки. 

Пишем функцию добавления лайков

Нам нужна функция добавления новых лайков, привязанная к статье. Поэтому мы будем добавлять соответствующую возможность прямо в [slug].svelte, где и лежит весь код, отвечающий за рендеринг текста статьи и информации о ней. 

Перед тем как приступить к написанию метода добавления лайков, добавим в код переменную likes, где и будет храниться нужное значение: 

let likes;

Переменная likes

Теперь переходим к функции like.

Метод like

  • Создаем асинхронную функцию like таким образом: const like = async ( ) => { }
  • В теле этой функции увеличиваем значение likes на единицу: likes += 1
  • После этого делаем запрос к базе данных, чтобы обновить количество лайков непосредственно в Supabase, а не только в интерфейсе нашего приложения. Мы делаем запрос, сравниваем статьи с названием открытой статьи и заменяем переменную likes в БД на ту, что сформировалась внутри программы:
 const { data, error } = await supabase.from('Posts').update({ 'likes': likes }).eq('title', title)

Кнопку для активации этой функции добавим в разметку, взяв svg в форме сердечка и прописав где-нибудь под названием статьи. 

Интерфейс рендеринга и добавления лайков

Теперь нужно отобразить количество лайков в интерфейсе, чтобы они добавлялись и об этом было известно всем читателям (иначе зачем еще нужны эти ваши лайки). 

Функция getAmountOfLikes для отслеживания количества лайков

  • Создаем асинхронную функцию getAmountOfLikes таким образом: const getAmountOfLikes = async ( ) => { }
  • Внутри делаем простой запрос к базе, чтобы посчитать наши лайки. Просто выбираем конкретный столбец данных: 
const { data } = await supabase.from('Posts').select('likes').eq('title', title)
  • Затем значение likes обновляем, заменив его на число, выданное базой данных: likes = data[0].likes

Саму функцию потом не забудьте забросить в onMount, чтобы она автоматически срабатывала при каждой загрузке страницы. 

Блок onMount

Готово. Но наша функция сейчас работает некорректно. Во-первых, один пользователь может ставить неограниченное количество лайков любой публикации, что не особо-то вяжется с концепцией лайков. Такой подход ближе к соцсетям в духе TikTok и Instagram, где есть стриминг. Во-вторых, никоим образом не фиксируется факт лайка со стороны конкретного пользователя, то есть непонятно, кому понравился пост. Зарегистрировать это попросту невозможно. По этой причине мы сейчас будем рефакторить код и корректировать работу базы данных. 

Это пример того, как, казалось бы, простая идея может завести в тупик при первоначальной реализации. Если вы новичок, то вы часто будете попадать в ситуации, когда нужно переписывать код, чтобы изменить логику работы приложения, потому что часто тот алгоритм, что работает для одного формата, совсем не подходит для другого. 

Заставляем функцию добавления лайков работать корректно 

Есть несколько вариантов реализации более корректного добавления и отображения лайков. Мы выберем следующий путь – создадим массив с именами пользователей, которым понравилась статья и будем пополнять его, когда очередной читатель нажимает на заветную иконку с сердечком. Так мы сможем и узнать, ставил лайк человек или нет, и при этом легко посчитать общее количество лайков у поста. Простой, логичный и легкомодифицируемый алгоритм. 

Перед началом надо удалить из базы данных старый столбец likes и заменить на новый, в котором тип данных будет не int8, а text[] (то есть массив с буквами). Все настройки видно на скриншоте. 

Обновленные настройки колонки likes

Следующий этап – небольшая переделка функции like, которую мы создали ранее. 

Обновленный метод like

  • Мы также делаем асинхронную функцию. 
  • Отличие только в первом шаге – нужно не увеличивать значение likes на единицу, а пушить в массив лайков имя пользователя или его id (человека, который сейчас читает статью). Я использую переменную author для примера. Вам нужно будет заменить ее на id или имя пользователя, который зашел в приложение, введя пароль. Получилось likes.push(author)

Теперь нужно отобразить количество лайков. Для этого создадим новую переменную, в которой будут храниться не имена или id пользователей/авторов, а общее число лайков. По умолчанию оно должно быть равно нулю: let likesCount = 0

Обновленная функция getAmountOfLikes

Формировать это значение будем внутри функции getAmountOfLikes, созданной нами ранее. 

Переменная likesCount

  • Оставляем асинхронную функцию getAmountOfLikes. Код: const getAmountOfLikes = async ( ) => { }
  • Оставляем такой же запрос к базе данных. 
  • Лайки берем те же.
  • Меняем только значение переменной likesCount. Ее легко вытащить, взяв длину массива: likesCount = likes.length

Осталась только одна деталь. Надо сделать так, чтобы лайк можно было ставить единожды. А если человек ставит его повторно, то он должен исчезать. Для этого снова слегка отредактируем функцию like.

Финальная версия метода like

  • Добавляем проверку наличия лайка от автора. И если в массиве с пользователями, лайкнувшими пост, есть искомое имя, то мы удаляем его из массива: 
if (likes.includes(author)) { likes.splice(likes.indexOf(author), 1 }
  • А если соответствие не найдено, то добавляем автора в список лайкнувших, параллельно увеличивая значение переменной likesCount (это нужно исключительно для визуальной презентации внесенных изменений): 
else { likes.push(author); likesCount++ }

Дизлайки можете попробовать реализовать самостоятельно. Алгоритм тот же, нужно будет изменить только значения. 

Вместо заключения

Как видите, есть два простых способа реализации лайков со всей функциональностью, к которой мы привыкли в социальных сетях и в других блогах. Единственное, чего не хватает – возможности посмотреть, кому понравились те или иные посты. Возможно, мы реализуем соответствующую возможность в будущем (на этапе рефакторинга, например). Либо можете попытаться сделать это самостоятельно и опубликовать статью в Комьюнити на соответствующую тему. 

Если возникли сложности, есть советы, хотите поругать мой код или предложить какую-то идею, то жду вас в комментариях.

источник

Related Posts
AllEscortAllEscort