Giter VIP home page Giter VIP logo

rss-reader's People

Contributors

dasha6elka avatar

Watchers

 avatar

rss-reader's Issues

Абстрактно названа функция onButtonClick(Sidebar.js:16) и onFormButtonClick(Sidebar.js:20)

При виде данного названия и зная, что мы в файле Sidebar.js, я смог построить весьма скудное умозаключение: "Эта функция сработает при нажатии какой-то кнопки в Сайдбаре". Нужно назвать более конкретно. При этом ниже есть функция onFormButtonClick, которая чуть уточняет своё местоположение, но всё равно есть неопределённость, так как в средних формах не всегда одна кнопка фигурирует.

Упрощение onChannelDelete

function onChannelDelete(index) {
if (channels[index].editable === true) {
return;
}
channels.splice(index, 1);
setChannels([...channels]);
}

Вроде должно сработать так:

function onChannelDelete(index) { 
   if (channels[index].editable === true) { 
     return; 
   } 
   setChannels(channels.splice(index, 1)); 
 } 

Омагад! Омагад! Скример!

Здравствуйте! Я впечатлительный хаброфил. Я добавил категорию "Программирование", в неё пытался добавить ленту habr'а, но при нажатии на кнопку "Добавить" упал со стула от испуга:
изображение

UX фильтрации при отсутствии статей

2019-07-29_10-47-18
Тонкий момент UX: когда человек на что-нибудь нажимает, что-то вводит и ожидает, что что-то произойдёт - должно что-то происходить. Здесь же ничего не происходит, потому что технически нечему происходить, так как нечего фильтровать. Но это понимают только сверхразумы, типа тебя и твоего кота, например.
Можно избежать психологических травм пользователей, если, например, дизейблить поле ввода, если фильтровать нечего. На самом деле это не идеальный вариант, а скорее просто дешёво-приемлимый, так как есть минус: всё, что дизейблится, должно поясняться (нельзя задизейблить и не показать рядом какую-то подсказочку, мол почему задизейблено)

Неунифицированный подход функций onCategoryDelete и onChannelDelete

onCategoryDelete принимает в параметрах список категорий и id категории, которую нужно удалить,
onChannelDelete принимает только id канала, который нужно удалить.
Почему было решено сделать разный подход одной и той же по типу операции?

Почему-то кнопка "Новая категория" не нажимается

Здравствуйте! Я начинающий в вашей системе, столкнулся с трудностью добавления новой категории. Я нажал на кнопочку "Новая категория". Эта кнопочка скакнула вниз, вместо неё появилось какое-то поле ввода с иконкой удаления. Я нажал на "Новая категория" ещё раз, но она уже не нажимается. Я сломал вторую мышку, она всё равно не нажимается. Я ничего не понимаю. Памагити.
изображение

Рефакторинг функции onClick(Channels.js:55)

function onClick(id, rss_url) {
context.channels.forEach(item => {
if (item.id === id) {
item.active = true;
}
if (context.activeChannel && item.id === context.activeChannel.id && item.id !== id) {
item.active = false;
}
});
context.onChannelsChange([...context.channels]);
context.onActiveChannelChange({ id: id, rss_url: rss_url });
}

if (item.id === id) {
    item.active = true;
}
if (context.activeChannel && item.id === context.activeChannel.id && item.id !== id) {
    item.active = false;
}

Можно вроде упростить длинное выражение с помощью else:

if (item.id === id) {
    item.active = true;
} else if (context.activeChannel && item.id === context.activeChannel.id) {
    item.active = false;
}

Упрощение onChangePostsList

{
posts.map((post, index) => change(post, index, value));
}
setPosts([...posts]);

  1. Зачем обрамлять фигурными скобками?
  2. Вроде бы можно упростить функцию, если учесть тот факт, что .map возвращает новый список

Пустой Select выбора категории RSS-ленты

Я, как новый пользователь, поманился на кнопку "Добавить ленту", так как она бросилась мне в глаза. Появилась форма, я начал её заполнять. Но при нажатии на Select выбора категории я увидел что-то дьявольски жуткое:
изображение

post.visible

У объекта "Пост" заметил свойство visible, что означает, что пост может быть видим или не видим. На самом деле пост всегда видим, даже если не полностью, для таких случаев человечество придумало слова expanded (расширен) и collapsed (сжат). Можно взять любое из этих слов и так же как с visible: true/false

Получить дружелюбную дату

мило =)
Но когда речь идёт о видоизменении даты под конкретные ситуации, то говорят "форматирование даты":
function formatDate(date)

Рефакторинг функции onChannelDelete (Channels.js:13)

  • Не понятно, почему мы принимаем в параметрах index и id. Зачем нам для удаления канала и индекс в неком списке и идентификатор удаляемого канала? Кажется, достаточно что-то одно.

  • Можно вынести дублирующие длинные обращения в переменную:
    2019-07-26_11-59-18
    кажется, можно назвать это "channelToDelete" и "channelToChange".
    Дабы это было не похоже на просто "так надо", попробую объяснить этот момент:
    Пусть у нас какой-то персонаж игры, хранится в списке всех персонажей, у него есть функция "съесть пищу", которая снизит его голод, повысит уровень жизни и улучшит настроение:

function eatFood(playerIndex, food) {
    players[playerIndex].starvationLevel -= food.caloriesLevel;
    players[playerIndex].healthPoints += food.healthPoints;
    players[playerIndex].mood += food.moodLevel;
}

А теперь прочитаем эту функцию:
Функция "съесть пищу" принимает индекс игрока и пищу.
Уменьшаем уровень голода у игрока из списка игроков по индексу playerIndex на уровень калорийности пищи.
Увеличиваем очки жизни у игрока из списка игроков по индексу playerIndex на очки жизни пищи.
Увеличиваем настроение у игрока из списка игроков по индексу playerIndex на уровень настроения пищи.

А теперь вынесем общую часть в переменную:

function eatFood(playerIndex, food) {
    const player = players[playerIndex];
    player.starvationLevel -= food.caloriesLevel;
    player.healthPoints += food.healthPoints;
    player.mood += food.moodLevel;
}

Функция "съесть пищу" принимает индекс игрока и пищу.
Берём игрока из списка игроков по индексу.
Уменьшаем его уровень голода на уровень калорийности пищи.
Увеличиваем его очки жизни на очки жизни пищи.
Увеличиваем его настроение на уровень настроения пищи.

  • В конце метода вызывается onChannelDelete, затем onChannelsChange, при этом onChannelDelete вызывает setChannels, причём дважды, затем onChannelsChange выывает ещё один setChannels. То есть в итоге вызывается трижды. Зачем так?

Полоска под списком категорий

изображение
На самом деле по дизайну имелось ввиду, что эта полоска - часть компонента ввода текста в Material. Но я тут подумал, что полоска вообще не нужна тогда уж

Слово-паразит "data"

<List
activeCategory={context.activeCategory}
onActiveCategoryChange={context.onActiveCategoryChange}
onActiveChannelChange={context.onActiveChannelChange}
data={context.categories}
onChange={context.onCategoriesChange}
onFinish={context.onCategoriesFinish}
onDelete={context.onCategoryDelete}
channels={context.channels}
/>

Слово "data"(данные) - это очень привлекательное слово для программистов, потому что подходит практически в каждом случае в силу своей абстрактности. В то же время абстрактность мешает человеку понять конкретность (капитан очевидность). Код будет намного понятнее, если таких абстрактностей будет как можно меньше.
В данной конкретной ситуации можно назвать аттрибут "items"... или "entries"... или "elements". Если верить гуглу, если List - тип данных в программировании, - то у него "elements", а если List - список в пользовательском интерфейсе, - то у него "items"

Введите название поста

2019-07-26_14-14-55
Но зачем я должен это делать? Не понятно. Даже при том, что у поле ввода есть иконка лупы, это может натолкнуть у австралопитека на как минимум 2 предположения:

  1. "Я введу название поста, он будет искаться словно как в гугле, и я смогу его прочитать"
  2. "Я введу название поста, тем самым быстрее найду его из списка"

Рефакторинг функции onChannelItemChange(Channels.js:30)

Здесь проблема в том, что функция выполняет разные действия в зависимости от параметра. Пришли в голову 2 альтернативы:

  1. Channel вызывает разные callback'и (onTitleChange и onLinkChange) вместо использования одного лишь onChange. Таким образом в Channels.js будут два трёх-строчных метода.
  2. Channel вызывает onChange, но передаёт туда весь объект канала с полями title и link. Таким образом в Channels.js метод onChannelItemChange присвоит все поля, даже если какие-то из них не были реально изменены, но это не считается плохим подходом:
function onChannelItemChange(index, newChannel) {
    const channelToChange = context.channels[index];
    channelToChange.editable = true;
    channelToChange.title = newChannel.title;
    channelToChange.rss_url = newChannel.rss_url;
    context.onChannelsChange([...context.channels]);
}

Непонятный интерфейс при отсутствии каких-либо RSS-лент и категорий

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

  • Что за пустые прямоугольники?
  • Что за поле поиска и почему ничего не происходит, когда я ввожу там текст?
  • Что происходит?

Нужно что-то придумать с этим. Интерфейс должен проявлять любовь, заботу и нежность по отношению к пользователям :)

Смешанные чувства от формы добавления RSS-ленты

изображение
Мне понравилось, что не открывается какое-нибудь всплывающее окно с формой, а всё происходит "не отходя от кассы". Однако есть и замечания:

  • Между поля ввода нет интервала. Это вызывает проблему только при фокусе какого-либо из полей:
    изображение

  • Пусть категория выбирается из списка существующих с помощью компонента Select

  • Кнопку "Добавить" в Disabled-состоянии можно не заметить:
    2019-07-14_15-52-15

  • Текст в полях ввода еле заметен
    изображение

  • Если выбрать имя ленты из предлагаемого списка, то поле ввода отличается от соседних. Да и вообще зачем предлагать там что-либо. Кажется, этим никто не будет пользоваться. Пусть вбивают без возникающих подсказок
    изображение

Упрощение change

function change(post, index, value) {
const title = post.title.toLowerCase();
if (title.includes(value.value)) {
post.found = true;
} else {
post.found = false;
}
}

Функция в 1-2 строчки (оба варианта норм). А твой вариант читать долго(( пожалей ленивых

Невалидное имя ленты

Заполняю форму добавления RSS-ленты. Решил добавить такую:
Имя: Medium: @dane.mackier
Ссылка: https://medium.com/feed/@dane.mackier
Но почему-то сервис не разрешает задать такое имя, говоря: "Невалидное имя ленты":
изображение
Не понимаю, что такого запретного в таком имени, и сервис даже не удосуживается показать, какие символы разрешены(

Воспользоваться @material-ui/icons

В проекте есть папка icons с SVG-компонентами. Прикольно, но в этом нет необходимости: Material UI предоставляет гугловские иконки Material'а в пакете @material-ui/icons.
В итоге будет на 1 папку с 6 файлами меньше.
Проиграю сценарий, как добавить иконку:

  1. Заходим на сайт https://material.io/tools/icons/?icon=looks_4&style=baseline
  2. Ищем нужную иконку в этом стоге сена. Ну в твоём случае есть лайфхак: в фигме в структуре элементов имена иконок соответствуют Material Icons именам:
    изображение
    (чтобы не ползать по структуре, можно натыкать на саму иконку в интерфейсе фигмы)
  3. Запомнить имя иконки:
    изображение
  4. Мысленно перевести в UpperCamelCase: ExpandLess, ExpandMore
  5. Это и будет именами компонент нужных иконок
    (импорт будет таким: @material-ui/icons/ExpandLess и @material-ui/icons/ExpandMore)

Упрощение кода с помощью готовых компонентов Material UI

Приведу пример.
У тебя разметка всё же осталась с прямым использованием CSS. Есть компонент Grid, который позволяет сделать всё почти без CSS:
изображение
изображение
изображение
изображение
Выглядит вроде бы также:
изображение

По Diff'у видно, что кода приубавилось чуток, и это я лишь самый-самый верх структуры приложения заменил. Надо везде так же. Как можно меньше CSS, как можно меньше не Material UI компонент =)

Непонятные имена функций в App.js

onCategoriesFinish(App.js:45). Эта функция вызовется, когда категории завершатся?
onChannelFinish (App.js:53). Эта функция вызовется, когда каналы завершатся?

Warning: "Each child in a list should have a unique "key" prop."

изображение
Шаги для воспроизведения (способ 1):

  1. Нажать на кнопку "Добавить ленту"
  2. Нажать на кнопку "Новая категория"

Шаги для воспроизведения (способ 2):

  1. Нажать на кнопку "Новая категория"
  2. Нажать на кнопку "Добавить ленту"

Не подсвечивается активный элемент списка категорий RSS-лент

Судя по кол-ву лент, при первоначальной загрузке приложения показываются RSS-ленты из категории "Программирование", однако сам элемент списка никак не индицируется. По дизайну активный элемент имеет один стиль, а наведённое состояние индицируется по-другому:
изображение

Использовать встроенный метод строки "padStart"

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

function normalizeDateNumber(number) {
if (number.toString().length === 1) {
return `0${number}`;
}
return number.toString();
}

может быть заменена с помощью метода типа данных "string":
https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/String/padStart

Упростить выражения

function onClick(id, editable, count) {
data.forEach(item => {
if (item.id === id && !editable) {
item.active = true;
}
if (activeCategory && item.id === activeCategory.id && item.id !== id && !editable) {
item.active = false;
}
});
onChange([...data]);
if (editable) {
return;
}
onActiveCategoryChange({ id: id, count: count });
onActiveChannelChange(null);
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.