[Шаг 3. Проектируем интерфейс] Клиент GOLOS для Android/iOS на Delphi.
Мобильные приложения это уникальный вид приложений. Их особенность в том, что
- они должны работать как на маленьких, так и на относительно больших экранах
- мобильные ОС однозадачны, т.е. когда мы из приложения переключаемся, оно "засыпает"
- у пользователя все время один контекст, т.е. он может работать одновременно только с одним окном (что не мешает нам эмулировать несколько окон на экране, но "неполноценных")
Как вы помните из прошлого урока, мы выбрали шаблон приложения с заголовком, подвалом и навигацией. Мы немного дополним и изменим интерфейс. В верхней части формы у нас есть ```TopToolBar```. В его центр добавим компонент ```TcomboBox``` и назовем его ```ThemeBox```. В нем мы будем выбирать какой тип ленты данных нам будет показываться. Тут же есть 2 кнопки навигации, которые достались нам в наследство от шаблона. Не думаю, что мы их будем использовать, так как навигации осоой у нас не предвидится, но выбрасывать пока что тоже не будем.
Большую часть формы занимает компонент ```TTabControl```. Именно он будет основой нашего приложения. Так как корешков его закладок не видно, а самих их может быть довольно много, то переключение между закладками будет восприниматься пользователем как открытие нового экрана приложения. Кроме того, мы всегда можем создать новую закладку динамически и вывести на нее информацию, а после показать пользователю, что будет для него эквивалентно открытию нового экрана.
На первую закладку поместим компонент ```TListView```. В нем мы будем отображать ленту сообщений. Он конфигурируется не очень очевидным образом. Во-первых он имеет ряд свойств как потомок ```TControl```, а во-вторых мы можем сконфигурировать внешний вид отдельной строки - ```TListViewItem```. И не забудем прикрепить к нему компонент ```TImageList```, который отвечает за хранение и отображение картинок для каждой заметки. Пока что мы загрузим в него всего пару картинок в тестовых целях. Это будет логотип GOLOS. И выставим в `true` свойство ```SearchVisible```, оно позволит нам искать по заголовкам ленты.
Для самой строки выставим следующие параметры:
А именно, укажем что мы будем выводить в строке картинку, а помимо заголовка еще и подробную информацию. И зададим размеры картинки для поста:
Для начала нам этого хватит. Теперь пришла пора задуматься о том как вывести данные.
Здесь я сделаю небольшое лирическое отступление о процессе программирования. Часто, при работе над большими проектами применяют принципы декомпозиции, пилят все по частям и делают окончательную сборку в конце. А потом еще раз обрабатывают все напильником. Я же человек иного склада характера и придерживаюсь более понятной и близкой мне идеологии, которая гласит, что нужно сделать сначала минимально работающее приложение и уже потом итерациями доводить его до ума. Зато сразу видно, что у нас будет получаться.
Итак, нам нужно получить данные блокчейна голос, чтобы вывести их в нашем ```ListView```. Данные можно получить по технологии WebSocket с сервера голоса. Но есть и еще один путь, на который меня натолкнуло одно из обсуждений, что при плохом интернете GOLOS плохо работает, так как требователен к трафику. Не могу не согласится. Блокчейн самодостаточен, но для некоторых применений избыточен. Поэтому у нас есть еще один путь, получить нужные данные блокчейна запросом из БД Sql Server, любезно предоставленной сообществу @arcange. Мы планируем сделать некоторое дублирование в дальнейшем, чтобы можно было обращаться как к серверу БД, так и к WebSocket, скорее всего, на выбор. Но пока изберем более простой путь работы с БД. Он потребует наличия компонентов UniDAC, они кроссплатформенные и умеют работать с MS SQL Server.
Кладем на форму ```UniConnection```, ```SQLServerUniProvider``` и ```UniQuery```. Они сами друг друга найдут. Для ```UniConnection``` устанавливаем параметры доступа к серверу sql.golos.cloud. Теперь, на событие ```OnCreate``` формы пишем вот такой код:
```procedure THeaderFooterwithNavigation.FormCreate(Sender: TObject);
var
Item: TListViewItem;
I: integer;
Details: string;
begin
{ This defines the default active tab at runtime }
TabControl1.First(TTabTransition.None);
UniConnection.Connect;
if UniConnection.Connected then
begin
UniQuery.SQL.Clear;
UniQuery.SQL.Add('select top(30) * from TxComments where title <> '''' and parent_author = '''' order by id desc');
UniQuery.Open;
if UniQuery.RecordCount > 0 then
begin
UniQuery.First;
for I := 0 to UniQuery.RecordCount - 1 do
begin
Item := ListView.Items.Add;
Item.ImageIndex := 0;
Item.Text := UniQuery.FieldByName('title').AsString;
Details := ClearMarkdown(ConvertHTML(UniQuery.FieldByName('body').AsString));
Item.Detail := Copy(Details, 1, 40) + sLineBreak + '@' + UniQuery.FieldByName('author').AsString;
UniQuery.Next;
end;
end;
end;
end;<CR>```
Здесь есть 2 функции, которых нет в Joomla. Они помогают нам вывести "очищенный" текст начала поста. Это
```ConvertHTML``` - удаляет HTML разметку
```ClearMarkdown``` - удаляет markdown разметку.
Мы вынесли их в отдельный модуль ```GolosUtils```.
Ну что же, ставим целевой платформой Windows (так проще отлаживаться и быстрее компилироваться) и запускаем приложение. УРА! Первые данные уже появились! Они еще корявые, налезают друг на друга, не все выводится красиво, но оно уже работает.
Вот тут продолжение