Юрий Петров | Flutter – Telegram
Юрий Петров | Flutter
1.9K subscribers
434 photos
41 videos
16 files
665 links
Привет! 👋
Я руководитель отдела разработки.
Здесь мы изучаем LLM, автоматизацию с n8n, делаем крутые приложения на Flutter и учим их думать с помощью ИИ.
Новости, лайфхаки, интересные кейсы, присоединяйся.
#flutter #dart #llm #ai #ollama #n8n
Download Telegram
Forwarded from Flutter Friendly
Привет, это Анна, Friflex Flutter Team Lead.

Признавайтесь, кому приходилось хотя бы раз писать расширения для строк, чисел и даже списков, чтобы выполнить какие-то простые преобразования или проверки, которых нет среди стандартных функций? Уверена, почти всем! Сегодня я расскажу, как перестать это делать.

Вам нужна всего одна библиотека — dartx.

Пакет дает доступ к дополнительным расширениям классов String, int, num, Iterable, DateTime, File и других, которые используются буквально в каждом проекте. Разберем самые интересные функции.

🔸String
1️⃣ capitalize() и decapitalize() — изменят регистр только первой буквы предложения
2️⃣ isNotNullOrBlank и isNullOrBlank — проверят, есть ли читаемое содержимое, при этом не учитывая специальные символы по типу \n и пробелов
3️⃣ urlEncode и urlDecode — в строке преобразуют ссылку в формат application/x-www-form-urlencoded или обратно

final capitalizedText = 'пример заглавной буквы'.capitalize(); // Пример заглавной буквы
final isBlank = ' \n'.isNullOrBlank; // true
final decodedText = 'Пример%20декодирования'.urlDecode; // Пример декодирования


🔸Iterable
1️⃣ sortedBy() и thenBy() — позволят вам выполнить сортировку по нескольким признакам
2️⃣ chunkWhile() и splitWhen() — объединит в подсписки при выполнении или невыполнении условия

final dogs = [
Dog(name: "Charlie", age: 1),
Dog(name: "Bark", age: 3),
Dog(name: "Charlie", age: 6),
];
final sorted = dogs.sortedBy((dog) => dog.name).thenByDescending((dog) => dog.age); // Bark, Charlie (6), Charlie (3)
final chunckedList =[1, 2, 4, 9, 10, 11].chunkWhile((a, b) => a + 1 == b); // [[1, 2], [4], [9, 10, 11]]


🔸DateTime/Duration (эти функции можно подключить отдельно через пакет time)
1️⃣isAtSameYearAs(date) — проверит, находится ли текущая дата в рамках одного и того же года даты date в параметре (есть аналогичные проверки по месяцу и дню)
2️⃣ minutes.fromNow и minutes.ago — высчитает DateTime по указанной длительности в будущем и прошлом
3️⃣ hours — создаст Duration объект из целого числа

final tenMinutes = 10.minutes; // Duration(minutes: 10)
final isAtSameYear = DateTime(2025, 01, 01).isAtSameYearAs(DateTime(2020, 10, 05)); // false
final timeInFuture = 5.minutes.fromNow; // DatiTime.now() + 5 минут


Это только малая часть того, что умеет dartx!

❤️ — если уже пользуетесь пакетом
🔥 — если только сейчас открыли для себя его чудесные функции
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥163
Дорогие и прелестные наши девушки, поздравляю вас с 8 Марта 🎉, желаю счастья, радости, благополучия. Не переставайте радовать нас и будьте счастливы 💐
Please open Telegram to view this post
VIEW IN TELEGRAM
👍64
Интересно, какой логикой руководствуются люди, которые ставят задачу создать полностью готовое приложение (клиент + бэкенд) за месяц? Откуда такой «крутой» менеджмент? Из курсов, где за две недели готовят IT-специалистов? Могли бы еще добавить в требования, чтобы код был идеальным, несмотря на сжатые сроки, и готовность работать 24/7. 😁 Я боюсь даже представить, каким будет качество кода и архитектуры. Разработчиков-то понять можно: они сдадут проект, получат деньги и уйдут в закат. Но почему собственники не задумываются о последствиях? Вот простая аналогия: вы хотите сделать ремонт в ванной, мастер говорит, что нужно неделю, а вы ему: «Нет, давай за три дня». Так никто не поступает, согласитесь. Потому что это своё, родное, и все понимают, что качество требует времени. Почему же в IT эти простые истины не понимают? Или считают, что это «не своё, не родное»? Странно конечно, и грустно.
👍22👏3
Тут MadBrains выкатили последнюю часть по сливерам, рекомендую всем почитать полный пак. Сливеры надо знать и понимать, без этого никак. 

Такие разные Slivers 

Часть 1

Часть 2

Часть 3

Часть 4

Часть 5

Такое мы читаем. 😎
#flutter #slivers
Please open Telegram to view this post
VIEW IN TELEGRAM
👍18
🚨Большое обновление🚨 курса "Основы Flutter (в разработке)", а значит и самой книги "Основы Flutter" 🥳

Не прошло и недели, как в курс добавился сквозной проект - игра "Тетрис" для главы по Dart (2 варианта консольной версии) и Flutter (по с 2-й по 4-ю главу включительно), а нулевая глава разжилась примером работы с фичей Null-aware elements 😎

В связи с добавленным объемом материалов, цена увеличивается на 300 рублей. Если вы хотели приобрести курс, но на это все никак не было "времени", по 16 марта его можно будет купить по старой цене, воспользовавшись скидкой 🫣

Но это еще не все 😇

22-го марта (суббота) в 11 часов по Мск состоится стрим с авторским коллективом
, где немного приоткроем завесу тайн над написанием книги, почему выбран такой сквозной проект, как началось сотрудничество с Surf и Mad Brains по разработке лабораторного практикума к книге и многое другое 🪨
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
🎉 Exciting news! Dart new version is out. Stay updated!

Dart: 3.7.2

Release date: 2025-03-11
hash: 9594995093f642957b780603c6435d9e7a61b923

Новости от @FlutterObserver_bot

🔗 Breaking changes
🔗 Changelog
🔗 Commit
🔗 Tag
👍3
‼️В спецификацию Dart готовится обновление‼️

Замечен черновик новой фичи - Generic Constructors 😩

Не прошло и пары месяцев с упоминания о предыдущем заходе на поле конструкторов с фичей Enhanced Constructors, как команда Dart, в тайне от сообщества, начала работу над черновиком еще одного конструктора... на этот раз - универсального... 🛑

По задумке разработчиков, Generic-конструкторы должны позволить объявлять конструкторы с собственными параметрами типов, которые не отражаются напрямую в типе возвращаемого объекта. Это значит, что можно задавать дополнительные зависимости между аргументами конструктора. Сейчас приходится приходится прибегать к менее безопасным способам.

Планируется 2 типа Generic-конструкторов 🫠

1️⃣Простой

На данный момент, если требуется задать связь между параметрами конструктора (например, значение и функция для его вычисления), приходится использовать универсальные типы вроде Object? и Function, что снижает статическую проверку типов:
class C {
final int i;
C(this.i);
C.computed(Object? x, Function func): this(func(x)); // Unsafe!
}

с появлением этого конструктора можно будет явно указать зависимость между параметрами, исключая необходимость runtime-проверок
class C {
final int i;
C(this.i);
C.computed<X>(X x, int Function(X) func) : this(func(x));
}

void main() {
C(42); // Обычный конструктор.
C.computed('Hello', (s) => s.length); // Автоматическое выведение типа.
C.computed<String>('Hello', (s) => s.length); // Явное указание типа.
}


2️⃣ Условный

С помощью этого типа Generic-конструктора можно будет объявлять конструкторы, которые корректно работают только при определенных типовых аргументах.
Сейчас приходится писать такой код
class D<X> {
final X x;
final int Function(X, X) _compare;
D(this.x, this._compare);
D.ofComparable(X x): // Unsafe!
this(x, (dynamic x1, dynamic x2) => x1.compareTo(x2)) {
// Check at run-time that `X extends Comparable<X>`.
if (<X>[] is! List<Comparable<X>>) {
throw ArgumentError("The type argument failed"
" to satisfy `X extends Comparable<X>`.");
}
}
}

использование универсального конструктора сделает его более лаконичным:
class D<X> {
final X x;
final int Function(X, X) _compare;
D(this.x, this._compare);
D<X>.ofComparable<X extends Comparable<X>>(X x)
: this(x, (x1, x2) => x1.compareTo(x2));
}

void main() {
D.ofComparable(1); // OK, num удовлетворяет Comparable.
D.ofComparable<num>(1); // Тоже OK.
D.ofComparable(C(42), (c1, c2) => c1.i.compareTo(c2.i)); // OK.
D.ofComparable(C(42)); // Ошибка компиляции – тип не соответствует.
}


p.s. Вот теперь я уже точно уверен, что в команде Dart нашелся какой-то маньяк конструкторов... иначе как объяснить такой набор: по-умолчанию, фабричный, именованный, константный, а теперь вот еще первичный, объявляющий, расширенный и универсальный?👀

👍 - больше конструкторов Богу конструкторов
👌 - сомнительно, но Окей
👎 - не вижу от него пользы

#dart_lang@madteacher_channel
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10👎7
🎉 Потрясающие новости! Вышла новая версия Flutter!

Flutter: 3.29.2

Dart: 3.7.2
Release date: 2025-03-13
hash: c23637390482d4cf9598c3ce3f2be31aa7332daf

Новости от @FlutterObserver_bot


🔗 Breaking changes
🔗 Changelog
🔗 Commit
🔗 Tag

Короткие изменения согласно changelog:
🔄 Импеллер: текст, повернутый на 180 градусов, отображается неправильно. Исправлено масштабирование с вместо !
🔧 Исправлены сбои на устройствах Android старше API 29 при использовании импеллера OpenGLES.
🚫 Исправлена ошибка отсутствия глифа на устройствах Android и iOS.
📱 На устройствах iOS увеличено количество одновременных задач декодирования фонового изображения, чтобы устранить ошибки «Не удалось загрузить изображение из-за потери доступа к графическому процессору».
🚀 Повышение производительности рендеринга CanvasKit для web.
iOS исправляет сбой при выделении поверхности для .
🧰 Всегда используйте аппаратные буферы Android для просмотра платформы, если они поддерживаются.
🆕 Исправлена двойная загрузка canvaskit.wasm.
🔧 Добавлен пустой ввод-вывод для Android apps после миграции встраиваемого модуля версии v2.
🛠️ Для всех платформ исправлен сбой при одновременной анимации и взаимодействии с прокручиваемым объектом.
📱 На Android используйте Open GL вместо Vulkan MediaTek Soc.
👍8🔥3
Forwarded from Flutter Friendly
Привет, с вами Роза, Flutter Dev Friflex👋 И сегодня мы немного погрузимся в магию FutureOr!

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

Лучше, если вы объявите метод, как FutureOr. FutureOr<T> — это такой хитрый тип в Dart, который говорит: «Эй, результат моего метода может быть либо обычным значением типа T, либо Future<T>, если вдруг придется подождать».

Звучит пока не очень понятно? Давайте разберемся на примерах.

Предположим, мы разрабатываем сервис, который получает данные. Одна реализация будет синхронной, другая — асинхронной:

import 'dart:async';

abstract class SomeService {
  FutureOr<String> fetch();
}

class FirstImplService extends SomeService {
  @override
  Future<String> fetch() async {
    await Future.delayed(Duration(seconds: 2));
    return 'Данные из Future';
  }
}

class SecondImplService extends SomeService {
  @override
  String fetch() {
    return 'Простые данные';
  }
}


Aбстрактный класс SomeService объявляет метод fetch() с типом возвращаемого значения FutureOr<String>. Это значит, что fetch() может вернуть либо String, либо Future<String>.

⚙️Когда же использовать FutureOr?
FutureOr — ваш спаситель, когда вам нужно абстрагироваться от того, является ли результат операции асинхронным или синхронным.

🔧Как обрабатывать FutureOr?
Самый простой способ — использовать проверку типа с помощью is Future.

Да, такой вариант решения может показаться не самым элегантным. Ведь чрезмерное использование is Future может запутать логику и сделать код менее читаемым. Но в некоторых случаях, особенно при работе с абстракциями, это вполне рабочий и понятный подход.

У меня с работой так же. Иногда мне нужен await, чтобы подумать, а иногда все складывается супер. А у вас?
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
Плагин для VSCode, красивое число))
🔥16👍2🤩1
Всем привет!
У меня для вас хорошие новости по книге "Основы Flutter" 👀

Глава по локализации утверждена, а значит, в курсе "Основы Flutter" на степике обновление ^_^

Напоминаю, что уже завтра в 11 часов по Мск состоится стрим с авторским коллективом, где немного приоткроем завесу тайны над написанием книги, почему выбран такой сквозной проект, как началось сотрудничество с Surf и Mad Brains по разработке лабораторного практикума к книге и многое другое 🪨
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5👍1
❤️ Спасибо большое всем кто был на трансляции

🤟 Отличный онлайн собрали для субботнего утра! И отдельное спасибо всем кто задавал вопросы, вышло интересное обсуждение

Для вашего удобства сразу добавил подробные таймкоды, ведь мы обсуждали не только книгу но и кучу других вопрсов

📺 Для тех кто не мог смотреть в онлайне запись трансляции достпуна на канале
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9
Forwarded from Flutter Friendly
Привет, это Катя, Flutter Dev Friflex. Сегодня поговорим о фреймворке gRPC и его реализации.

Что это?
gRPC — это фреймворк для удаленного вызова процедур (RPC), разработанный Google. Он использует HTTP/2 для транспорта и Protocol Buffers (protobuf) в качестве языка описания интерфейсов и формата сериализации данных.

Настройка и использование gRPC

1️⃣ Добавляем в pubspec.yaml:

dependencies:
  grpc: ^4.1.0
  protobuf: ^3.1.0

dev_dependencies:
  protoc_plugin: ^21.1.2


2️⃣ Создаем файл .proto
Сделаем на примере создания чата. Определяем сервис в файле .proto. Например, lib/protos/chat.proto:

syntax = "proto3";

package chat;

service ChatService {
  rpc SendMessage (Message) returns (MessageResponse);
  rpc ReceiveMessages (Empty) returns (stream Message);
}

message Message {
  string text = 1;
  string sender = 2;
  int64 timestamp = 3;
}

message MessageResponse {
  bool success = 1;
  string error = 2;
}


3️⃣ Генерируем код
Запускаем команду для генерации Dart-кода:

bash
protoc --dart_out=grpc:lib/generated -Ilib/protos lib/protos/chat.proto


4️⃣ Создаем клиента

class GrpcClient {
  late ChatServiceClient client;

  /// Инициализация канала соединения
  GrpcClient() {
    final channel = ClientChannel(
      'http://localhost',
      port: 50051,
      options: const ChannelOptions(
        credentials: ChannelCredentials.insecure(),
      ),
    );
    client = ChatServiceClient(channel);
  }

  /// Отправка сообщения
  Future<MessageResponse> sendMessage(String text, String sender) async {
    final message = Message()
      ..text = text
      ..sender = sender
      ..timestamp = DateTime.now().millisecondsSinceEpoch;
    
    try {
      return await client.sendMessage(message);
    } catch (e) {
      print('Error sending message: $e');
      return MessageResponse()..success = false..error = e.toString();
    }
  }
  
  /// Получение сообщений
  Stream<Message> receiveMessages() {
    return client.receiveMessages(Empty());
  }
}


5️⃣ Используем клиента в приложении

На что следует обратить внимание:
🔸gRPC клиент:
➡️инициализируется один раз при создании состояния
➡️обеспечивает двустороннюю коммуникацию
➡️управляет подпиской на поток сообщений

🔸Потоковая передача:
➡️receiveMessages() возвращает Stream<Message>
➡️listen() подписывается на новые сообщения

🔸Управление ресурсами:
➡️gRPC соединение должно закрываться
➡️Отмена подписок происходит автоматически при dispose()

Продолжение — в комментариях📌
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7
У бота Flutter Observer количество активных пользователей превысило планку в 300 человек. Неплохо, неплохо. ☺️

Напоминаю, что есть тема в группе, где можно предлагать добавить функции, которые, вы считаете, были бы полезны сообществу. Также это сделать можно написать прямо в боте командой /send.
👍53
Молодцы ребята, что верят и драйвят Flutter!
5🥰5
Forwarded from Ringov | Flutter Bro
Где в Яндексе есть Flutter?

Недавно прошедший внутренний митап ознаменовал новую веху — в Яндексе появилось Flutter-комьюнити!

На митапе отлично повеселились, а заодно провели инвентаризацию команд, использующих Flutter — записывайте 😯

1. Про — iOS | Android
2. Драйв — iOS | Android
3. Практикум — iOS | Android
4. Маршрутизация — iOS | Android
5. Афиша — iOS | Android
6. Авто.ру Бизнес — iOS | Android
7. Заправки — iOS | Android
8. Смена — iOS | Android
9. Маркет ПВЗ — iOS | Android

Ещё есть несколько мест, где Flutter встроен в Яндекс Go. Ну и на десерт. В десктопном Яндекс Браузере многие части UI — на Flutter 😎

Ну чисто чтобы у вас не было сомнений по поводу количества продуктовых Flutter-команд в Яндексе ☕️
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥16👍61
Forwarded from Flutter Friendly
This media is not supported in your browser
VIEW IN TELEGRAM
Привет, с вами Роза, Flutter Dev Friflex!

Когда только начинаешь разрабатывать на Flutter, многие возможности языка остаются незамеченными. А с опытом начинаешь глубже разбираться в деталях и повышать свою экспертность. С модификаторами классов у меня было так же: изначально в моем арсенале был лишь abstract... и все, наверное. А со временем я узнала и про sealed, и про base. Делюсь этим и с вами!

Зачем нужны модификаторы?

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

Основные модификаторы:

🔸abstract
Если вам не нужна реализация всех методов, а вы хотите создать класс-шаблон, используйте abstract.
🔴Запрещает создавать экземпляры этого класса напрямую (new AbstractClass() не сработает).
🔴Часто используется как базовый класс, определяющий интерфейс и частичное поведение для наследников.

🔸base
Разрешает наследование (extends) и реализацию (implements), но только в пределах текущего пакета.
🔴За пределами пакета base-класс нельзя реализовать (implements).
🔴Полезно, если нужно предотвратить реализацию, но оставить возможность наследования.

🔸interface
Принуждает использовать класс только через implements, запрещая наследование (extends).

Полезно, если хотите создать чистый контракт, без возможности переиспользовать реализацию.

🔸final
Запрещает любое наследование (extends) или реализацию (implements) класса за пределами текущей библиотеки. 

Гарантирует, что класс — конечная точка в иерархии. Его нельзя расширить или изменить поведение через подклассы вне вашего контроля.

🔸mixin
Позволяет переиспользовать код без наследования.
🔴Класс с mixin можно добавлять к другим классам через with.
🔴Миксины не могут иметь конструкторов и не могут быть инстанцированы напрямую.

🔸sealed
Позволяет создавать закрытый набор подтипов.
🔴Все подклассы должны быть в той же библиотеке, что и sealed-класс.
🔴Полезно для switch, так как компилятор проверяет, что все случаи учтены (exhaustiveness).
🔴Отлично подходит для описания состояний (Loading, Success, Error), событий и других строго определенных иерархий.

Как использовать модификаторы?
Добавьте перед классом нужное ключевое слово. Например:

sealed class GameState {
  // ...
}


🔖Важно! Модификаторы можно комбинировать (abstract base class), создавая тонкие правила для классов. Подробнее — в таблице в комментариях.

📎 Официальная документация по модификаторам

А какие модификаторы используете чаще всего? Делитесь в комментариях! 👀
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
Обновил ботика FlutterObserver_bot до версии 0.2.1

- Обновление Telegram API до 8.3
- Теперь changelog отображается первым для быстрого перехода
- Оптимизация сервиса для отправки сообщений пользователем
- Исправление минорных ошибок

https://telegra.ph/Flutter-Observer-02-17
👍3
Ух, зашел в репозиторий по ресурсам Flutter и увидел, что ребята из Mad Brains сделали пулреквесты на оптимизацию и добавления чата Комьюнити Flutter-разработчиков от Mad Brains.

Прошу меня простить, что сразу не увидел. В дальнейшем буду периодически заходить смотреть пулреквесты )

В итоге:
- в список чатов на русском языке добавлен чат Комьюнити Flutter-разработчиков от Mad Brains;
- в список чатов на английском языке добавлен чат Комьюнити Flutter Guys.
- в список чатов на английском языке добавлен чат Flutter developers community.

Если кто-то еще знает интересные ресурсы по Flutter, пишите мне или сделайте пулреквест.

Отслеживать обновления в репозитории можно в боте @FlutterObserver_bot
2