…

    итак, пора браться за дело.

место для длинного вступления*

    Первым делом выбираем сайт, который мы будем использовать как макет. Первое, что пришло в голову, это 4PDA. Это достаточно красивый, и, очень, известный сайт. 

Усложним себе задачу загрузкой списка элементов напрямую с сайта, без api.

    Далее, выбираем язык. В последний раз я писал на Kotlin, значит, переключаемся на Dart

  На скриншоте мы видим:

  • Прокручиваемый список элементов
  • Рекламу сверху и внизу в разных представлениях (Пока не знаю, следует ли её вставлять)
  • Наверху контейнер с логотипом, поиском, кнопкой для входа, вкладки, две обычные кнопки, тёмная кнопка
  • Ниже  поле с текстом и кнопками с обводкой

  Внизу страницы номера страниц и какой-то текст

  Анимации на сайте я не обнаружил, это упростит нам задачу

 

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

 

  Неожиданным моментом оказалось то, что в качестве логотипа страницы используется не привычный SVG файл, а специальный шрифт

const Text(
                "4",
                style: TextStyle(
                  fontFamily: "fontello",
                  fontWeight: FontWeight.normal,
                  fontStyle: FontStyle.normal,
                  color: Colors.white,
                  backgroundColor: Color.fromARGB(255, 0, 114, 188),
                ),
              ),

таким образом у нас выглядит логотип.

 

   Спустя несколько часов рутины мы получаем вот такое меню, надпись HUAWEI, вдруг, оказалась SVG изображанием, потому я использовал flutter_svg для её отображения. При детальном разборе можно заметить неточности размеров, но, это вряд-ли будет критично в нашем проекте, а если будет - ничего не мешает это исправить без особых трудностей.

 

  Я ожидал проблем в этом виджете, но не думал что они будут в кодировке

final a = (await http.Client().get(Uri.parse("https://4pda.to/"))).body;

  Я использовал этот способ обращения к сайту, далее регулярные выражения 

_title = RegExp('title=".+">').firstMatch(o)?.group(0);

Взять название достаточно просто, а вот исправить уже сложнее

При использовании этого

var resp = await http.Client().get(Uri.parse("https://4pda.to/"));
String.fromCharCodes(resp.bodyBytes)

или этого

var resp = await http.Client().get(Uri.parse("https://4pda.to/"));
utf8.decode(resp.bodyBytes)

способа кириллица не отображается.

При этом кодирование и декодирование строк происходит без ошибок.

print((utf8.decode(resp.bodyBytes.sublist(754, 769), allowMalformed: true)));

I/flutter (19851): ����� �� �����

эта строка не подлежит восстановлению.

Та же ошибка происходит при ascii и base64. 

Верной кодировкой оказалась windows-1251

Раз проблему не удалось решить стандартным способом, придётся использовать свой

 

const List cp1251 = [
  '\u0000',
  '\u0001',
  ...
  '\u044E',
  '\u044F'
];

создаём массив символов кодировки

String encode(Uint8List data){
    StringBuffer out = StringBuffer();
    for (int i in data){
      out.write(cp1251[i]);
    }
    return out.toString();
  }

создаём функцию обработки. Работает достаточно быстро, а это значит, что дополнительная оптимизация не нужна

final a = encode((await http.Client().get(Uri.parse("https://4pda.to/"))).bodyBytes);

и обращаемся к функции.

Получаем человеческий.

 

Немного рутины внизу, исправление ошибок, и, наконец, мы получаем результат

На странице ещё остались необработанные детали, вроде, рекламы и изменений дизайна отдельных постов, но для нашего проекта этой работы достаточно

 

Если вам интересно попробовать запустить приложение или посмотреть код результата, переходите по ссылке.

Пишите предложения для подобных проектов, если получилось интересно.