[ { "id": 1, "label": "100%×150_Branding_desktop", "provider": "adfox", "adaptive": [ "desktop", "tablet" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "cndo", "p2": "ezfl" } } }, { "id": 2, "label": "1200х400", "provider": "adfox", "adaptive": [ "phone" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "cndo", "p2": "ezfn" } } }, { "id": 3, "label": "240х200 _ТГБ_desktop", "provider": "adfox", "adaptive": [ "desktop" ], "adfox": { "ownerId": 228129, "params": { "pp": "i", "ps": "cndo", "p2": "fizc" } } }, { "id": 4, "label": "240х200_mobile", "provider": "adfox", "adaptive": [ "phone" ], "adfox": { "ownerId": 228129, "params": { "pp": "i", "ps": "cndo", "p2": "flbq" } } }, { "id": 5, "label": "300x500_desktop", "provider": "adfox", "adaptive": [ "desktop" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "cndo", "p2": "ezfk" } } }, { "id": 6, "disable": true, "label": "1180х250_Interpool_баннер над комментариями_Desktop", "provider": "adfox", "adaptive": [ "desktop", "tablet" ], "adfox": { "ownerId": 228129, "params": { "pp": "h", "ps": "clmf", "p2": "ffyh" } } }, { "id": 7, "label": "Article Footer 100%_desktop_mobile", "provider": "adfox", "adaptive": [ "desktop", "tablet", "phone" ], "adfox": { "ownerId": 228129, "params": { "p1": "byswn", "p2": "fjxb" } } }, { "id": 8, "label": "Fullscreen Desktop", "provider": "adfox", "adaptive": [ "desktop", "tablet" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "cndo", "p2": "fjoh" } } }, { "id": 9, "label": "Fullscreen Mobile", "provider": "adfox", "adaptive": [ "phone" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "cndo", "p2": "fjog" } } }, { "id": 10, "disable": true, "label": "Native Partner Desktop", "provider": "adfox", "adaptive": [ "desktop", "tablet" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fmyb" } } }, { "id": 11, "disable": true, "label": "Native Partner Mobile", "provider": "adfox", "adaptive": [ "phone" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fmyc" } } }, { "id": 12, "label": "Кнопка в шапке", "provider": "adfox", "adaptive": [ "desktop", "tablet" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "cndo", "p2": "fdhx" } } }, { "id": 13, "label": "DM InPage Video PartnerCode", "provider": "adfox", "adaptive": [ "desktop", "tablet", "phone" ], "adfox_method": "create", "adfox": { "ownerId": 228129, "params": { "pp": "h", "ps": "cndo", "p2": "flvn" } } }, { "id": 14, "label": "Yandex context video banner", "provider": "yandex", "yandex": { "block_id": "VI-223677-0", "render_to": "inpage_VI-223677-0-101273134", "adfox_url": "//ads.adfox.ru/228129/getCode?p1=byaeu&p2=fpjw&puid1=&puid2=&puid3=&puid4=&puid8=&puid9=&puid11=&puid12=&puid13=&puid14=&puid21=&puid22=&puid31=&fmt=1&pr=" } } ]
{ "author_name": "Kat Vance", "author_type": "self", "tags": [], "comments": 42, "likes": 46, "favorites": 3, "is_advertisement": false, "section_name": "blog", "id": "29223" }
Kat Vance
1 215
Блоги

TJ для Windows 10: Финишная прямая

Третья, по всей видимости, последняя публикация из серии «Говорящая кошка пытается в сишарп» (предыдущие: 1, 2). Как всегда отчёт о выполненном, пара вопросов в пустоту и рассказ о первой непреодолимой (поведение компонента зависит только от Microsoft, и никаких хаков изобрести, судя по всему, не получится) трудности, встретившейся на пути. Но обо всём по порядку.

Поделиться

В избранное

В избранном

Что сделано?

Этот месяц был не таким свободным в плане личного времени, как предыдущий, возможности полностью посвятить какой-то день только приложению ни разу не представилось вовсе, потому коммитил маленькими порциями, когда получалось, и потому, собственно, так долго не мог ничего выкатить. Тем не менее, почти всё, что я обещал реализовать в прошлый раз, наконец стало реальностью. Самое время подвести промежуточный итог.

Текст статей

Добавлена поддержка всего, что часто используется: твиты, инстаграм, перелистывающиеся блоки картинок aka «галереи», ссылки, привязанные к новостям, немного переделаны цитаты – в общем, читать материалы уже можно полноценно, не теряя каких-то значимых частей смысла. Единственное, чего ещё нет – поддержки «расширенных» ссылок, которые отображаются с сопроводительной картинкой в большой яркой оранжевой рамке.

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

Навигация

В прошлый раз я не мог выбрать между пагинацией и бесконечным скроллом в качестве основного способа перемещения по страницам. Жизнь расставила всё на свои места: в Win 10, оказывается, нет встроенной возможности отслеживать положение ScrollView, и есдинственный способ сделать бесконечный скролл – писать костыль, реагирующий на появление в видимой области какого-то конкретного элемента. Это не путь джедая, потому был выбран компромиссный вариант:

Преимущества такого подхода в детерминированности: вы сами решаете, когда загружать новую страницу, и ничего не происходит само собой. Основной недостаток в том, что не слишком удобно искать очень старые записи, перейти на, скажем, пятидесятую страницу будет довольно трудно. Также скроллинг слетает к первой записи после прочтнения материала. Серьёзная проблема, которую я осознал только что, пока набирал эту строчку. Будем думать, как решить (скорее всего нужно открывать статью поверх фрейма с новостями, как это реализовано в андроидовом приложении, ок, сделаю).

Поиск

Он работает, не вылетает. Что ещё можно сказать?

Твиты

На следующий же день после публикации предыдущего поста, выяснилась довольно неприятная штука. Оказывается, в твитах, в силу определённых обстоятельств, не отображалось всё, что идёт в тексте дальше первой ссылки. Такую оплошность нетрудно проглядеть, потому что большинство твитов как раз заканчиваются ссылкой, но баг был, и с ним надо было что-то делать.

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

Другие, не инлайновые типы данных добавить в него нельзя, это вызовет ошибку. Поэтому вместо классического TextBlock в RichTextBlock используется Run, картинки в обязательном порядке оборачиваются в InlineUIContainer, и так далее.

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

Однако, обойти его можно. Полностью свободно управлять деревом, удаляя, изменяя и добавляя элементы так, как привыкли веб-разработчики, можно из области code behind'а, ссылаясь на уникальный идентификатор тега. Такие операции немного медленнее, но это не то чтобы прямо уж заметно для конечного пользователя. Загвоздка в том, что я уже написал логику работы с твитами из-под вьюмодели, и переписывать весьма весомую её часть по новой совсем не хотелось.

Ещё не заснули? Ладно, тогда добавлю, что в силу всего вышесказанного, инлайновые данные нельзя напрямую подбиндить к списку, который я генерирую каждый раз из текста твита для того чтобы обеспечить развитое форматирование. Мне очень хотелось как-нибудь подцепить к списку содержимое RichTextBlock, однако, увы, компилятор C# достаточно умён, чтобы не дать разработчику выстрелить себе в ногу, и ничего предсказуемо не получилось.

Но разве такого упорного говнокодера как я остановит такая мелочь как умный компилятор? Ха-ха! Порывшись основательно, я нашёл интересный хак за авторством одного индуса, слегка переделав который, можно было добиться желаемого поведения, что незамедлительно и сделал. В общем, все благодарности за работающие нормально твиты – индусу. Харе Кришна, ёпт.

Чёрный список

Не обещал, даже не планировал, но как-то в процессе задумался о такой возможности, тем более что в фанатских скриптах к тж она давно есть, и на поверку оказывается весьма удобной. Всё что нужно для того чтобы навсегда избавиться от надоевшей личности (да, ЧС работает глобально, даже в поиске, будьте внимательны, удаляя из своей выдачи популярного постера), – это зайти в материал, им написанный, и щёлкнуть по крестику в верхнем левом углу аватарки. Больше он вас не побеспокоит.

Для того чтобы амнистировать персонажа, зайдите в Настройки → Чёрный список, и уберите соответствующую ему запись из списка. Там же можно, зная ID, вручную добавить аккаунты для игнорирования.
Важно: в отличие от остальных настроек, ЧС хранится в локальном файле, в %APPDATA%/Local, и не синхронизируется с аккаунтом Microsoft. Его можно самостоятельно перенести с компьютера на компьютер, но легче, по-моему, создать заново. Энивей, если чё, я предупредил.

Превратности WebView

Вот мы и подобрались к самому главному: к проблеме, решение которой не зависит от меня. Косяк настолько велик, что он один даёт основания печатать буклетики «Вендекапец, покайтесь!» в промышленных масштабах и приставать к прохожим, вербуя всех подряд в секту свидетелей Линуса, но я здесь, к счастью или к сожалению для некоторых, не за этим. Просто расскажу что случилось, с самого начала.

Давным давно, в далёкой галактике... Кхм, нет, не с самого. Так слишком долго будет. Короче, есть такая штука, унифицированный API, типа стандарт, для вставки всяких социальных публикаций во внешние, не связанные с основным источником места. В ответ на запрос он отдаёт предсказуемую информацию в предсказуемом формате так, что ответ твиттера не слишком сильно отличается от ответа инстаграма, и их легко разбирать на всех целевых платформах.

С другой стороны, в силу того, что самый популярный сейчас формат разметки гипертекста – это html+css, а не проприетарный xaml, на котором строится интерфейс винды, данные отправляются в веб-формате, ведь предполагается, что уже каждый калькулятор умеет с ними работать. И правда, движки, интерпретирующие html, уже написаны для всего, но не везде они одинаково хороши.

Так, стандартный WebView в десятой винде, вместо того, чтобы напрямую транслировать контролы из родственного в прицнипе формата в свой, таким образом обеспечивая абсолютную нативность, зачем-то вставляет внешний iFrame фиксированного размера поверх документа, и уже в нём с помощью движка Trident (да-да, пока даже не EdgeHTML!) рисует содержимое. И хуй бы с ним, но предугадать заранее размер твита или блока инстаграма (то, что мы пытамемся вставить) невозможно. Никто, даже сам твиттер не знает, какой высоты окажется отрендеренный блок, поэтому в идеале размер WebView должен бы автоматически изменяться в зависимости от размеров содержимого, или хотя бы должна быть доступна такая опция.

Но нет. Никакого Heights.Auto, вопреки ожиданиям, в свойствах WebView не оказалось. Само собой, о каком-либо подобии андроидовских адаптивных разметок и мечтать не приходится. Даже на оф. форуме поддержки пишут, мол, это неосуществимо в текущих реалиях. Какой-то тип, самолайкнувший свой собственный ответ, вроде бы изобрёл грязнейшее решение, но у меня этот хак не заработал от слова совсем. Sad_trombone.wav

Значит ли это, что твитов и инстаграма не будет? Конечно, нет. Они уже есть. Самый первый скриншот демонстрирует пример вставки инстаграма, а так выглядят твиты:

В одной из тестовых версий они даже выглядели вот так, под стать дизайну всей системы, но после непродолжительной переписки с техническим директором выяснилось, что просто пользоваться отдаваемыми TJ данными принципиально недостаточно, и все норм пацаны в 21 веке юзают oEmbed. Так появилась поддержка социалок в её текущем виде.

Единственная проблема – некоторые твиты как бы «не влезают» в предоставленное им пространство, и в их блоке отображаются полосы прокрутки, а для некоторых наоборот, свободного места слишком много, что приводит к появлнию гигантских отступов между контентом и контентом. Весь этот текст был написан только для того, чтобы снять с себя ответственность за такой вот разметочный пиздец, потому что меня самого он бесит не меньше вашего. Ну, вроде снял, всё. Теперь либо ждать фикса от Майкрософт, что маловероятно, ввиду весьма низкой важности этого вопроса по сравнению с остальными, либо искать обходные пути.

Что дальше?

А ничего. Постепенно, уже без особого азарта, исправлю все оставшиеся шероховатости (такие, как отсутствие кольца загрузки, скрывающего процесс у статей, к примеру), да заморожу проект до лучших времён, занявшись чем-нибудь другим. Цель: сделать свой гитхаб менее пустым, попутно доказав самому себе, что могу создавать целостный рабочий продукт от начала и до конца, более чем достигнута, результат хоть и не устраивает меня на все сто, но и не разваливается на части от каждого неосторожного прикосновения.
Ссылки как всегда:
Гитхаб
Сборка
С исчерпывающим списком изменений можно ознакомиться здесь
Ну всё, всем удачи, держитесь там. Хорошего настроения, здоровья.

Популярные материалы
Показать еще
{ "is_needs_advanced_access": true }

Лучшие комментарии

Дискуссии по теме
доступны только владельцам клубного аккаунта

Купить за 75₽
Авторизоваться

Преимущества
клубного аккаунта

  • отсутствие рекламы
  • возможность писать комментарии и статьи
  • общение с членами клуба
Подробнее

Преимущества
клубного аккаунта

  • отсутствие рекламы
  • возможность читать и писать комментарии
  • общение с членами клуба
  • возможность создавать записи

Сколько это стоит?

Членство в клубе стоит всего 75₽ в месяц. Или даже дешевле при оплате за год.

Что такое клуб?

Клуб ТЖ это сообщество единомышленников. Мы любим читать новости, любим писать статьи, любим общаться друг с другом.

Вступить в клуб

Комментарии Комм.

Популярные

По порядку

0

Прямой эфир

Вы не против подписаться на важные новости от TJ?

Нет, не против