# Tochka.Stories
## Одним запросом получаем все, что нужно (список + детали)
```json=
{
"id":"C3C54AC4-E22F-48DB-ACB0-56B052CE4300",
"jsonrpc":"2.0",
"result":{
"stories":[
{
"position":0,
"data":{
"story_id":"6541",
"status":{
"is_viewed":false,
"is_shareable":true,
"is_likeable":true
}
},
"template":{
"data":{
"preview":{
"name":"Приходи работать айосером в Точку",
"background":{
"gradient":{
"colors":[
],
"direction":"vertical"
}
},
"icon_background":{
"image_url":"https://tochka.com/stories/media/images/preview_image.png",
"gradient":{
"colors":[
],
"direction":"horizontal"
}
}
},
"content":{
"type":"story-page",
"page":"1",
"properties":{
"background":{
"image_url":"https://tochka.com/stories/media/images/first_page_image.png",
"gradient":{
"colors":[
],
"direction":"vertical"
},
"blur":false
},
"actions":[
{
"trigger":"on_open",
"action":{
"type":"send_web_analytics",
"parameters":"{}"
}
}
]
},
"content":[
{
"type":"label",
"description":"Хочешь работать в Точке iOS разработчиком?",
"properties":{
"font_name":"TTNormsTochkaExt-Bold",
"font_size":30,
"font_type":"bold",
"font_color":{
"hex":"#ffffff",
"alpha":1
},
"alignment":"leading"
}
},
{
"type":"label",
"description":"Молодец, хоти дальше",
"properties":{
"font_name":"TTNormsTochkaExt-Regular",
"font_size":16,
"font_type":"regular",
"font_color":{
"hex":"#ffffff",
"alpha":1
},
"alignment":"leading"
}
}
]
}
}
}
}
]
}
}
```
**Вопросы:** (Дамир)
1) Кажется `stories` поле избыточно, можно предавать в `result` сразу массив
2) нам точно нужно поле `position`? вроде говорили, что как бэк отдает – так и отображаем
3) можно схлопнуть и `template` и `data` и оставить `{ story_id, is_viewed, preview, content }` на одном уровне вложенности
4) нам нужен флаг `is_shareable`? вроде обсуждали, что шарить истории наружу мы не сможем и не будем это делать
5) зачем флаг `is_likeable`? разве мы не можем лайкнуть все сториз?
**Про `preview`:**
1) не помню чтобы обсуждали градиенты в превьюхе. возможно только два варианта – `заливка + растр поверх` либо просто `растр`. Это можно выразить в простой структуре `preview: { name: "", fill_color: "#fff", image_url: "" }`. Если заливка не нужна – ее можно просто не присылать.
**Про `content`:**
1) `type: "story_page"` – а у нас разве может быть что то другое? Пока кажется избыточным
2) где то должен быть обозначен массив `pages`
3) `page: 1` – это указатель на то, с какой странички открывать?
**А теперь про рендер**
Хочется сделать так, чтобы рендер был максимально простым в плане:
– процесса рендера объектов на странице
– последовательности рендера
– гибкости в добавлении новых объектов для рендера и масштабируемости
не хочется делать все на ручнике и превращать ответ бэкенда в кучу `properties`
*Мое предложение ввести следующие определения:*
**Страница** – это набор слоев которые рендерятся последовательно и независимо друг от друга.
**Слой** – это объект, имеющий собственный набор параметров и который клиент умеет отрендерить.
Отрендерить страницу == отрендерить все слои от первого до последнего. За отрисовку каждого слоя ответственнен свой рендерер (привет solid).
Пример:
```json=
layers: [
{ // идем по массиву и отрисовываем по очереди
// понимаем что слой – это изображение
// передаем соответствующему рендереру
type: "IMAGE",
// рендерер ожидает параметры для отрисовки
params: {
// в данном случае мы просто грузим картинку по урлу
// и размещаем
url: "",
// понимаем как разместить изображение
// растянуть, разместить по центру, или обрезать по вьюпорту и тд
scale_type: "fitXY" // center, center_crop etc
}
},
// после того как отрисовали изображение
// переходим к отрисовке следующего слоя (поверх предыдущего)
{
// понимаем что слой это блок с текстом
// передаем соответствующему рендереру
type: "TEXT_BLOCK",
params: {
title: "",
subtitle: "",
gravity: "top" // center, bottom
}
}
]
```
Как итог: получаем страничку с фоновым изображением и текстом поверх него.
- Масштабировать просто – можно добавлять возможности и параметры каждому слою и прокачивать рендереры
- Можно добавлять новые типы слоев – видео, кнопки, гифки, опросы и тд
- Гибкость в кастомизации – мы не рассуждаем в терминалогии шаблонов и можем наложить хоть две картинки друг на друга, хоть текст на текст, что угодно – а значит можем очень гибко настраивать внешний вид
**Про лэйауты:** (Гоша)
Вопрос - как мы будем специфицировать разные лэйауты элементов? Для начала хотя бы тот же пример с текстом - по дизайну он может быть сверху/снизу/в центре. У gui фреймворков обычно за это отвечает какая-то система лэйаутов так или иначе. Понятно что в полном объеме такая система тут скорее оверкилл, но мб есть смысл вдохновиться оттуда базовыми вещами?
**Еще одна попытка:** (Гоша)
Я попробовал описать [пример из фигмы](https://www.figma.com/file/UKAwDJcmhh9olLxyofuStK/%D0%A1%D1%82%D0%BE%D1%80%D0%B8%D0%B7-Mobile?node-id=7514%3A58242) с учетом имеющихся предложений. Пока не понятно что делать с font_size и position. Давайте может попробуем этот пример полностью описать?
```json=
{
"version": 1, //по версии можно понять можем ли мы отрендерить эту стори
"story_id": 123,
"is_viewed": false,
"is_likeable": true, // спросить у дизайнеров
// можем добавлять доп поля в будущем
"preview": {
"name": "Соберись с духом",
// опциональные поля, но должно приходить что-то одно
"fill_color": "#a3fb43", // если цвет не приходит, рисуем градиент поверх изображения
"image": "https://tochka.com/stories/media/images/preview_image.png"
}
"pages": [
{
// ...
"content": [
{
"type": "IMAGE",
"params": {
"url": "",
"scale": "fill"
"position": ???
}
},
{
"type": "TEXT",
"params": {
"text": "Соберись с духом",
"position": ???
"font": { // Тут можно договориться о каких-то дефолтных значениях
"name": "TTNormsTochkaExt-Bold",
"type": "regular",
"size": ???
"color": #ffffff",
"alpha": 1
}
}
},
{
"type": "TEXT",
"params": {
"text": "Можно переводить на любые российские банки",
"position": ???
"font": {
"name": "TTNormsTochkaExt-Bold",
"type": "regular",
"size": ???
"color": #ffffff",
"alpha": 1
}
}
},
{
"type": "BUTTON",
"params": {
"text": "Подробнее",
"position": ???
"font": {
"name": "TTNormsTochkaExt-Bold",
"type": "regular",
"size": ???
"color": #ffffff",
"alpha": 1
},
"action": {
"type": "link",
"url": ""
}
},
}
]
},
]
}
```
## Layers/Content (названия типов обсуждаемы)
### Объект FULLSCREEN_IMAGE
```json=
{
"type": "FULLSCREEN_IMAGE",
"params": {
"url": "",
// пока будет только один параметр center_crop
// по фигме вроде бы других не предусматривается
// те мы не будем растягивать картинку по XY
"scale": "center_crop"
// TODO вероятно список параметров будет расширяться
}
}
```
### Объект FULLSCREEN_FILL (заливка цветом или градиент)
```json=
{
"type": "FULLSCREEN_FILL",
"params": {
"fill_color": "#333333",
// надо уточнить у дизайнеров по градиенту и как его параметризовать
"gradient": {
"colors":[],
"direction":"horizontal"
}
}
}
```
### Объект TEXT
```json=
{
"type": "TEXT",
"params": {
"position": "top", // bottom, center
"align": "left" // center, right
"text": "Соберись с духом",
"style": "TS700_3XL", // стили Christina DS
"color": "#333333",
// можно описать в отдельную сущность, применимую
// к каждому объекту
"margins": {
"top": 0,
"left": 0,
"right": 0,
"bottom": 40
}
}
}
```
### Объект TEXT_SEQUENCE (тексты, идущие один за другим)
```json=
{
"type": "TEXT_SEQUENCE",
"params": {
"position": "top", // bottom, center
"margins": {
"top": 0,
"left": 0,
"right": 0,
"bottom": 0
},
"sequence": [
{
"text": "Соберись с духом",
"style": "TS700_3XL", // стили Christina DS
"color": "#333333",
"margins": {
"top": 0,
"left": 0,
"right": 0,
"bottom": 0
}
},
{
"text": "Можно переводить на любые российские банки. ",
"style": "TS400_XL", // стили Christina DS
"color": "#333333",
"margins": {
// отступ от предыдущего текста в последовательности
"top": 30,
"left": 0,
"right": 0,
"bottom": 0
}
}
]
}
}
```
### Объект BUTTON (кнопка)
предлагаю пока не описывать тк не будет в мвп