{"id":21748340,"url":"https://github.com/surfstudio/surf-flutter-study-jam-2023","last_synced_at":"2025-08-19T03:09:54.970Z","repository":{"id":185302651,"uuid":"622967444","full_name":"surfstudio/surf-flutter-study-jam-2023","owner":"surfstudio","description":null,"archived":false,"fork":false,"pushed_at":"2023-04-12T14:49:46.000Z","size":1611,"stargazers_count":6,"open_issues_count":3,"forks_count":60,"subscribers_count":8,"default_branch":"main","last_synced_at":"2025-04-13T07:15:09.303Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/surfstudio.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2023-04-03T12:33:57.000Z","updated_at":"2023-12-27T01:45:59.000Z","dependencies_parsed_at":null,"dependency_job_id":"6a1aa043-e70b-4c4f-94bb-e55cd821d6d9","html_url":"https://github.com/surfstudio/surf-flutter-study-jam-2023","commit_stats":null,"previous_names":["surfstudio/surf-flutter-study-jam-2023"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/surfstudio/surf-flutter-study-jam-2023","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/surfstudio%2Fsurf-flutter-study-jam-2023","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/surfstudio%2Fsurf-flutter-study-jam-2023/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/surfstudio%2Fsurf-flutter-study-jam-2023/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/surfstudio%2Fsurf-flutter-study-jam-2023/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/surfstudio","download_url":"https://codeload.github.com/surfstudio/surf-flutter-study-jam-2023/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/surfstudio%2Fsurf-flutter-study-jam-2023/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":271093053,"owners_count":24697921,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-19T02:00:09.176Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-26T08:13:07.585Z","updated_at":"2025-08-19T03:09:54.946Z","avatar_url":"https://github.com/surfstudio.png","language":"Dart","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Surf Flutter Study Jam 2023\n\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"https://surf.ru/wp-content/themes/surf/assets/img/logo.svg\" height=\"120\" /\u003e\n\u003c/p\u003e\n\n## Требования к приложению\n\n- Версия Flutter: **3.7.9**\n- Версия Dart: **2.19.6**\n\nВаша ветка с выполнением задания называется `study-jam-2023`.\n\nВ шаблонном приложении у вас уже есть базовый экран.\n\nЭмоджи 🔥 показывает задание повышеной сложности.\n\n---\n\n### Описание фичи\n\nИзвестный агрегатор туристических мероприятий “Async Tour” провел маркетинговое исследование, в ходе которого \nвыяснилось, что клиенты агрегатора часто оказываются в ситуации, когда не могут предоставить свой оплаченный \nбилет на туристическое мероприятие (тур, экскурсию).\n\nВ ходе опроса выяснилось, что клиенты часто забывают билеты в физическом виде, а скачивая в электронном виде \nпопросту теряют эти билеты в куче файлов папки “Загрузка” на телефоне или в письмах на почте.\n\nКомпания “Async Tour” уже имеет собственное успешное приложение для поиска туристических мероприятий. \nРуководством было решено включить в следующий релиз фичу “Хранение билетов”, что не только поможет клиентам \nне забывать свои билеты, но и увеличит вовлеченность пользователей, что в свою очередь увеличит количество \nпоказов рекламных предложений.\n\nВам предстоит разработать отдельный модуль фичи “Хранения билетов”, который позволит пользователю скачивать \nфайлы в формате PDF, следить за состоянием скачивания файлов и хранить эти файлы на телефоне.\n\n### Техническое задание\n\n#### Общие компоненты экрана\n- Аппбар с заголовком “Хранение билетов”;\n- Кнопка “Добавить”, которая открывает модальное окно “Добавление ссылки”.\n\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"./docs/assets/tickets_empty_state.png\" width=\"375\" alt=\"Empty screen\" /\u003e\n\u003c/p\u003e\n\n#### Состояние отсутствия данных\nПри отсутствии скачанных или доступных для скачивания файлов должен отображаться экран с надписью “Здесь пока ничего нет”.\n\n#### Состояние загрузки данных\nВ процессе загрузки доступных для скачивания файлов должен отображаться прогресс загрузки.\n\n#### Модалка “Добавление ссылки”\nНа модалке присутствует два компонента:\n\n- Текстовое поле с предложением ввести URL\n- Кнопка “Добавить”\n\n\u003cdiv class=\"row\" align=\"center\"\u003e\n  \u003cimg src=\"./docs/assets/modal_start.png\" width=\"375\" alt=\"ModalBottomSheet\" style=\"margin-right: 30px;\" /\u003e\n  \u003cimg src=\"./docs/assets/modal_empty.png\" width=\"375\" alt=\"ModalBottomSheet with keyboard\" /\u003e\n\u003c/div\u003e\n\nПо нажатию кнопки “Добавить” валидируется поле с URL по параметрам соответствующим URL.\n\n\u003cdiv class=\"row\" align=\"center\"\u003e\n  \u003cimg src=\"./docs/assets/modal_with_url.png\" width=\"375\" alt=\"ModalBottomSheet success\" style=\"margin-right: 30px;\" /\u003e\n  \u003cimg src=\"./docs/assets/modal_error.png\" width=\"375\" alt=\"ModalBottomSheet error\" /\u003e\n\u003c/div\u003e\n\nЕсли валидация проходит, на основной экран добавляется один элемент “Файл”.\n\nЕсли в буфере обмена есть ссылка формата .pdf обеспечьте её автоматическую подстановку в поле ввода url.\n\n\u003cdiv class=\"row\" align=\"center\"\u003e\n  \u003cimg src=\"./docs/assets/tickets_wait_download.png\" width=\"375\" alt=\"ModalBottomSheet\" style=\"margin-right: 30px;\" /\u003e\n  \u003cimg src=\"./docs/assets/tickets_scroll.png\" width=\"375\" alt=\"ModalBottomSheet\" /\u003e\n\u003c/div\u003e\n\n\n#### Компонент “Билет”\nПри успешном добавлении билет появляется в общем списке, но скачивание не начинается автоматически.\n\nЭлемент содержит следующие общие компоненты:\n- Иконка билета\n- Название файла, формируемое из конечного пути ссылки.\n- Кнопка загрузки\n\nВ состоянии элемента, который доступен для скачивания:\n- Кнопка загрузки находится в состоянии доступной для скачивания. По её нажатию начинается скачивание файла.\n\nВ состоянии, когда файл находится в процессе загрузки:\n- Индикатор прогресса загрузки файла.\n- Индикатор прогресса загрузки в Мбайтах: текущее значение и общий вес файла.\n- Кнопка загрузки меняется на паузу. По её нажатию останавливается загрузка файла.\n\nВ состоянии, когда файл загружен и находится на устройстве:\n- Кнопка загрузки становится неактивной.\n\n\u003cdiv class=\"row\" align=\"center\"\u003e\n  \u003cimg src=\"./docs/assets/tickets_with_states.png\" width=\"375\" alt=\"ModalBottomSheet success\" style=\"margin-right: 30px;\" /\u003e\n  \u003cimg src=\"./docs/assets/tickets_downloaded.png\" width=\"375\" alt=\"ModalBottomSheet error\" /\u003e\n\u003c/div\u003e\n\n \n## Итак, давайте начнём!\n\n\u003e Небольшие рекомендации: \n\u003e \n\u003e - Не забывайте писать комментарии к классам и методам чтобы другим разработчикам было сразу понятно что тут происходит. \n\u003e Умение писать понятный код это важный навык для командной разработки.\n\u003e - Помните про форматирование кода 👆.\n\n### Задание 1\n\nРеализуйте интерфейс экрана: Аппбар, состояния экрана, модальное окно (или боттомшит), кнопки, карточку файла.\n\n### Задание 2\n\nРеализуйте логику добавления ссылки на загрузку файла. Не забудьте про валидацию данных!\n\nРеализуйте отображение снекбара при успешном добавлении ссылки.\n\n🔥 При наличии ссылки формата .pdf в буфере обмена обеспечьте её автоматическую подстановку в поле ввода url.\n\n🔥🔥 Сохранение списка файлов в локальном хранилище.\n\n### Задание 3\n\nРеализуйте логику отображения списка файлов.\n\n🔥 Добавить скрытие кнопки добавления ссылки, если долистали список до конца.\n\n🔥🔥 Сортировка файлов по дате добавления, по состоянию загрузки с сохранением в локальной базе данных.\n\n### Задание 4\n\nРеализуйте процесс загрузки и сохранения файлов. В качестве клиента можно использовать пакет **DIO**: [https://pub.dev/packages/dio](https://pub.dev/packages/dio)\n\n🔥 Удаление файла из хранилища.\n\n🔥🔥🔥 Загрузка всех незагруженных файлов по одной кнопке. \n\nМожно реализовать разные варианты:\n\n- Загрузить все незагруженные.\n- Добавить отображение чекбоксов для выбора файлов и загрузить все выбранные файлы.\n- Скрывать кнопки, если долистали до конца списка.\n\n\u003cdiv class=\"row\" align=\"center\"\u003e\n  \u003cimg src=\"./docs/assets/tickets_select_all.png\" width=\"375\" alt=\"ModalBottomSheet success\" style=\"margin-right: 30px;\" /\u003e\n  \u003cimg src=\"./docs/assets/tickets_checkbox_selected.png\" width=\"375\" alt=\"ModalBottomSheet success\" /\u003e\n\u003c/div\u003e\n\n\u003cdiv class=\"row\" align=\"center\"\u003e\n  \u003cimg src=\"./docs/assets/tickets_checkbox_scroll.png\" width=\"375\" alt=\"ModalBottomSheet success\" style=\"margin-right: 30px;\" /\u003e\n  \u003cimg src=\"./docs/assets/tickets_hidden_buttons.png\" width=\"375\" alt=\"ModalBottomSheet error\" style=\"margin-bottom: 60px;\" /\u003e\n\u003c/div\u003e\n\n### Задание 5 🔥🔥\n\nОткройте pdf файл для просмотра на отдельном экране\n\n### Креатив 🔥🔥🔥\n\nУспели сделать все задания раньше всех или просто хотите выделиться? Доработайте фичу по своему усмотрению!\n\n# Предоставление результатов\n\nУмение защитить результаты своей работы - невероятно важный навык для разработчика.\n\nВ текущем проекте есть файл `/docs/RESULT.md`. Этот шаблон нужен как раз для того, чтобы вы могли поделиться результатами вашей работы. Вы можете записать скринкаст, сделать скриншоты или целый README-файл, в котором будет описано, что вы успели сделать.\n\nЭто один из критериев, по которому будет оцениваться ваша работа!","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsurfstudio%2Fsurf-flutter-study-jam-2023","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsurfstudio%2Fsurf-flutter-study-jam-2023","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsurfstudio%2Fsurf-flutter-study-jam-2023/lists"}