Lokiedu / libertysoil-site

GNU Affero General Public License v3.0
8 stars 5 forks source link

All used tags by type #926

Open xekc opened 7 years ago

xekc commented 7 years ago

Concept design

2017-mlbf4

In this concept interface user is able to see an alphabetical list of all hashtags on the site. You can See alphabetical sub-headers and then alphabetical list of all tags with counters (used times).

Implementation

Integration

This sidebar with full tags list by type will be developed further with added filters (show only my own tags, show only tags from Europe etc.) and further selection features. The point of going to sidebar for the user is to explore content in various perspectives that he finds relevant to his situation.

We will call this sidebar from random pages. We'll want request operators to be implemented - so that the list of tags that opens in sidebar is pre-filtered by URL parameters, sorted not alphabetically but by last modified, by number of user engagements. That will follow in further tasks. Right now we need a solid client side + basically the same server side that tag clouds have, revised and re-thought through in new context (how would "Load more" work if there's 100k tags?).

artkravchenko commented 6 years ago

@voidxnull, @indeyets, @xekc,

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

Предлагаю создать контроллер вида /tags/all (по аналогии с /posts/all), который может выдавать или сплошной массив значений (тегов), или их группы, сформированные по какому-либо признаку (интерфейс слева на скриншоте). Таким образом, значением "верхнего уровня" является либо тэг, либо группа тэгов. Группа выглядит подобным образом:

type TagGroup<T> = {
  count:   number,    // число всех тэгов, приналеджащих группе
  entries: Array<T>,  // массив тэгов с числом элементов N <= query.group_limit
  offset:  number,
  key:     string,    // признак группировки
  value:   string     // значение по ключу key, общее для тэгов в группе
          // (в случае с query.group_by === 'first_letter' обозначает заголовок группы)
}

Отсюда следующие query-параметры:

Позже появится фильтрация по пользователям:

Тогда запрос внутрь категории хэштэгов, собранной по первой букве названия, может быть выполнен следующим образом:

GET /api/v1/tags/all?q=A&sort=-q&type=hashtag

Запросим группированный список:

GET /api/v1/tags/all?group_by=first_letter&group_sort=-post_count&sort=-first_letter&type=hashtags

В рамках store результат может выглядеть примерно так:

store = {
  rivers: {
    sidebar_tags: {
      queries: {
        'group_by=first_letter&group_sort=-post_count&sort=-first_letter&type=hashtags': [
          {
            count: 20,
            entries: ['uuid_1', 'uuid_2'],
            key: 'starts_with',
            value: 'A'
          }
        ],
        // дополняемый массив, используемый на странице отдельной группы
        'sort=-post_count&starts_with=A&type=hashtags': [
          'uuid_1',
          'uuid_2'
        ]
      }
    }
  },
  hashtags: {
    'uuid_1': {},
    'uuid_2': {}
  }
}

В целом из-за будущего внедрения поиска и фильтрации здесь, вероятно, имеет смысл провести рефакторинг существующего клиентского кода, обслуживающего поисковую функциональность, чтобы осуществлять code sharing. Во всяком случае в store для кэширования результатов.

voidxnull commented 6 years ago

@Oopscurity Если често, мне не нравится один большой контроллер. В частности, параметр type вместо трех котроллеров по типу. Для отдельных контроллеров точно так же можно сократить копипасту выносом общего кода. Поиск по всем типам тегов одновременно (кроме общего поиска по всем сущностям), как я понимаю, не нужен? Со всем остальным согласен.

Еще думаю что не стоит использовать query string как ключ в объекте: сложно будет отлаживать, когда порядок параметров где-нибудь случайно поменяться. Можно использовать объект как ключ, но тогда придется менять сериализацию store, т.к. json этого не поддерживает.

artkravchenko commented 6 years ago

@voidxnull,

Поиск по всем типам тегов одновременно (кроме общего поиска по всем сущностям), как я понимаю, не нужен?

Вроде бы, не нужен. @xekc, стоит рассчитывать на появление этого в будущем?

не стоит использовать query string как ключ в объекте

Только что проверил: this.context.router.location.query (или this.props.location.query для routes) является объектом с упорядоченными по алфавиту ключами. Например, для

?b=b&cb=c&c=c&ca=c&a=a

результатом вызова Object.keys(this.props.location.query) является

["a", "b", "c", "ca", "cb"]

С другой стороны, мы можем считать поступающие в reducer данные априори не упорядоченными и исправлять эту ситуацию самим, попутно выкидывая лишние свойства (limit и др. - см. пример).

artkravchenko commented 6 years ago

@xekc,

  • [ ] (COULD Have) We'll likely need auto-load on scrolling here. @Oopscurity can you do it?

Right now we need a solid client side + basically the same server side that tag clouds have, revised and re-thought through in new context (how would "Load more" work if there's 100k tags?)

Basically, we need to perform a bunch of optimizations to support real infinite scrolling when there are many elements to be rendered. After some investigation of the field, I have to say there aren't many possible ready-to-use open-source solutions and all of them have caveats. The task's complexity actually depends on the requirements and use cases such as support the scrolling to the given item in the river.

For example, it's important to know exact size (height) of the river elements before rendering them and it's recommended not to change their size dynamically (especially with screen size change) for the performance reasons.

react-list library seems the most suitable of the solutions. I'll use it to implement infinite scrolling here (#926). Most likely we'd like to migrate our existing rivers of posts to the scenario further since the performance of long ones is terrible.

artkravchenko commented 6 years ago

@xekc, было бы здорово узнать, как именно будет реализовано постраничное разбиение элементов и к чему именно (к каким элементам) оно будет применяться, познакомиться со сценариями использования. От этого зависит, как следует организовать хранение и обновление данных интерфейса для его гибкого использования в будущем: в контексте поиска, фильтрации и отображения каких-либо пользовательских реакций.

Твое упоминание о разном количестве потенциально однородных элементов (тегов) на разных страницах внутри одной и той же группы (?) запутывает, в связи с чем в данный момент (пока не будет оформлена отдельная задача про paging) списки тегов внутри категорий будут также выполнены с расчетом на автоматическую загрузку, как и интерфейс с группами тегов.

Какое максимальное количество элементов может находиться на одной странице? (Ты говорил, что вполне может быть и более ста.) Планируется ли для списков тегов также вариант с автоматической загрузкой, а для категорий - с постраничным разделением?

Планируется ли использование клавиатуры для взаимодействия с элементами, как мы это видим в концепте публикаций?