{"id":391971,"date":"2024-06-29T10:08:12","date_gmt":"2024-06-29T10:08:12","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=391971"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=391971","title":{"rendered":"<span>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043a\u043b\u043e\u043d Instagram \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 Flutter \u0438 Feeds. \u0427\u0430\u0441\u0442\u044c 2<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/bdb\/668\/719\/bdb668719f7b128deefd7c4d6fa1d578.jpg\" width=\"1200\" height=\"630\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/bdb\/668\/719\/bdb668719f7b128deefd7c4d6fa1d578.jpg\" data-blurred=\"true\"\/><\/figure>\n<p>\u041f\u0440\u0438\u0432\u0435\u0442! \u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u044e \u0432\u044b\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u0432\u043e\u0434 \u0441\u0442\u0430\u0442\u044c\u0438, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b \u043a\u0430\u043a \u043e\u0441\u043d\u043e\u0432\u0443 \u0434\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0441\u043e\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430 \u0432 \u043d\u0430\u0448\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435 <a href=\"https:\/\/dom24x7.ru\" rel=\"noopener noreferrer nofollow\">Dom24x7<\/a>, \u0433\u0434\u0435 \u043b\u044e\u0434\u0438 \u043c\u043e\u0433\u0443\u0442 \u043e\u0431\u0449\u0430\u0442\u044c\u0441\u044f \u0434\u0440\u0443\u0433 \u0441 \u0434\u0440\u0443\u0433\u043e\u043c, \u0440\u0435\u0448\u0430\u0442\u044c \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u044e\u0449\u0438\u0435 \u0431\u044b\u0442\u043e\u0432\u044b\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0441 \u0423\u041a\/\u0422\u0421\u0416. \u041f\u0435\u0440\u0432\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u0441\u0442\u0430\u0442\u044c\u0438 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c <a href=\"https:\/\/habr.com\/ru\/articles\/727794\/\" rel=\"noopener noreferrer nofollow\">\u0442\u0443\u0442<\/a>.<\/p>\n<h2>\u041f\u0438\u0448\u0435\u043c \u043a\u043e\u0434 \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0433\u043e \u0438\u043d\u0441\u0442\u0430\u0433\u0440\u0430\u043c \u043a\u043b\u043e\u043d\u0430<\/h2>\n<p>\u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u043c\u044b \u0434\u043e\u0431\u0440\u0430\u043b\u0438\u0441\u044c \u0434\u043e \u0441\u0430\u043c\u043e\u0439 \u0438\u043d\u0442\u0440\u0438\u0433\u0443\u044e\u0449\u0435\u0439 \u0447\u0430\u0441\u0442\u0438 \u0441\u0442\u0430\u0442\u044c\u0438.<\/p>\n<p>\u041f\u0435\u0440\u0435\u0434 \u0442\u0435\u043c \u043a\u0430\u043a \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0431\u044b\u0441\u0442\u0440\u043e \u043e\u0431\u0441\u0443\u0434\u0438\u043c \u043f\u043e\u0434\u0445\u043e\u0434, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043c\u044b \u043f\u043e\u0434\u043e\u0439\u0434\u0435\u043c \u043a \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044e \u043d\u0430\u0448\u0435\u0433\u043e \u043a\u043b\u043e\u043d\u0430.<\/p>\n<p>\u041d\u0430\u0448 Stream-agram \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u0442\u044c \u0438\u0437 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 UI, \u043e\u0442 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u043e\u0442\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u043e\u0437\u0436\u0435 \u0432 \u0441\u0442\u0430\u0442\u044c\u0435. \u042d\u0442\u043e \u0442\u0430\u043a\u0438\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u043a\u0430\u043a:<\/p>\n<ul>\n<li>\n<p><strong>\u042d\u043a\u0440\u0430\u043d \u0432\u0445\u043e\u0434\u0430<\/strong> (mock-\u043e\u0431\u044a\u0435\u043a\u0442): \u0442\u0430\u043c, \u0433\u0434\u0435 \u043c\u044b \u0432\u0445\u043e\u0434\u0438\u043c \u0432 \u0441\u0432\u043e\u0439 \u043f\u0440\u043e\u0444\u0438\u043b\u044c;<\/p>\n<\/li>\n<li>\n<p><strong>\u0413\u043b\u0430\u0432\u043d\u044b\u0439 \u044d\u043a\u0440\u0430\u043d<\/strong>: \u043e\u0442\u043a\u0443\u0434\u0430 \u043c\u044b \u0441\u043c\u043e\u0436\u0435\u043c \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u0442\u044c \u0432 \u0434\u0440\u0443\u0433\u0438\u0435 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f (\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0442\u0430\u043c \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u043a\u0440\u044b\u0442\u0430 \u0445\u0440\u043e\u043d\u043e\u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u043b\u0435\u043d\u0442\u0430);<\/p>\n<\/li>\n<li>\n<p><strong>\u0421\u0430\u043c\u0443 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0441 \u0445\u0440\u043e\u043d\u043e\u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u043b\u0435\u043d\u0442\u043e\u0439<\/strong> (\u0434\u043e\u043c\u0430\u0448\u043d\u044f\u044f \u0432\u043a\u043b\u0430\u0434\u043a\u0430): \u043c\u0435\u0441\u0442\u043e, \u0433\u0434\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441\u043c\u043e\u0442\u0440\u0438\u0442 \u043f\u043e\u0441\u0442\u044b \u0442\u0435\u0445 \u043d\u0430 \u043a\u043e\u0433\u043e \u043f\u043e\u0434\u043f\u0438\u0441\u0430\u043d;<\/p>\n<\/li>\n<li>\n<p><strong>\u0412\u043a\u043b\u0430\u0434\u043a\u0443 \u043b\u0438\u0447\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0444\u0438\u043b\u044f<\/strong>: \u0442\u0430\u043c, \u0433\u0434\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0430 \u0432\u0441\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e \u043f\u0440\u043e\u0444\u0438\u043b\u0435, \u0432\u043a\u043b\u044e\u0447\u0430\u044f \u043e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u0441\u0442\u044b;<\/p>\n<\/li>\n<li>\n<p><strong>\u0412\u043a\u043b\u0430\u0434\u043a\u0443 \u043f\u043e\u0438\u0441\u043a\u0430<\/strong>: \u043e\u0442\u043a\u0443\u0434\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0434\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u0438 \u043e\u0442\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u043e\u0442 \u0434\u0440\u0443\u0433\u0438\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439;<\/p>\n<\/li>\n<li>\n<p><strong>\u042d\u043a\u0440\u0430\u043d \u00ab\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0444\u0438\u043b\u044c\u00bb<\/strong>: \u0442\u0430\u043c, \u0433\u0434\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043c\u043e\u0436\u0435\u0442 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u043e\u0441\u043d\u043e\u0432\u043d\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043f\u0440\u043e\u0444\u0438\u043b\u044f \u0438 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0435 \u0444\u043e\u0442\u043e;<\/p>\n<\/li>\n<li>\n<p><strong>\u042d\u043a\u0440\u0430\u043d \u00ab\u041d\u043e\u0432\u0430\u044f \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u044f\u00bb<\/strong>: \u0442\u0430\u043c, \u0433\u0434\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0435 \u043f\u043e\u0441\u0442\u044b (\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f) \u0432 \u0441\u0432\u043e\u0439 \u043f\u0440\u043e\u0444\u0438\u043b\u044c.<\/p>\n<\/li>\n<\/ul>\n<p>\u041c\u044b \u043d\u0430\u0447\u043d\u0435\u043c \u0441 \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u043d\u044b\u0445 \u0432\u0435\u0440\u0441\u0438\u0439 \u044d\u0442\u0438\u0445 \u0432\u043a\u043b\u0430\u0434\u043e\u043a \u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446 \u0438 \u0431\u0443\u0434\u0435\u043c \u0432\u043d\u043e\u0441\u0438\u0442\u044c \u0432 \u043d\u0438\u0445 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0448\u0430\u0433 \u0437\u0430 \u0448\u0430\u0433\u043e\u043c, \u043f\u043e \u043c\u0435\u0440\u0435 \u0442\u043e\u0433\u043e \u043a\u0430\u043a \u0431\u0443\u0434\u0435\u043c \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0432 \u043d\u0430\u0448\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439. \u041a\u043e\u043d\u0435\u0447\u043d\u044b\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c \u0441\u0442\u0430\u043d\u0435\u0442 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0438\u0434\u0435\u043d\u0442\u0438\u0447\u043d\u044b\u0439 \u043a\u043b\u043e\u043d Instagram*.<\/p>\n<h2>\u0424\u0430\u0439\u043b Flutter \u0438 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043f\u0430\u043f\u043e\u043a<\/h2>\n<p>\u041a\u0430\u0436\u0434\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u043c \u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0441\u0432\u043e\u0435\u0439 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u043f\u0430\u043f\u043e\u043a. \u0422\u0443 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435, \u043d\u0438 \u0432 \u043a\u043e\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0435\u043b\u044c\u0437\u044f \u0441\u0447\u0438\u0442\u0430\u0442\u044c \u043b\u0443\u0447\u0448\u0435 \u043a\u0430\u043a\u043e\u0439-\u043b\u0438\u0431\u043e \u0434\u0440\u0443\u0433\u043e\u0439. \u042d\u0442\u043e \u043b\u0438\u0448\u044c \u043e\u0434\u0438\u043d \u0438\u0437 \u0443\u0434\u043e\u0431\u043d\u044b\u0445 \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u0432 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0434 \u0434\u043b\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<p>\u042d\u0442\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u0443\u0435\u0442 \u0432\u0435\u0441\u044c \u043a\u043e\u0434 \u043f\u043e\u0434 \u0434\u0432\u0435 \u043f\u0430\u043f\u043a\u0438 \u0432\u0435\u0440\u0445\u043d\u0435\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f: <strong>app<\/strong> \u0438 <strong>components<\/strong>.<\/p>\n<p>\u0412 <strong>components<\/strong> \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432\u0441\u0435, \u0447\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043e \u0432 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u043c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0435 &#8212; \u0435\u0433\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b. \u0414\u0440\u0443\u0433\u0438\u043c\u0438 \u0441\u043b\u043e\u0432\u0430\u043c\u0438 \u044d\u0442\u043e \u0431\u0443\u0434\u0443\u0442 \u043a\u0443\u0441\u043e\u0447\u043a\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u043c\u043e\u0433\u0443\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u043e\u0442 \u0434\u0440\u0443\u0433\u0438\u0445 \u0435\u0433\u043e \u0447\u0430\u0441\u0442\u0435\u0439; \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 &#8212; \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b\/\u0432\u043a\u043b\u0430\u0434\u043a\u0438, \u043a\u043d\u043e\u043f\u043a\u0438, \u0438 \u0432\u0438\u0434\u0436\u0435\u0442\u044b. \u041a\u0430\u0442\u0430\u043b\u043e\u0433 <strong>component<\/strong> \u0431\u0443\u0434\u0435\u0442 \u0442\u0430\u043a\u0436\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u043f\u0430\u043f\u043a\u0443 \u0441 \u0438\u043c\u0435\u043d\u0435\u043c<strong> app_widgets<\/strong>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0432\u0441\u0435 \u043e\u0431\u0449\u0438\u0435 \u0432\u0438\u0434\u0436\u0435\u0442\u044b, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0435 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438.<\/p>\n<p>\u041a\u0430\u0442\u0430\u043b\u043e\u0433<strong> app<\/strong> \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043a\u043b\u0430\u0441\u0441\u044b, \u043e\u0442\u043d\u043e\u0441\u044f\u0449\u0438\u0435\u0441\u044f \u043a\u043e \u0432\u0441\u0435\u043c\u0443 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044e, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043a\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, app state \u0438 navigation.<\/p>\n<p>\u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0430\u043a\u043a\u0443\u0440\u0430\u0442\u043d\u043e \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c\u044b\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b, \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0444\u0430\u0439\u043b\u044b Barrel (\u0434\u0430\u043b\u0435\u0435 \u043f\u0440\u043e\u0441\u0442\u043e &#8212; \u0431\u0430\u0440\u0440\u0435\u043b\u044c-\u0444\u0430\u0439\u043b\u044b).<\/p>\n<blockquote>\n<p>\u0411\u0430\u0440\u0440\u0435\u043b\u044c-\u0444\u0430\u0439\u043b\u044b \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u0441\u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c\u044b\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u0438\u0437 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043f\u0430\u043f\u043e\u043a \u0432 \u043e\u0434\u0438\u043d \u0443\u0434\u043e\u0431\u043d\u044b\u0439 \u0444\u0430\u0439\u043b.<\/p>\n<\/blockquote>\n<p>\u041a \u043a\u043e\u043d\u0446\u0443 \u0441\u0442\u0430\u0442\u044c\u0438 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0432\u0430\u0448\u0438\u0445 \u043f\u0430\u043f\u043e\u043a \u0438 \u0444\u0430\u0439\u043b\u043e\u0432 \u0434\u043e\u043b\u0436\u043d\u0430 \u0438\u043c\u0435\u0442\u044c \u043f\u043e\u0445\u043e\u0436\u0438\u0439 \u0432\u0438\u0434. \u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043b\u0438\u0431\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0432\u0441\u0451 \u044d\u0442\u043e \u0441\u0435\u0439\u0447\u0430\u0441 \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e, \u043b\u0438\u0431\u043e \u043f\u043e\u0437\u0436\u0435 \u043f\u043e \u043c\u0435\u0440\u0435 \u043f\u0440\u043e\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u044f \u0441\u0442\u0430\u0442\u044c\u0438.<\/p>\n<pre><code>\u251c\u2500\u2500 lib |   \u251c\u2500\u2500 app \u2502   \u2502   \u251c\u2500\u2500 navigation \u2502   \u2502   \u2502   \u2514\u2500\u2500 custom_rect_tween.dart |   |   |   \u2514\u2500\u2500 hero_dialog_route.dart |   |   |   \u2514\u2500\u2500 navigation.dart * |   |   \u251c\u2500\u2500 state |   |   |   \u251c\u2500\u2500 models |   |   |   |   \u2514\u2500\u2500 models.dart * |   |   |   |   \u2514\u2500\u2500 user.dart |   |   |   \u2514\u2500\u2500 app_state.dart |   |   |   \u2514\u2500\u2500 demo_users.dart |   |   |   \u2514\u2500\u2500 state.dart * |   |   \u2514\u2500\u2500 app.dart * |   |   \u2514\u2500\u2500 stream_agram.dart |   |   \u2514\u2500\u2500 theme.dart |   |   \u2514\u2500\u2500 utils.dart |   \u251c\u2500\u2500 components \u2502   \u2502   \u251c\u2500\u2500 app_widgets \u2502   \u2502   \u2502   \u2514\u2500\u2500 app_widgets.dart * |   |   |   \u2514\u2500\u2500 avatars.dart |   |   |   \u2514\u2500\u2500 comment_box.dart |   |   |   \u2514\u2500\u2500 favorite_icon.dart |   |   |   \u2514\u2500\u2500 tap_fade_icon.dart |   |   \u251c\u2500\u2500 comments |   |   |   \u251c\u2500\u2500 state |   |   |   |   \u2514\u2500\u2500 comment_state.dart * |   |   |   |   \u2514\u2500\u2500 state.dart |   |   |   \u2514\u2500\u2500 comment_screen.dart |   |   |   \u2514\u2500\u2500 comments.dart * \u2502   \u2502   \u251c\u2500\u2500 home \u2502   \u2502   \u2502   \u2514\u2500\u2500 home_screen.dart |   |   |   \u2514\u2500\u2500 home.dart * |   |   \u251c\u2500\u2500 login |   |   |   \u2514\u2500\u2500 login_screen.dart |   |   |   \u2514\u2500\u2500 login.dart * \u2502   \u2502   \u251c\u2500\u2500 new_post \u2502   \u2502   \u2502   \u2514\u2500\u2500 new_post_screen.dart |   |   |   \u2514\u2500\u2500 new_post.dart * |   |   \u251c\u2500\u2500 profile |   |   |   \u2514\u2500\u2500 edit_profile_screen.dart |   |   |   \u2514\u2500\u2500 profile_page.dart |   |   |   \u2514\u2500\u2500 profile.dart * \u2502   \u2502   \u251c\u2500\u2500 search \u2502   \u2502   \u2502   \u2514\u2500\u2500 search_page.dart |   |   |   \u2514\u2500\u2500 search.dart * |   |   \u2514\u2500\u2500 timeline |   |   |   \u251c\u2500\u2500 widgets |   |   |   |   \u2514\u2500\u2500 post_card.dart |   |   |   |   \u2514\u2500\u2500 widgets.dart * |   |       \u2514\u2500\u2500 timeline_page.dart |   |       \u2514\u2500\u2500 timeline.dart * \u2502   \u2514\u2500\u2500 main.dart \u251c\u2500\u2500 pubspec.lock \u251c\u2500\u2500 pubspec.yaml<\/code><\/pre>\n<blockquote>\n<p>\u26a0\ufe0f \u0417\u0430\u043c\u0435\u0442\u044c\u0442\u0435, \u0447\u0442\u043e \u0431\u0430\u0440\u0440\u0435\u043b\u044c-\u0444\u0430\u0439\u043b\u044b \u043f\u043e\u043c\u0435\u0447\u0435\u043d\u044b \u0437\u0432\u0435\u0437\u0434\u043e\u0447\u043a\u043e\u0439 \u00ab*\u00bb<\/p>\n<\/blockquote>\n<h2>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0433\u043e Instagram<\/h2>\n<p>\u041a\u0430\u043a \u0443\u0436\u0435 \u0431\u044b\u043b\u043e \u0443\u043f\u043e\u043c\u044f\u043d\u0443\u0442\u043e \u0432\u044b\u0448\u0435, \u0432 \u0446\u0435\u043b\u044f\u0445 \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u0438, \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u0437\u0430\u0445\u0430\u0440\u0434\u043a\u043e\u0434\u0438\u043c \u043d\u0430\u0448\u0438\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439, \u0442\u043e \u0435\u0441\u0442\u044c \u0437\u0430\u043f\u043e\u043b\u043d\u0438\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u043d\u0438\u0445 \u0432\u0440\u0443\u0447\u043d\u0443\u044e.<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u0444\u0430\u0439\u043b <code>app\/state\/demo_users.dart<\/code> \u0438 \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0432 \u043d\u0435\u0433\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<pre><code class=\"dart\">import 'package:stream_feed_flutter_core\/stream_feed_flutter_core.dart';  \/\/\/ Demo application users. enum DemoAppUser {   sahil,   sacha,   reuben,   gordon, }  \/\/\/ Convenient class Extension on [DemoAppUser] enum extension DemoAppUserX on DemoAppUser {   \/\/\/ Convenient method Extension to generate an [id] from [DemoAppUser] enum   String? get id => {         DemoAppUser.sahil: 'sahil-kumar',         DemoAppUser.sacha: 'sacha-arbonel',         DemoAppUser.reuben: 'reuben-turner',         DemoAppUser.gordon: 'gordon-hayes',       }[this];    \/\/\/ Convenient method Extension to generate a [name] from [DemoAppUser] enum   String? get name => {         DemoAppUser.sahil: 'Sahil Kumar',         DemoAppUser.sacha: 'Sacha Arbonel',         DemoAppUser.reuben: 'Reuben Turner',         DemoAppUser.gordon: 'Gordon Hayes',       }[this];    \/\/\/ Convenient method Extension to generate [data] from [DemoAppUser] enum   Map&lt;String, Object>? get data => {         DemoAppUser.sahil: {           'first_name': 'Sahil',           'last_name': 'Kumar',           'full_name': 'Sahil Kumar',         },         DemoAppUser.sacha: {           'first_name': 'Sacha',           'last_name': 'Arbonel',           'full_name': 'Sacha Arbonel',         },         DemoAppUser.reuben: {           'first_name': 'Reuben',           'last_name': 'Turner',           'full_name': 'Reuben Turner',         },         DemoAppUser.gordon: {           'first_name': 'Gordon',           'last_name': 'Hayes',           'full_name': 'Gordon Hayes',         },       }[this];    \/\/\/ Convenient method Extension to generate a [token] from [DemoAppUser] enum   Token? get token => &lt;DemoAppUser, Token>{         DemoAppUser.sahil: const Token(''), \/\/ TODO add token         DemoAppUser.sacha: const Token(''), \/\/ TODO add token         DemoAppUser.reuben: const Token(''), \/\/ TODO add token         DemoAppUser.gordon: const Token(''), \/\/ TODO add token       }[this]; }<\/code><\/pre>\n<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0444\u0430\u0439\u043b\u0435 \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e <strong>TODO<\/strong> \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c <strong>String<\/strong> \u0442\u043e\u043a\u0435\u043d\u044b, \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0435 \u0440\u0430\u043d\u0435\u0435. \u041e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0435 \u0442\u043e\u043a\u0435\u043d\u044b \u0434\u043b\u044f \u043d\u0443\u0436\u043d\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u0432\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0435 \u0434\u0440\u0443\u0433\u0438\u0435 \u0438\u043c\u0435\u043d\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439, \u0442\u043e \u0432\u0430\u043c \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0441\u0442\u0440\u043e\u043a\u0438 \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0444\u0430\u0439\u043b\u0435.<\/p>\n<p>\u041a\u043e\u0434 \u0432\u044b\u0448\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0432 \u0441\u0435\u0431\u0435 enum \u043a\u043b\u0430\u0441\u0441 <strong>DemoAppUser<\/strong> c \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435\u043c <strong>DemoAppUserX<\/strong>. \u0421\u0434\u0435\u043b\u0430\u043d\u043e \u044d\u0442\u043e \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043c\u044b \u043c\u043e\u0433\u043b\u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0434\u0440\u0443\u0433\u0438\u043c \u0434\u0430\u043d\u043d\u044b\u043c (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u043a \u0442\u043e\u043a\u0435\u043d\u0430\u043c \u0438\u043b\u0438 \u043a \u0438\u043c\u0435\u043d\u0430\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439). \u042d\u0442\u043e\u0442 \u0444\u0430\u0439\u043b \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043a\u0440\u0438\u0442\u0438\u0447\u043d\u043e \u0432\u0430\u0436\u043d\u044b\u043c, \u0438 \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0432\u0430\u0448\u0438\u0445 \u0444\u0435\u0439\u043a\u043e\u0432\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u043b\u044e\u0431\u044b\u043c \u0434\u0440\u0443\u0433\u0438\u043c \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u043c.<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u0431\u0430\u0440\u0440\u0435\u043b\u044c-\u0444\u0430\u0439\u043b \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439 <code>app\/state\/state.dart<\/code> \u0438 \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0439\u0442\u0435 \u0435\u0433\u043e:<\/p>\n<pre><code class=\"dart\">export 'demo_users.dart';<\/code><\/pre>\n<p>\u0414\u0430\u043b\u0435\u0435, \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0431\u0430\u0440\u0440\u0435\u043b\u044c-\u0444\u0430\u0439\u043b \u0443\u0440\u043e\u0432\u043d\u044f \u0432\u044b\u0448\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u043c\u0435\u0435\u0442 \u0432\u0438\u0434 <code>app\/app.dart<\/code> \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0439\u0442\u0435 \u0435\u0433\u043e:<\/p>\n<pre><code class=\"dart\">export 'state\/state.dart';<\/code><\/pre>\n<h2>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0442\u0435\u043c\u044b \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0433\u043e \u0438\u043d\u0441\u0442\u0440\u0430\u0433\u0440\u0430\u043c \u043a\u043b\u043e\u043d\u0430<\/h2>\n<p>\u041c\u044b \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u043c\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u0435 \u0436\u0435 \u0446\u0432\u0435\u0442\u0430 \u0438 \u0448\u0440\u0438\u0444\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u044b \u0432\u0438\u0434\u0438\u0442\u0435 \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0435\u0433\u043e \u0418\u043d\u0441\u0442\u0430\u0433\u0440\u0430\u043c\u0430, \u0434\u043b\u044f \u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u043d\u0430\u0448\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0434\u0430\u0432\u0430\u043b\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c \u0442\u0435 \u0436\u0435 \u044d\u043c\u043e\u0446\u0438\u0438, \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438. \u041c\u044b \u0442\u0430\u043a\u0436\u0435 \u0445\u043e\u0442\u0438\u043c \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u0432 \u043d\u0430\u0448\u0435\u043c \u043a\u043b\u043e\u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0434\u043d\u0435\u0432\u043d\u043e\u0439 \u2600\ufe0f \u0438 \u043d\u043e\u0447\u043d\u043e\u0439 ? \u0440\u0435\u0436\u0438\u043c\u044b. \u041e\u0441\u043d\u043e\u0432\u043d\u044b\u0439 \u0440\u0435\u0436\u0438\u043c \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u0432\u0438\u0441\u0435\u0442\u044c \u043e\u0442 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b. \u0412 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u0430 \u0441\u043c\u0435\u043d\u0430 \u0440\u0435\u0436\u0438\u043c\u043e\u0432 \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0434\u043d\u0435\u0432\u043d\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u044d\u0442\u043e \u0441\u043b\u0435\u0433\u043a\u0430 \u0432\u044b\u0445\u043e\u0434\u0438\u0442 \u0437\u0430 \u0440\u0430\u043c\u043a\u0438 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0446\u0435\u043b\u0438 \u043d\u0430\u0448\u0435\u0439 \u0441\u0442\u0430\u0442\u044c\u0438.<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 <code>app\/theme.dart<\/code> \u0438 \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<pre><code class=\"dart\">import 'package:flutter\/material.dart';  \/\/\/ Global reference to application colors. abstract class AppColors {   \/\/\/ Dark color.   static const dark = Colors.black;    static const light = Color(0xFFFAFAFA);    \/\/\/ Grey background accent.   static const grey = Color(0xFF262626);    \/\/\/ Primary text color   static const primaryText = Colors.white;    \/\/\/ Secondary color.   static const secondary = Color(0xFF0095F6);    \/\/\/ Color to use for favorite icons (indicating a like).   static const like = Colors.red;    \/\/\/ Grey faded color.   static const faded = Colors.grey;    \/\/\/ Light grey color   static const ligthGrey = Color(0xFFEEEEEE);    \/\/\/ Top gradient color used in various UI components.   static const topGradient = Color(0xFFE60064);    \/\/\/ Bottom gradient color used in various UI components.   static const bottomGradient = Color(0xFFFFB344); }  \/\/\/ Global reference to application [TextStyle]s. abstract class AppTextStyle {   \/\/\/ A medium bold text style.   static const textStyleBoldMedium = TextStyle(     fontWeight: FontWeight.w600,   );    \/\/\/ A bold text style.   static const textStyleBold = TextStyle(     fontWeight: FontWeight.bold,   );    static const textStyleSmallBold = TextStyle(     fontWeight: FontWeight.bold,     fontSize: 13,   );    \/\/\/ A faded text style. Uses [AppColors.faded].   static const textStyleFaded =       TextStyle(color: AppColors.faded, fontWeight: FontWeight.w400);    \/\/\/ A faded text style. Uses [AppColors.faded].   static const textStyleFadedSmall = TextStyle(       color: AppColors.faded, fontWeight: FontWeight.w400, fontSize: 11);    \/\/\/ A faded text style. Uses [AppColors.faded].   static const textStyleFadedSmallBold = TextStyle(       color: AppColors.faded, fontWeight: FontWeight.w500, fontSize: 11);    \/\/\/ Light text style.   static const textStyleLight = TextStyle(fontWeight: FontWeight.w300);    \/\/\/ Action text   static const textStyleAction = TextStyle(     fontWeight: FontWeight.w700,     color: AppColors.secondary,   ); }  \/\/\/ Global reference to the application theme. class AppTheme {   final _darkBase = ThemeData.dark();   final _lightBase = ThemeData.light();    \/\/\/ Dark theme and its settings.   ThemeData get darkTheme => _darkBase.copyWith(         visualDensity: VisualDensity.adaptivePlatformDensity,         backgroundColor: AppColors.dark,         scaffoldBackgroundColor: AppColors.dark,         appBarTheme: _darkBase.appBarTheme.copyWith(           backgroundColor: AppColors.dark,           foregroundColor: AppColors.light,           iconTheme: const IconThemeData(color: AppColors.light),           elevation: 0,         ),         bottomNavigationBarTheme: _darkBase.bottomNavigationBarTheme.copyWith(           backgroundColor: AppColors.dark,           selectedItemColor: AppColors.light,         ),         outlinedButtonTheme: OutlinedButtonThemeData(           style: ButtonStyle(             side: MaterialStateProperty.all(               const BorderSide(                 color: AppColors.grey,               ),             ),             foregroundColor: MaterialStateProperty.all&lt;Color>(               AppColors.light,             ),             backgroundColor: MaterialStateProperty.all&lt;Color>(               AppColors.dark,             ),             overlayColor: MaterialStateProperty.all&lt;Color>(               AppColors.grey,             ),           ),         ),         elevatedButtonTheme: ElevatedButtonThemeData(           style: ButtonStyle(             backgroundColor: MaterialStateProperty.all&lt;Color>(               AppColors.secondary,             ),             foregroundColor: MaterialStateProperty.all&lt;Color>(               AppColors.primaryText,             ),             overlayColor: MaterialStateProperty.all&lt;Color>(               AppColors.grey,             ),           ),         ),         textButtonTheme: TextButtonThemeData(           style: ButtonStyle(             foregroundColor: MaterialStateProperty.all&lt;Color>(               AppColors.secondary,             ),             overlayColor: MaterialStateProperty.all&lt;Color>(               AppColors.grey,             ),             textStyle: MaterialStateProperty.all&lt;TextStyle>(               const TextStyle(                 color: AppColors.secondary,                 fontSize: 16,                 fontWeight: FontWeight.w600,               ),             ),           ),         ),         brightness: Brightness.dark,         colorScheme:             _darkBase.colorScheme.copyWith(secondary: AppColors.secondary),       );    ThemeData get lightTheme => _lightBase.copyWith(         visualDensity: VisualDensity.adaptivePlatformDensity,         backgroundColor: AppColors.light,         scaffoldBackgroundColor: AppColors.light,         appBarTheme: _lightBase.appBarTheme.copyWith(           backgroundColor: AppColors.light,           foregroundColor: AppColors.dark,           iconTheme: const IconThemeData(color: AppColors.dark),           elevation: 0,         ),         bottomNavigationBarTheme: _lightBase.bottomNavigationBarTheme.copyWith(           backgroundColor: AppColors.light,           selectedItemColor: AppColors.dark,         ),         snackBarTheme:             _lightBase.snackBarTheme.copyWith(backgroundColor: AppColors.dark),         outlinedButtonTheme: OutlinedButtonThemeData(           style: ButtonStyle(             side: MaterialStateProperty.all(               const BorderSide(                 color: AppColors.ligthGrey,               ),             ),             foregroundColor: MaterialStateProperty.all&lt;Color>(               AppColors.dark,             ),             backgroundColor: MaterialStateProperty.all&lt;Color>(               AppColors.light,             ),             overlayColor: MaterialStateProperty.all&lt;Color>(               AppColors.ligthGrey,             ),           ),         ),         elevatedButtonTheme: ElevatedButtonThemeData(           style: ButtonStyle(             backgroundColor: MaterialStateProperty.all&lt;Color>(               AppColors.secondary,             ),             foregroundColor: MaterialStateProperty.all&lt;Color>(               AppColors.primaryText,             ),             overlayColor: MaterialStateProperty.all&lt;Color>(               AppColors.ligthGrey,             ),           ),         ),         textButtonTheme: TextButtonThemeData(           style: ButtonStyle(             foregroundColor: MaterialStateProperty.all&lt;Color>(               AppColors.secondary,             ),             textStyle: MaterialStateProperty.all&lt;TextStyle>(               const TextStyle(                 color: AppColors.secondary,                 fontSize: 16,                 fontWeight: FontWeight.w600,               ),             ),             overlayColor: MaterialStateProperty.all&lt;Color>(               AppColors.ligthGrey,             ),           ),         ),         brightness: Brightness.light,         colorScheme:             _lightBase.colorScheme.copyWith(secondary: AppColors.secondary),       ); }<\/code><\/pre>\n<p>\u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043d\u0435 \u0442\u043e\u0440\u043e\u043f\u0438\u0442\u044c\u0441\u044f \u0438 \u0438\u0437\u0443\u0447\u0438\u0442\u044c \u044d\u0442\u043e\u0442 \u043a\u043e\u0434 \u0432 \u0441\u0432\u043e\u0435\u043c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u043c \u0442\u0435\u043c\u043f\u0435, \u0438\u043b\u0438 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c\u0441\u044f \u043d\u0430 \u043d\u0435\u043c \u043f\u043e\u0437\u0436\u0435, \u043a\u043e\u0433\u0434\u0430 \u043c\u044b \u0431\u0443\u0434\u0435\u0442 \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0437 \u0442\u0435\u0440\u043c\u0438\u043d\u043e\u0432, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0445\u0441\u044f \u0432 \u043d\u0435\u043c.<\/p>\n<p>\u0412 \u0431\u0430\u0440\u0440\u0435\u043b\u044c-\u0444\u0430\u0439\u043b\u0435 <code>state\/state.dart<\/code> \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0441\u0442\u0440\u043e\u043a\u0438:<\/p>\n<pre><code class=\"dart\">export 'state\/state.dart'; export 'theme.dart'; \/\/ ADD THIS<\/code><\/pre>\n<h2>\u041c\u043e\u0434\u0435\u043b\u0438<\/h2>\n<p>\u041c\u043e\u0436\u0435\u0442\u0435 \u043b\u0438 \u0432\u044b \u043f\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0432 \u0442\u043e, \u0447\u0442\u043e \u0432 \u0442\u0430\u043a\u043e\u043c \u043e\u0433\u0440\u043e\u043c\u043d\u043e\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438 \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441 \u043d\u0443\u043b\u044f \u0432\u0441\u0435\u0433\u043e \u043b\u0438\u0448\u044c \u043e\u0434\u0438\u043d \u043a\u043b\u0430\u0441\u0441 \u043c\u043e\u0434\u0435\u043b\u0438? ?<\/p>\n<p>\u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0432 \u044d\u0442\u043e\u043c \u043d\u0435 \u0441\u043e\u043c\u043d\u0435\u0432\u0430\u0442\u044c\u0441\u044f, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e \u043c\u043e\u0434\u0435\u043b\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u044f\u0442\u0441\u044f \u0431\u0443\u0434\u0443\u0442 \u0432\u0437\u044f\u0442\u044b \u0438\u0437 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0445 \u043f\u0430\u043a\u0435\u0442\u043e\u0432 Stream Feed.<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 <code>app\/state\/models\/user.dart<\/code> \u0438 \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<pre><code class=\"dart\">import 'dart:convert';  import 'package:flutter\/material.dart';  \/\/\/ Data model for a feed user's extra data. @immutable class StreamagramUser {   \/\/\/ Data model for a feed user's extra data.   const StreamagramUser({     required this.firstName,     required this.lastName,     required this.fullName,     required this.profilePhoto,     required this.profilePhotoResized,     required this.profilePhotoThumbnail,   });    \/\/\/ Converts a Map to this.   factory StreamagramUser.fromMap(Map&lt;String, dynamic> map) {     return StreamagramUser(       firstName: map['first_name'] as String,       lastName: map['last_name'] as String,       fullName: map['full_name'] as String,       profilePhoto: map['profile_photo'] as String?,       profilePhotoResized: map['profile_photo_resized'] as String?,       profilePhotoThumbnail: map['profile_photo_thumbnail'] as String?,     );   }    \/\/\/ Converts json to this.   factory StreamagramUser.fromJson(String source) =>       StreamagramUser.fromMap(json.decode(source) as Map&lt;String, dynamic>);    \/\/\/ User's first name   final String firstName;    \/\/\/ User's last name   final String lastName;    \/\/\/ User's full name   final String fullName;    \/\/\/ URL to user's profile photo.   final String? profilePhoto;    \/\/\/ A 500x500 version of the [profilePhoto].   final String? profilePhotoResized;    \/\/\/ A small thumbnail version of the [profilePhoto].   final String? profilePhotoThumbnail;    \/\/\/ Convenient method to replace certain fields.   StreamagramUser copyWith({     String? firstName,     String? lastName,     String? fullName,     String? profilePhoto,     String? profilePhotoResized,     String? profilePhotoThumbnail,   }) {     return StreamagramUser(       firstName: firstName ?? this.firstName,       lastName: lastName ?? this.lastName,       fullName: fullName ?? this.fullName,       profilePhoto: profilePhoto ?? this.profilePhoto,       profilePhotoResized: profilePhotoResized ?? this.profilePhotoResized,       profilePhotoThumbnail:           profilePhotoThumbnail ?? this.profilePhotoThumbnail,     );   }    \/\/\/ Converts this model to a Map.   Map&lt;String, dynamic> toMap() {     return {       'first_name': firstName,       'last_name': lastName,       'full_name': fullName,       'profile_photo': profilePhoto,       'profile_photo_resized': profilePhotoResized,       'profile_photo_thumbnail': profilePhotoThumbnail,     };   }    \/\/\/ Converts this class to json.   String toJson() => json.encode(toMap());    @override   String toString() {     return '''UserData(firstName: $firstName, lastName: $lastName, fullName: $fullName, profilePhoto: $profilePhoto, profilePhotoResized: $profilePhotoResized, profilePhotoThumbnail: $profilePhotoThumbnail)''';   }    @override   bool operator ==(Object other) {     if (identical(this, other)) return true;      return other is StreamagramUser &amp;&amp;         other.firstName == firstName &amp;&amp;         other.lastName == lastName &amp;&amp;         other.fullName == fullName &amp;&amp;         other.profilePhoto == profilePhoto &amp;&amp;         other.profilePhotoResized == profilePhotoResized &amp;&amp;         other.profilePhotoThumbnail == profilePhotoThumbnail;   }    @override   int get hashCode {     return firstName.hashCode ^         lastName.hashCode ^         fullName.hashCode ^         profilePhoto.hashCode ^         profilePhotoResized.hashCode ^         profilePhotoThumbnail.hashCode;   } }<\/code><\/pre>\n<p>\u042d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0432\u0430\u0448\u0438\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u043c \u043a\u043b\u0430\u0441\u0441\u043e\u043c \u0434\u0430\u043d\u043d\u044b\u043c (<strong>User Data Class<\/strong>). \u041e\u043d \u0445\u0440\u0430\u043d\u0438\u0442 \u0432 \u0441\u0435\u0431\u0435 \u0440\u044f\u0434 \u043f\u043e\u043b\u0435\u0439 \u0438 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0442\u0430\u043a\u0438\u0435 \u0443\u0434\u043e\u0431\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u043a\u0430\u043a: <code>toMap<\/code>, <code>fromMap<\/code>, \u0438 <code>copyWith<\/code>. \u041e\u043d\u0438 \u043f\u0440\u0438\u0433\u043e\u0434\u044f\u0442\u0441\u044f \u043d\u0430\u043c \u043f\u043e\u0437\u0436\u0435. \u041c\u044b \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u044d\u0442\u043e\u0442 \u043a\u043b\u0430\u0441\u0441 \u043f\u043e \u043e\u0434\u043d\u043e\u0439 \u043f\u0440\u0438\u0447\u0438\u043d\u0435 &#8212; \u0447\u0442\u043e\u0431\u044b \u043c\u044b \u043c\u043e\u0433\u043b\u0438 \u043b\u0435\u0433\u043a\u043e \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0438\u0437 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f Stream Feed.<\/p>\n<p>\u0425\u043e\u0442\u044c \u0443 \u043d\u0430\u0441 \u0432\u0441\u0435\u0433\u043e \u0438 \u043e\u0434\u043d\u0430 \u043c\u043e\u0434\u0435\u043b\u044c, \u043c\u044b \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u043f\u043e\u0434\u0430\u0432\u0430\u0442\u044c \u043f\u043b\u043e\u0445\u043e\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u0438 \u0432\u0441\u0435 \u0440\u0430\u0432\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043d\u0430\u0448 \u0431\u0430\u0440\u0440\u0435\u043b\u044c-\u0444\u0430\u0439\u043b.<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 <code>app\/state\/models\/models.dart<\/code> \u0438 \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<pre><code class=\"dart\">export 'user.dart';<\/code><\/pre>\n<p>\u0412 \u0431\u0430\u0440\u0440\u0435\u043b\u044c-\u0444\u0430\u0439\u043b\u0435 <code>app\/state\/state.dart<\/code> \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0441\u0442\u0440\u043e\u043a\u0438:<\/p>\n<pre><code class=\"dart\">export 'demo_users.dart'; export 'app_state.dart'; export 'models\/models.dart'; \/\/ ADD THIS<\/code><\/pre>\n<h2>\u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c (Provider)<\/h2>\n<p>\u041f\u0440\u0435\u0434\u043c\u0435\u0442 \u0432\u0435\u0447\u043d\u044b\u0445 \u0441\u043f\u043e\u0440\u043e\u0432.<\/p>\n<p>\u0414\u043b\u044f \u043d\u0430\u0448\u0435\u0433\u043e \u0438\u043d\u0441\u0442\u0430\u0433\u0440\u0430\u043c \u043a\u043b\u043e\u043d\u0430 \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0431\u0430\u0437\u043e\u0432\u044b\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u043c\u044b \u043c\u043e\u0433\u043b\u0438 \u043b\u0435\u0433\u043a\u043e \u0432\u043d\u043e\u0441\u0438\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432 \u043d\u0430\u0448 UI.<\/p>\n<p>\u0411\u043e\u043b\u044c\u0448\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0431\u0443\u0434\u0435\u0442 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043f\u0430\u043a\u0435\u0442\u0430 <a href=\"https:\/\/pub.dev\/packages\/stream_feed_flutter_core\" rel=\"noopener noreferrer nofollow\"><strong>stream_feed_flutter_core<\/strong> package<\/a>. \u041e\u0434\u043d\u0430\u043a\u043e \u043d\u0430\u043c \u0432\u0441\u0435 \u0440\u0430\u0432\u043d\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c \u043b\u0435\u0433\u043a\u0438\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0447\u0442\u043e\u0431\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0432 \u043d\u0430\u0448\u0435\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 &#8212; \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439).<\/p>\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u043d\u0435 \u043f\u044b\u0442\u0430\u0435\u043c\u0441\u044f \u043e\u0442\u0441\u0442\u0430\u0438\u0432\u0430\u0442\u044c \u043a\u0430\u043a\u0443\u044e-\u043b\u0438\u0431\u043e \u0442\u043e\u0447\u043a\u0443 \u0437\u0440\u0435\u043d\u0438\u044f \u043f\u043e \u043f\u043e\u0432\u043e\u0434\u0443 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c. \u041f\u043e\u0440\u043e\u0439, \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0432\u0438\u0434\u0436\u0435\u0442 \u0442\u0438\u043f\u0430 <a href=\"https:\/\/api.flutter.dev\/flutter\/widgets\/InheritedWidget-class.html\" rel=\"noopener noreferrer nofollow\">Inherited<\/a> &#8212; \u0432\u0441\u0435 \u0447\u0442\u043e \u0432\u0430\u043c \u043d\u0443\u0436\u043d\u043e; \u0430 \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f <a href=\"https:\/\/pub.dev\/packages\/provider\" rel=\"noopener noreferrer nofollow\">Provider<\/a> \u0432\u0438\u0434\u0436\u0435\u0442\u044b \u0442\u0430\u043a\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u0441\u0442\u0430\u043d\u043e\u0432\u044f\u0442\u0441\u044f \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u044b\u043c\u0438 \u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438. \u041a \u0442\u043e\u043c\u0443 \u0436\u0435, <a href=\"https:\/\/pub.dev\/packages\/provider\" rel=\"noopener noreferrer nofollow\">Provider<\/a> \u0442\u0430\u043a\u0436\u0435 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u043c\u044b \u043f\u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u043c\u0441\u044f \u043f\u043e\u0437\u0436\u0435 \u0432 \u0441\u0442\u0430\u0442\u044c\u0435.<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u0444\u0430\u0439\u043b <code>app\/state\/app_state.dart<\/code> \u0438 \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0432 \u043d\u0435\u0433\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<pre><code class=\"dart\">import 'package:flutter\/material.dart'; import 'package:stream_feed_flutter_core\/stream_feed_flutter_core.dart'; import 'models\/models.dart';  import 'demo_users.dart';  \/\/\/ State related to Stream-agram app. \/\/\/ \/\/\/ Manages the connection and stores a references to the [StreamFeedClient] \/\/\/ and [StreamagramUser]. \/\/\/ \/\/\/ Provides various convenience methods. class AppState extends ChangeNotifier {   \/\/\/ Create new [AppState].   AppState({     required StreamFeedClient client,   }) : _client = client;    late final StreamFeedClient _client;    \/\/\/ Stream Feed client.   StreamFeedClient get client => _client;    \/\/\/ Stream Feed user - [StreamUser].   StreamUser get user => _client.currentUser!;    StreamagramUser? _streamagramUser;    \/\/\/ The extraData from [user], mapped to an [StreamagramUser] object.   StreamagramUser? get streamagramUser => _streamagramUser;    \/\/\/ Connect to Stream Feed with one of the demo users, using a predefined,   \/\/\/ hardcoded token.   \/\/\/   \/\/\/ THIS IS ONLY FOR DEMONSTRATIONS PURPOSES. USER TOKENS SHOULD NOT BE   \/\/\/ HARDCODED LIKE THIS.   Future&lt;bool> connect(DemoAppUser demoUser) async {     final currentUser = await _client.setUser(       User(id: demoUser.id),       demoUser.token!,       extraData: demoUser.data,     );         if (currentUser.data != null) {       _streamagramUser = StreamagramUser.fromMap(currentUser.data!);       notifyListeners();       return true;     } else {       return false;     }   } }<\/code><\/pre>\n<p>\u0414\u0430\u043d\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u043d\u0435 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0441\u043b\u043e\u0436\u043d\u044b\u0439. \u0414\u0430\u043b\u0435\u0435 \u0432 \u0441\u0442\u0430\u0442\u044c\u0435, \u043c\u044b \u0435\u0449\u0435 \u0432\u0435\u0440\u043d\u0435\u043c\u0441\u044f \u043a \u043d\u0435\u043c\u0443 \u0438 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u043c \u043a\u043e\u0434.<\/p>\n<p>\u041d\u0430 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u043e\u043d \u0442\u043e\u043b\u044c\u043a\u043e \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c \u0438 \u0438\u0445 \u0434\u0430\u043d\u043d\u044b\u043c\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u0441\u0442\u0443\u043f\u0430\u044e\u0442 \u0432 \u043d\u0435\u0433\u043e. \u041a\u043b\u0430\u0441\u0441 \u043f\u043e\u0434 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c <a href=\"https:\/\/docs.flutter.dev\/development\/data-and-backend\/state-mgmt\/simple#changenotifier\" rel=\"noopener noreferrer nofollow\"><strong>ChangeNotifier<\/strong><\/a> \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u0441 \u043b\u0435\u0433\u043a\u043e\u0441\u0442\u044c\u044e \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c \u0432\u043e Flutter. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0432\u044b \u0445\u0440\u0430\u043d\u0438\u0442\u0435 \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0432 \u043a\u043b\u0430\u0441\u0441\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043c\u043e\u0436\u0435\u0442\u0435 \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c. \u041a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u0444\u0430\u0439\u043b \u0431\u0443\u0434\u0435\u0442 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d, \u0432\u044b \u0441\u043c\u043e\u0436\u0435\u0442\u0435 \u0443\u0432\u0435\u0434\u043e\u043c\u0438\u0442\u044c \u043b\u044e\u0431\u044b\u0445 \u0432\u0430\u0448\u0438\u0445 \u0441\u043b\u0443\u0448\u0430\u0442\u0435\u043b\u0435\u0439 (listeners) \u043f\u0443\u0442\u0435\u043c \u0432\u044b\u0437\u043e\u0432\u0430 \u043c\u0435\u0442\u043e\u0434\u0430 <code>notifyListeners<\/code>.<\/p>\n<p>\u041a\u0430\u043a \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u043a\u043b\u0430\u0441\u0441\u0435, \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f \u0441 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c <code>_streamagramUser<\/code> \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0443\u0441\u0442\u043e\u0439 \u0438 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u0434\u0430\u043d\u0430 \u043a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u044b \u0432\u044b\u0437\u043e\u0432\u0435\u0442\u0435 \u043c\u0435\u0442\u043e\u0434 <code>connect<\/code>, \u0442\u0440\u0435\u0431\u0443\u044e\u0449\u0438\u0439 \u043a\u043b\u0430\u0441\u0441 <strong>DemoAppUser<\/strong>.<\/p>\n<p>\u0417\u0434\u0435\u0441\u044c \u0432\u0430\u0436\u043d\u043e \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u043a\u043b\u0430\u0441\u0441 <strong>StreamFeedClient<\/strong>. \u041e\u043d \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u043c\u0435\u0442\u043e\u0434\u043e\u0432, \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043e\u043d \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0443\u0435\u0442 \u0441 API Stream Feeds. \u041e\u0434\u043d\u0438\u043c \u0438\u0437 \u0442\u0430\u043a\u0438\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043c\u0435\u0442\u043e\u0434 setUser. \u0414\u0430\u043d\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442 \u0442\u0435\u043a\u0443\u0449\u0438\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 Stream Feeds \u0434\u043b\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0438, \u0434\u0430\u043b\u0435\u0435, \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0438\u0445. \u0415\u0441\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442, \u043e\u043d \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u0435\u0433\u043e, \u0430 \u0435\u0441\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0432\u0441\u0435 \u0442\u0430\u043a\u0438 \u0435\u0441\u0442\u044c, \u043e\u043d \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u0442 \u0435\u0433\u043e \u0434\u0430\u043d\u043d\u044b\u0435 \u0441 \u0431\u044d\u043a\u0435\u043d\u0434\u0430 Stream Feeds.<\/p>\n<p>\u041c\u0435\u0442\u043e\u0434 <code>setUser<\/code> \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u043d\u0430\u043b\u0438\u0447\u0438\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u0430 <strong>User<\/strong>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0432 \u0441\u0435\u0431\u044f:<\/p>\n<ul>\n<li>\n<p>\u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 <strong>\u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440<\/strong> \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f (\u0435\u0433\u043e \u0438\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f);<\/p>\n<\/li>\n<li>\n<p>\u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 <strong>\u0434\u0430\u043d\u043d\u044b\u0435<\/strong> \u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c \u0431\u0443\u0434\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u044b \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 (\u0438\u043c\u044f, URL \u0430\u0434\u0440\u0435\u0441 \u0444\u043e\u0442\u043e \u0433\u043b\u0430\u0432\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0444\u0438\u043b\u044f, \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435, \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0432\u0430\u0448\u0438\u0445 \u043f\u0440\u0435\u0434\u043f\u043e\u0447\u0442\u0435\u043d\u0438\u0439);<\/p>\n<\/li>\n<li>\n<p><strong>\u0442\u043e\u043a\u0435\u043d \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438<\/strong>.<\/p>\n<\/li>\n<\/ul>\n<p>\u0414\u0430\u043d\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u0432\u0445\u043e\u0434\u0438\u0442 \u0432 \u043a\u043b\u0430\u0441\u0441 <a href=\"https:\/\/api.dart.dev\/stable\/2.16.1\/dart-async\/Future-class.html\" rel=\"noopener noreferrer nofollow\">Future<\/a> (\u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0439 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442). \u041a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u043b\u0430\u0441\u0441 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u0442 \u0432 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d, \u0432\u044b \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442\u0435 \u043e\u0431\u044a\u0435\u043a\u0442 <code>_streamagramUser<\/code> \u043f\u0443\u0442\u0435\u043c \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u043a <code>fromMap<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u043d\u043e\u0432\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 \u0432 \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0435 <strong>Map<\/strong>. \u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442\u0435 \u0432\u0441\u0435\u0445 \u0441\u043b\u0443\u0448\u0430\u0442\u0435\u043b\u0435\u0439 \u043f\u0443\u0442\u0435\u043c \u0432\u044b\u0437\u043e\u0432\u0430 <code>notifyListeners<\/code>.<\/p>\n<p>\u041e\u0431\u043d\u043e\u0432\u0438\u0442\u0435 \u0431\u0430\u0440\u0440\u0435\u043b\u044c-\u0444\u0430\u0439\u043b <code>app\/state\/state.dart<\/code>:<\/p>\n<pre><code class=\"dart\">export 'demo_users.dart'; export 'app_state.dart'; \/\/ ADD THIS<\/code><\/pre>\n<h2>\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0438 Provider(\u044b)<\/h2>\n<p>\u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u043d\u043e\u0432\u044b\u0439 \u0444\u0430\u0439\u043b. \u041d\u0430\u0437\u043e\u0432\u0438\u0442\u0435 \u0435\u0433\u043e <code>app\/stream_agram.dart<\/code> \u0438 \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0432 \u043d\u0435\u0433\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<pre><code class=\"dart\">import 'package:flutter\/material.dart'; import 'package:provider\/provider.dart'; import 'package:stream_agram\/app\/app.dart'; import 'package:stream_feed_flutter_core\/stream_feed_flutter_core.dart';  import '..\/components\/login\/login.dart';  \/\/\/ {@template app} \/\/\/ Main entry point to the Stream-agram application. \/\/\/ {@endtemplate} class StreamagramApp extends StatefulWidget {   \/\/\/ {@macro app}   const StreamagramApp({     Key? key,     required this.appTheme,   }) : super(key: key);    \/\/\/ App's theme data.   final AppTheme appTheme;    @override   State&lt;StreamagramApp> createState() => _StreamagramAppState(); }  class _StreamagramAppState extends State&lt;StreamagramApp> {   final _client = StreamFeedClient('YOUR KEY'); \/\/ TODO: Add API Key   late final appState = AppState(client: _client);    \/\/ Important to only initialize this once.   \/\/ Unless you want to update the bloc state   late final feedBloc = FeedBloc(client: _client);    @override   Widget build(BuildContext context) {     return ChangeNotifierProvider.value(       value: appState,       child: MaterialApp(         title: 'Stream-agram',         theme: widget.appTheme.lightTheme,         darkTheme: widget.appTheme.darkTheme,         themeMode: ThemeMode.dark,         builder: (context, child) {           \/\/ Stream Feeds provider to give access to [FeedBloc]           \/\/ This class comes from Stream Feeds.           return FeedProvider(             bloc: feedBloc,             child: child!,           );         },         home: const LoginScreen(),       ),     );   } }<\/code><\/pre>\n<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0444\u0430\u0439\u043b\u0435, \u043c\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0430\u0436\u043d\u044b\u0445 \u043c\u043e\u043c\u0435\u043d\u0442\u043e\u0432:<\/p>\n<ul>\n<li>\n<p>\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c <strong>StreamFeedClient <\/strong>\u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u0432\u0430\u0448\u0435\u0433\u043e \u043a\u043b\u044e\u0447\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 (<strong>API Key<\/strong>);<\/p>\n<\/li>\n<li>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043a\u043b\u0430\u0441\u0441 <strong>AppState, <\/strong>\u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 <strong>StreamFeedClient<\/strong>;<\/p>\n<\/li>\n<li>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c<strong> FeedBloc (<\/strong>\u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0430 \u0434\u043b\u044f \u0432\u0430\u0448\u0438\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0432 Stream Feeds). \u042d\u0442\u043e\u0442 \u043a\u043b\u0430\u0441\u0441 \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u0432 \u043f\u0430\u043a\u0435\u0442\u0435 <a href=\"https:\/\/pub.dev\/packages\/stream_feed\" rel=\"noopener noreferrer nofollow\">Stream Feeds<\/a>, \u0438 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0447\u0430\u0441\u0442\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f \u043a \u043d\u0435\u043c\u0443 \u043f\u043e\u0437\u0436\u0435 \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435;<\/p>\n<\/li>\n<li>\n<p>\u041e\u0431\u0435\u0440\u0442\u044b\u0432\u0430\u0435\u043c <strong>MaterialApp <\/strong>\u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 <strong>ChangeNotifierProvider <\/strong>\u043e\u0442\u043a\u0440\u044b\u0432\u0430\u044f \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u043e\u0431\u044a\u0435\u043a\u0442\u0443<strong> AppState<\/strong>. \u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u044d\u0442\u043e\u043c\u0443, \u0432\u0441\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0441\u043c\u043e\u0436\u0435\u0442 \u0441 \u043b\u0435\u0433\u043a\u043e\u0441\u0442\u044c\u044e \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044e.\u00a0 \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 factory-\u043c\u0435\u0442\u043e\u0434\u0430 <code>.value<\/code> \u0432\u0430\u0436\u043d\u043e, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043e\u043d \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0443\u0436\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u043e\u043c\u0443 \u043e\u0431\u044a\u0435\u043a\u0442\u0443 appState;<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u0435\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 LoginScreen\u00a0 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0443 <strong>home<\/strong>. \u042d\u0442\u043e \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u043d\u0430\u043c \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u044d\u043a\u0440\u0430\u043d\u0430 \u0432\u0445\u043e\u0434\u0430 \u0432 \u0441\u043a\u043e\u0440\u043e\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u0438;<\/p>\n<\/li>\n<li>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 <strong>Builder<\/strong>, \u0447\u0442\u043e\u0431\u044b \u043e\u0431\u0435\u0440\u043d\u0443\u0442\u044c \u043d\u0430\u0448\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <strong>FeedProvider<\/strong>, \u0447\u0442\u043e \u0432 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u043e\u0431\u044a\u0435\u043a\u0442\u0443 feedBloc \u0434\u043b\u044f \u0432\u0441\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. <strong>FeedProvider<\/strong> \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c \u0432\u0438\u0434\u0436\u0435\u0442\u0430\u043c Stream Feeds \u0432 \u0446\u0435\u043b\u044f\u0445 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a <strong>FeedBloc<\/strong> \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u043e\u0442 \u0442\u043e\u0433\u043e \u0433\u0434\u0435 \u043e\u043d\u0438 \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u0432 \u0434\u0435\u0440\u0435\u0432\u0435 \u0432\u0438\u0434\u0436\u0435\u0442\u043e\u0432.<\/p>\n<\/li>\n<\/ul>\n<p>\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u0435 \u0432\u0430\u0448 \u0431\u0430\u0440\u0440\u0435\u043b\u044c-\u0444\u0430\u0439\u043b <code>app\/app.dart<\/code> \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code class=\"dart\">export 'state\/state.dart'; export 'theme.dart'; export 'stream_agram.dart'; \/\/ ADD THIS<\/code><\/pre>\n<h2>\u0420\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 \u043a\u043b\u0430\u0441\u0441\u043e\u0432  \u0438 \u0423\u0442\u0438\u043b\u0438\u0442\u044b<\/h2>\n<p>\u0414\u0430\u043b\u0435\u0435, \u0441\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u0444\u0430\u0439\u043b <code>app\/utils.dart<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0445 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u0447\u0430\u0441\u0442\u043e \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0437\u0436\u0435 \u0432 \u0441\u0442\u0430\u0442\u044c\u0435. \u042d\u0442\u0438 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f \u0441\u0434\u0435\u043b\u0430\u044e\u0442 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043f\u0440\u043e\u0449\u0435 \u0432 \u043d\u0430\u0448\u0435\u043c UI \u0438 \u043f\u043e\u043c\u043e\u0433\u0443\u0442 \u0441\u043e\u043a\u0440\u0430\u0442\u0438\u0442\u044c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043e\u0434\u0430, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0435 \u043d\u0430\u043c \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0447\u0430\u0441\u0442\u043e \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u044e\u0449\u0438\u0445\u0441\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439.<\/p>\n<p>\u042d\u0442\u0438 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0442 \u0432\u0430\u043c:<\/p>\n<ul>\n<li>\n<p>\u0443\u0431\u0438\u0440\u0430\u0442\u044c \u0438 \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u044c \u043d\u0430 \u043f\u043e\u043a\u0430\u0437 \u0432\u0438\u0434\u0436\u0435\u0442 <strong>Snackbar<\/strong> \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435\u043c;<\/p>\n<\/li>\n<li>\n<p>\u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a <strong>AppState<\/strong> \u0438\u0437 <strong>BuildContext<\/strong>.<\/p>\n<\/li>\n<\/ul>\n<p>\u0414\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0432 \u0444\u0430\u0439\u043b \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<pre><code class=\"dart\">import 'package:flutter\/material.dart';  import 'package:provider\/provider.dart';  import 'state\/app_state.dart';  \/\/\/ Extension method on [BuildContext] to easily perform snackbar operations. extension Snackbar on BuildContext {   \/\/\/ Removes the current active [SnackBar], and replaces it with a new snackbar   \/\/\/ with content of [message].   void removeAndShowSnackbar(final String message) {     ScaffoldMessenger.of(this).removeCurrentSnackBar();     ScaffoldMessenger.of(this).showSnackBar(       SnackBar(content: Text(message)),     );   } }  \/\/\/ Extension method on [BuildContext] to easily retrieve providers. extension ProviderX on BuildContext {   \/\/\/ Returns the application [AppState].   AppState get appState => read&lt;AppState>(); }<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043a\u043e\u043d\u0435\u0446 \u043f\u0440\u0438\u0448\u043b\u043e \u0432\u0440\u0435\u043c\u044f \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u043d\u0430\u0448 \u0431\u0430\u0440\u0440\u0435\u043b\u044c-\u0444\u0430\u0439\u043b <code>app\/app.dart<\/code> \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0440\u0430\u0437 ? (\u043f\u043e \u043a\u0440\u0430\u0439\u043d\u0435\u0439 \u043c\u0435\u0440\u0435, \u043f\u043e\u043a\u0430 \u0447\u0442\u043e). \u0414\u043e\u0431\u0430\u0432\u044c\u0442\u0435:<\/p>\n<pre><code class=\"dart\">export 'state\/state.dart'; export 'theme.dart'; export 'stream_agram.dart'; export 'utils.dart'; \/\/ ADD THIS<\/code><\/pre>\n<h2>\u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u043c\u043e\u043a\u043e\u0432\u044b\u0439 \u044d\u043a\u0440\u0430\u043d \u0432\u0445\u043e\u0434\u0430 \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0433\u043e Instagram*<\/h2>\n<p>\u0414\u0430\u043b\u0435\u0435, \u0432\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0431\u0443\u0434\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u044d\u043a\u0440\u0430\u043d \u0432\u0445\u043e\u0434\u0430 &#8212; \u043c\u043e\u043a\u043e\u0432\u044b\u0439 \u044d\u043a\u0440\u0430\u043d, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0432\u044b \u0441\u043c\u043e\u0436\u0435\u0442\u0435 \u0437\u0430\u043b\u043e\u0433\u0438\u043d\u0438\u0442\u044c\u0441\u044f \u043f\u043e\u0434 \u043e\u0434\u043d\u0438\u043c \u0438\u0437 \u0432\u0430\u0448\u0438\u0445 \u0444\u0435\u0439\u043a\u043e\u0432\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439.<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u0444\u0430\u0439\u043b <code>components\/login\/login_screen.d<\/code> \u0438 \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0432 \u043d\u0435\u0433\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<pre><code class=\"dart\">import 'package:flutter\/material.dart';  import '..\/..\/app\/app.dart'; import '..\/home\/home.dart';  \/\/\/ {@template login_screen} \/\/\/ Screen that presents an option of users to authenticate as. \/\/\/ {@endtemplate} class LoginScreen extends StatefulWidget {   \/\/\/ {@macro login_screen}   const LoginScreen({Key? key}) : super(key: key);    @override   _LoginScreenState createState() => _LoginScreenState(); }  class _LoginScreenState extends State&lt;LoginScreen> {   @override   Widget build(BuildContext context) {     final size = MediaQuery.of(context).size;     return Scaffold(       appBar: AppBar(title: const Text('Demo users')),       body: Padding(         padding: const EdgeInsets.symmetric(horizontal: 24.0),         child: SizedBox(           width: size.width,           height: size.height,           child: SingleChildScrollView(             child: Column(               mainAxisAlignment: MainAxisAlignment.center,               children: [                 const SizedBox(height: 42),                 for (final user in DemoAppUser.values)                   Padding(                     padding: const EdgeInsets.all(16.0),                     child: ElevatedButton(                       style: ButtonStyle(                         backgroundColor: MaterialStateColor.resolveWith(                             (states) => Colors.white),                         padding: MaterialStateProperty.all(                           const EdgeInsets.symmetric(horizontal: 4.0),                         ),                         shape: MaterialStateProperty.all(                           RoundedRectangleBorder(                             borderRadius: BorderRadius.circular(24.0),                           ),                         ),                       ),                       onPressed: () async {                         context.removeAndShowSnackbar('Connecting user');                          final success = await context.appState.connect(user);                          if (success) {                           context.removeAndShowSnackbar('User connected');                            await Navigator.of(context).pushReplacement(                             MaterialPageRoute(                               builder: (_) => const HomeScreen(),                             ),                           );                         } else {                           context                               .removeAndShowSnackbar('Could not connect user');                         }                       },                       child: Padding(                         padding: const EdgeInsets.symmetric(                             vertical: 24.0, horizontal: 36.0),                         child: SizedBox(                           width: 200,                           child: Text(                             user.name!,                             style: const TextStyle(                               fontSize: 18,                               color: Colors.blueGrey,                             ),                           ),                         ),                       ),                     ),                   )               ],             ),           ),         ),       ),     );   } }<\/code><\/pre>\n<p>\u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c\u0441\u044f \u043d\u0430 \u044d\u0442\u043e\u043c \u0444\u0430\u0439\u043b\u0435 \u0438 \u043f\u043e\u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0438\u0437\u0443\u0447\u0438\u0442\u044c \u0435\u0433\u043e \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e. \u041a\u0440\u0430\u0442\u043a\u043e, \u044d\u0442\u043e\u0442 \u0432\u0438\u0434\u0436\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<ul>\n<li>\n<p>\u0412\u044b\u0432\u043e\u0434\u0438\u0442 \u043d\u0430 \u043f\u043e\u043a\u0430\u0437 \u043a\u043d\u043e\u043f\u043a\u0438, \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0449\u0438\u0435 \u0438\u043c\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f. \u0415\u0441\u043b\u0438 \u043d\u0430\u0436\u0430\u0442\u044c \u043d\u0430 \u0438\u043c\u044f &#8212; \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0435\u0434\u043f\u0440\u0438\u043d\u044f\u0442\u0430 \u043f\u043e\u043f\u044b\u0442\u043a\u0430 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438;<\/p>\n<\/li>\n<li>\n<p>\u0412\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u043c\u0435\u0442\u043e\u0434 connect \u0432 <strong>AppState<\/strong> \u0438 \u0435\u0441\u043b\u0438 \u043e\u0442\u0432\u0435\u0442 <strong>\u043f\u043e\u043b\u043e\u0436\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 <\/strong>(<strong>true<\/strong>), \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u043d\u0430 <strong>HomeScreen <\/strong>(\u0433\u043b\u0430\u0432\u043d\u044b\u0439 \u044d\u043a\u0440\u0430\u043d); \u0432 \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 Snackbar \u0432\u044b\u0434\u0430\u0441\u0442 \u043e\u0448\u0438\u0431\u043a\u0443;<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f <strong>Snackbar<\/strong> \u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f.<\/p>\n<\/li>\n<\/ul>\n<p>\u041a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u044b \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u0432\u0430\u0448 \u044d\u043a\u0440\u0430\u043d \u0431\u0443\u0434\u0435\u0442 \u0438\u043c\u0435\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0432\u0438\u0434:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/913\/cd9\/663\/913cd96633286ae4ee23ec5add914c0d.png\" width=\"293\" height=\"633\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/913\/cd9\/663\/913cd96633286ae4ee23ec5add914c0d.png\"\/><\/figure>\n<p>\u041d\u0435 \u0437\u0430\u0431\u0443\u0434\u044c\u0442\u0435 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0432\u0430\u0448 \u0431\u0430\u0440\u0440\u0435\u043b\u044c-\u0444\u0430\u0439\u043b \u0434\u043b\u044f \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 <code>components\/login\/login.dart<\/code>:<\/p>\n<pre><code class=\"dart\">export 'login_screen.dart';<\/code><\/pre>\n<h2>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0433\u043b\u0430\u0432\u043d\u044b\u0439 \u044d\u043a\u0440\u0430\u043d \u043a\u0430\u043a \u0432 Instagram<\/h2>\n<p>\u042d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u043c \u044d\u043a\u0440\u0430\u043d\u043e\u043c \u0432\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043e\u0442\u043a\u0443\u0434\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438 \u0441\u043c\u043e\u0433\u0443\u0442 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u0442\u044c \u043d\u0430 \u0434\u0440\u0443\u0433\u0438\u0435 \u044d\u043a\u0440\u0430\u043d\u044b \u0438 \u0432\u043a\u043b\u0430\u0434\u043a\u0438.<\/p>\n<p>\u041e\u0442\u043a\u0440\u044b\u0432\u0430\u044f \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0438\u0439 Instagram*, \u043c\u044b \u0438\u043c\u0435\u0435\u043c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u0442\u044c \u043d\u0430 \u0434\u0440\u0443\u0433\u0438\u0435 \u0432\u043a\u043b\u0430\u0434\u043a\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0439 \u043f\u0430\u043d\u0435\u043b\u0438 \u0432\u043d\u0438\u0437\u0443 \u044d\u043a\u0440\u0430\u043d\u0430. \u041c\u044b \u0433\u043e\u0432\u043e\u0440\u0438\u043c \u043f\u0440\u043e \u0442\u0430\u043a\u0438\u0435 \u0432\u043a\u043b\u0430\u0434\u043a\u0438 \u043a\u0430\u043a:<\/p>\n<ul>\n<li>\n<p>\u0412\u043a\u043b\u0430\u0434\u043a\u0430 \u0441 \u0445\u0440\u043e\u043d\u043e\u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u043b\u0435\u043d\u0442\u043e\u0439 \u0438\u043b\u0438 \u0434\u043e\u043c\u0430\u0448\u043d\u044f\u044f \u0432\u043a\u043b\u0430\u0434\u043a\u0430 (\u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u043f\u0440\u0438 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438);<\/p>\n<\/li>\n<li>\n<p>\u0412\u043a\u043b\u0430\u0434\u043a\u0430 \u043f\u043e\u0438\u0441\u043a\u0430;<\/p>\n<\/li>\n<li>\n<p>\u0412\u043a\u043b\u0430\u0434\u043a\u0430 Reels;<\/p>\n<\/li>\n<li>\n<p>\u0412\u043a\u043b\u0430\u0434\u043a\u0430 \u00ab\u041c\u0430\u0433\u0430\u0437\u0438\u043d\u00bb;<\/p>\n<\/li>\n<li>\n<p>\u0412\u043a\u043b\u0430\u0434\u043a\u0430 \u043f\u0440\u043e\u0444\u0438\u043b\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f.<\/p>\n<\/li>\n<\/ul>\n<p>\u0412 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438, \u0443 \u0432\u0430\u0441 \u0442\u0430\u043a\u0436\u0435 \u0435\u0441\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0431\u044b\u0441\u0442\u0440\u043e \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043a \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0447\u0430\u0441\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0432\u0435\u0440\u0445\u043d\u0435\u0439 \u043f\u0430\u043d\u0435\u043b\u0438. \u042d\u0442\u043e \u0442\u0430\u043a\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043a\u0430\u043a:<\/p>\n<ul>\n<li>\n<p>\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0439 \u043f\u043e\u0441\u0442;\u00a0<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f;<\/p>\n<\/li>\n<li>\n<p>\u041e\u0442\u043a\u0440\u044b\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f.<\/p>\n<\/li>\n<\/ul>\n<p>\u041d\u0430 \u0434\u0430\u043d\u043d\u043e\u043c \u044d\u0442\u0430\u043f\u0435 \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u043d\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u041f\u043e\u0437\u0436\u0435, \u043c\u044b \u0438\u0437\u043c\u0435\u043d\u0438\u043c \u043a\u043e\u0434, \u0447\u0442\u043e\u0431\u044b \u0432\u043d\u0435\u0441\u0442\u0438 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0443\u043b\u0443\u0447\u0448\u0435\u043d\u0438\u044f \u0432 \u0440\u0430\u0431\u043e\u0442\u0443 \u0433\u043b\u0430\u0432\u043d\u043e\u0433\u043e \u044d\u043a\u0440\u0430\u043d\u0430 \u0438 \u0435\u0433\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c.<\/p>\n<p>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u043c\u044b \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0441\u044f <strong>PageView<\/strong> \u0438 <strong>BottomNavigationBar<\/strong> \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u044f \u0432 \u043d\u0430\u0448\u0435\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438 \u0431\u044b\u043b\u0430 \u043f\u043e\u0445\u043e\u0436\u0430 \u043d\u0430 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0438\u0439 Instagram \u0438 \u0438\u043c\u0435\u043b\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0432\u043a\u043b\u0430\u0434\u043a\u0438:<\/p>\n<ul>\n<li>\n<p>\u0425\u0440\u043e\u043d\u043e\u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0443\u044e \u043b\u0435\u043d\u0442\u0443;<\/p>\n<\/li>\n<li>\n<p>\u0412\u043a\u043b\u0430\u0434\u043a\u0443 \u043f\u043e\u0438\u0441\u043a\u0430;<\/p>\n<\/li>\n<li>\n<p>\u0412\u043a\u043b\u0430\u0434\u043a\u0443 \u043f\u0440\u043e\u0444\u0438\u043b\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f.<\/p>\n<\/li>\n<\/ul>\n<p>\u041f\u043e\u043a\u0430 \u0447\u0442\u043e, \u0432\u0441\u0435 \u044d\u0442\u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0431\u0443\u0434\u0443\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0435\u043a\u0441\u0442-\u0437\u0430\u0433\u043b\u0443\u0448\u043a\u0443, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0438\u0437\u043c\u0435\u043d\u0438\u043c \u043f\u043e\u0437\u0436\u0435.<\/p>\n<p>\u041c\u044b \u0442\u0430\u043a\u0436\u0435 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043a\u043b\u0430\u0441\u0441 <strong>AppBar<\/strong> (\u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0432\u0435\u0440\u0445\u043d\u0435\u0439 \u043f\u0430\u043d\u0435\u043b\u044c\u044e \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f),<strong> <\/strong>\u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e <strong>title <\/strong>(\u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435). \u041f\u043e\u0437\u0436\u0435 \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0441\u044e\u0434\u0430 \u0431\u043e\u043b\u044c\u0448\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f.<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u0444\u0430\u0439\u043b <code>components\/home\/home_screen.dart<\/code> \u0438 \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0432 \u043d\u0435\u0433\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<pre><code class=\"dart\">import 'package:flutter\/cupertino.dart'; import 'package:flutter\/material.dart'; import 'package:google_fonts\/google_fonts.dart';  import '..\/..\/app\/app.dart';  \/\/\/ HomeScreen of the application. \/\/\/ \/\/\/ Provides Navigation to various pages in the application and maintains their \/\/\/ state. \/\/\/ \/\/\/ Default first page is [TimelinePage]. class HomeScreen extends StatefulWidget {   \/\/\/ Creates a new [HomeScreen]   const HomeScreen({Key? key}) : super(key: key);    \/\/\/ List of pages available from the home screen.   static const List&lt;Widget> _homePages = &lt;Widget>[     Center(child: Text('TimelinePage')),     Center(child: Text('SearchPage')),     Center(child: Text('ProfilePage')),   ];    @override   _HomeScreenState createState() => _HomeScreenState(); }  class _HomeScreenState extends State&lt;HomeScreen> {   final PageController pageController = PageController();    @override   Widget build(BuildContext context) {     final iconColor = Theme.of(context).appBarTheme.iconTheme!.color!;     return Scaffold(       appBar: AppBar(         title:             Text('Stream-agram', style: GoogleFonts.grandHotel(fontSize: 32)),         elevation: 0,         centerTitle: false,       ),       body: PageView(         controller: pageController,         physics: const NeverScrollableScrollPhysics(),         children: HomeScreen._homePages,       ),       bottomNavigationBar: _StreamagramBottomNavBar(         pageController: pageController,       ),     );   } }  class _StreamagramBottomNavBar extends StatefulWidget {   const _StreamagramBottomNavBar({     Key? key,     required this.pageController,   }) : super(key: key);    final PageController pageController;    @override   State&lt;_StreamagramBottomNavBar> createState() =>       _StreamagramBottomNavBarState(); }  class _StreamagramBottomNavBarState extends State&lt;_StreamagramBottomNavBar> {   void _onNavigationItemTapped(int index) {     widget.pageController.jumpToPage(index);   }    @override   void initState() {     super.initState();     widget.pageController.addListener(() {       setState(() {});     });   }    @override   Widget build(BuildContext context) {     return Container(       decoration: BoxDecoration(         boxShadow: &lt;BoxShadow>[           BoxShadow(             color: (Theme.of(context).brightness == Brightness.dark)                 ? AppColors.ligthGrey.withOpacity(0.5)                 : AppColors.faded.withOpacity(0.5),             blurRadius: 1,           ),         ],       ),       child: BottomNavigationBar(         onTap: _onNavigationItemTapped,         showSelectedLabels: false,         showUnselectedLabels: false,         elevation: 0,         iconSize: 28,         currentIndex: widget.pageController.page?.toInt() ?? 0,         items: const [           BottomNavigationBarItem(             icon: Icon(Icons.home_outlined),             activeIcon: Icon(Icons.home),             label: 'Home',           ),           BottomNavigationBarItem(             icon: Icon(CupertinoIcons.search),             activeIcon: Icon(               Icons.search,               size: 22,             ),             label: 'Search',           ),           BottomNavigationBarItem(             icon: Icon(Icons.person_outline),             activeIcon: Icon(Icons.person),             label: 'Person',           )         ],       ),     );   } }<\/code><\/pre>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0440\u0430\u0437\u0431\u0435\u0440\u0435\u043c \u044d\u0442\u0443 \u0447\u0430\u0441\u0442\u044c \u043a\u043e\u0434\u0430:<\/p>\n<ul>\n<li>\n<p>\u044d\u0442\u0430 \u0447\u0430\u0441\u0442\u044c \u043a\u043e\u0434\u0430 \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0430 \u043d\u0430 \u0442\u0440\u0438 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u0447\u0430\u0441\u0442\u0438: <strong>AppBar<\/strong>, <strong>PageView<\/strong> \u0438 <strong>BottomNavigationBar<\/strong>;<\/p>\n<\/li>\n<li>\n<p>\u0441\u043f\u0438\u0441\u043e\u043a \u0432\u0438\u0434\u0436\u0435\u0442\u043e\u0432 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0432 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 <code>_homePages<\/code>. \u041d\u0430 \u0434\u0430\u043d\u043d\u043e\u043c \u044d\u0442\u0430\u043f\u0435, \u043e\u043d\u0438 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442 \u0441\u043e\u0431\u043e\u0439 \u043b\u0438\u0448\u044c \u0442\u0435\u043a\u0441\u0442-\u0437\u0430\u0433\u043b\u0443\u0448\u043a\u0443, \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0439 \u0432\u0438\u0434\u0436\u0435\u0442\u043e\u043c <strong>Text<\/strong>;<\/p>\n<\/li>\n<li>\n<p>\u0432 \u043a\u043e\u0434\u0435 \u0442\u0430\u043a\u0436\u0435 \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 <strong>PageController <\/strong>\u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u043c\u0435\u0436\u0434\u0443 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430\u043c\u0438<strong> PageView<\/strong>. \u041e\u043d \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0432\u00a0 <strong>_StreamagramBottomNavBar<\/strong>. \u0417\u0434\u0435\u0441\u044c \u0442\u0430\u043a\u0436\u0435 \u0435\u0441\u0442\u044c \u0441\u043b\u0443\u0448\u0430\u0442\u0435\u043b\u044c, \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0439 \u043a \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0443, \u0447\u0442\u043e\u0431\u044b \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c UI, \u043a\u043e\u0433\u0434\u0430 \u0442\u043e\u0442 \u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f;<\/p>\n<\/li>\n<li>\n<p>\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0444\u0438\u0437\u0438\u043a\u0438 <strong>PageView<\/strong> \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043a\u0430\u043a\u00a0 <code>NeverScrollableScrollPhysics<\/code>. \u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u044d\u0442\u043e\u043c\u0443, \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u043c \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u043c \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0442\u044c\u0441\u044f \u043c\u0435\u0436\u0434\u0443 \u0432\u043a\u043b\u0430\u0434\u043a\u0430\u043c\u0438 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u0430\u0436\u0430\u0442\u0438\u0435 \u043d\u0430 \u043e\u0434\u043d\u0443 \u0438\u0437 \u043d\u0438\u0445 \u0432 \u043d\u0438\u0436\u043d\u0435\u0439 \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0439 \u043f\u0430\u043d\u0435\u043b\u0438;<\/p>\n<\/li>\n<li>\n<p>\u0437\u0434\u0435\u0441\u044c, \u0432 \u043a\u043b\u0430\u0441\u0441\u0435 <strong>AppBar<\/strong>, \u043c\u044b \u0442\u0430\u043a\u0436\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0448\u0440\u0438\u0444\u0442 <code>grandHotel<\/code> \u0438\u0437 \u043f\u0430\u043a\u0435\u0442\u0430 <strong>GoogleFonts<\/strong> \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0448\u0440\u0438\u0444\u0442 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0431\u044b\u043b \u0438\u0434\u0435\u043d\u0442\u0438\u0447\u0435\u043d \u0448\u0440\u0438\u0444\u0442\u0443 \u0432 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0435\u043c Instagram. \u042d\u0442\u043e \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442\u0441\u044f \u0432 \u043b\u0435\u0432\u043e\u0439 \u0432\u0435\u0440\u0445\u043d\u0435\u0439 \u0447\u0430\u0441\u0442\u0438 \u044d\u043a\u0440\u0430\u043d\u0430.<\/p>\n<\/li>\n<\/ul>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0435\u0441\u043b\u0438 \u0432\u044b \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u0442\u043e \u0433\u043b\u0430\u0432\u043d\u044b\u0439 \u044d\u043a\u0440\u0430\u043d \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/3ab\/b28\/a52\/3abb28a528cf15ce4e6c735524412cbb.png\" width=\"293\" height=\"633\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/3ab\/b28\/a52\/3abb28a528cf15ce4e6c735524412cbb.png\"\/><\/figure>\n<p>\u0418 \u0432\u044b \u0442\u0430\u043a\u0436\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u0438\u043c\u0435\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0442\u044c\u0441\u044f \u043c\u0435\u0436\u0434\u0443 \u0440\u0430\u0437\u043d\u044b\u043c\u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430\u043c\u0438, \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f <strong>PageView<\/strong>.<\/p>\n<h2>\u0422\u043e\u0447\u043a\u0430 \u0432\u0445\u043e\u0434\u0430 (main.dart)<\/h2>\n<p>\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0448\u0442\u0440\u0438\u0445. \u0423\u0434\u0430\u043b\u0438\u0442\u0435 \u0432\u0441\u0435 \u0438\u0437 <code>main.dart<\/code> \u0438 \u0432\u0441\u0442\u0430\u0432\u044c\u0442\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<pre><code class=\"dart\">import 'package:flutter\/material.dart';  import 'app\/app.dart';  void main() {   WidgetsFlutterBinding.ensureInitialized();   final theme = AppTheme();   runApp(StreamagramApp(appTheme: theme)); }<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c, \u0435\u0441\u043b\u0438 \u0432\u044b \u0432\u0441\u0435 \u0441\u0434\u0435\u043b\u0430\u043b\u0438 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e, \u0443 \u0432\u0430\u0441 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u044d\u043a\u0440\u0430\u043d \u0432\u0445\u043e\u0434\u0430, \u0433\u0434\u0435 \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0438 \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043d\u0430 \u0433\u043b\u0430\u0432\u043d\u044b\u0439 \u044d\u043a\u0440\u0430\u043d \u043f\u043e\u0441\u043b\u0435 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438. \u0415\u0441\u043b\u0438 \u0447\u0442\u043e-\u0442\u043e \u043f\u043e\u0448\u043b\u043e \u043d\u0435 \u0442\u0430\u043a, \u043f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u043b\u0438 \u0432\u044b \u0443\u043a\u0430\u0437\u0430\u043b\u0438 \u0442\u043e\u043a\u0435\u043d\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439, \u0438\u0445 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u044b \u0438\u043b\u0438 \u043a\u043b\u044e\u0447 API.<\/p>\n<p>\u0421\u0443\u043f\u0435\u0440 ?. \u0422\u0435\u043f\u0435\u0440\u044c, \u043a\u043e\u0433\u0434\u0430 \u043c\u044b \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u043b\u0438 \u0440\u0430\u0431\u043e\u0442\u0443 \u043d\u0430\u0434 \u0431\u0430\u0437\u043e\u0432\u044b\u043c\u0438 \u0431\u043b\u043e\u043a\u0430\u043c\u0438, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043a \u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u044b\u043c.<\/p>\n<h2>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0430\u0432\u0430\u0442\u0430\u0440 \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u0432\u0438\u0434\u0436\u0435\u0442\u0430 Avatar<\/h2>\n<p>\u041f\u043e \u0445\u043e\u0434\u0443 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0432\u0430\u0448\u0435\u0433\u043e \u0438\u043d\u0441\u0442\u0430\u0433\u0440\u0430\u043c \u043a\u043b\u043e\u043d\u0430, \u0432\u044b \u0431\u0443\u0434\u0435\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 &#8212; \u0432\u0438\u0434\u0436\u0435\u0442\u043e\u0432. \u0421\u0435\u0439\u0447\u0430\u0441, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043e\u0434\u0438\u043d \u0438\u0437 \u043d\u0438\u0445. \u042d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0432\u0438\u0434\u0436\u0435\u0442 Avatar, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u0433\u043b\u0430\u0432\u043d\u043e\u0435 \u0444\u043e\u0442\u043e \u043f\u0440\u043e\u0444\u0438\u043b\u044f (\u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0435\u0441\u043b\u0438 \u043e\u043d\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043e), \u0438\u043b\u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f (\u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u043a\u043e\u0433\u0434\u0430 \u0444\u043e\u0442\u043e \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442).<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 <code>components\/app_widgets\/avatars.dart<\/code>\u00a0 \u0438 \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434:<\/p>\n<pre><code class=\"dart\">import 'package:cached_network_image\/cached_network_image.dart'; import 'package:flutter\/material.dart';  import '..\/..\/app\/app.dart';  \/\/\/ An avatar that displays a user's profile picture. \/\/\/ \/\/\/ Supports different sizes: \/\/\/ - `Avatar.tiny` \/\/\/ - `Avatar.small` \/\/\/ - `Avatar.medium` \/\/\/ - `Avatar.big` \/\/\/ - `Avatar.huge` class Avatar extends StatelessWidget {   \/\/\/ Creates a tiny avatar.   const Avatar.tiny({     Key? key,     required this.streamagramUser,   })  : _avatarSize = _tinyAvatarSize,         _coloredCircle = _tinyColoredCircle,         hasNewStory = false,         fontSize = 12,         isThumbnail = true,         super(key: key);    \/\/\/ Creates a small avatar.   const Avatar.small({     Key? key,     required this.streamagramUser,   })  : _avatarSize = _smallAvatarSize,         _coloredCircle = _smallColoredCircle,         hasNewStory = false,         fontSize = 14,         isThumbnail = true,         super(key: key);    \/\/\/ Creates a medium avatar.   const Avatar.medium({     Key? key,     this.hasNewStory = false,     required this.streamagramUser,   })  : _avatarSize = _mediumAvatarSize,         _coloredCircle = _mediumColoredCircle,         fontSize = 20,         isThumbnail = true,         super(key: key);    \/\/\/ Creates a big avatar.   const Avatar.big({     Key? key,     this.hasNewStory = false,     required this.streamagramUser,   })  : _avatarSize = _largeAvatarSize,         _coloredCircle = _largeColoredCircle,         fontSize = 26,         isThumbnail = false,         super(key: key);    \/\/\/ Creates a huge avatar.   const Avatar.huge({     Key? key,     this.hasNewStory = false,     required this.streamagramUser,   })  : _avatarSize = _hugeAvatarSize,         _coloredCircle = _hugeColoredCircle,         fontSize = 30,         isThumbnail = false,         super(key: key);    \/\/\/ Indicates if the user has a new story. If yes, their avatar is surrounded   \/\/\/ with an indicator.   final bool hasNewStory;    \/\/\/ The user data to show for the avatar.   final StreamagramUser streamagramUser;    \/\/\/ Text size of the user's initials when there is no profile photo.   final double fontSize;    final double _avatarSize;   final double _coloredCircle;    \/\/ Small avatar configuration   static const _tinyAvatarSize = 22.0;   static const _tinyPaddedCircle = _tinyAvatarSize + 2;   static const _tinyColoredCircle = _tinyPaddedCircle * 2 + 4;    \/\/ Small avatar configuration   static const _smallAvatarSize = 30.0;   static const _smallPaddedCircle = _smallAvatarSize + 2;   static const _smallColoredCircle = _smallPaddedCircle * 2 + 4;    \/\/ Medium avatar configuration   static const _mediumAvatarSize = 40.0;   static const _mediumPaddedCircle = _mediumAvatarSize + 2;   static const _mediumColoredCircle = _mediumPaddedCircle * 2 + 4;    \/\/ Large avatar configuration   static const _largeAvatarSize = 90.0;   static const _largPaddedCircle = _largeAvatarSize + 2;   static const _largeColoredCircle = _largPaddedCircle * 2 + 4;    \/\/ Huge avatar configuration   static const _hugeAvatarSize = 120.0;   static const _hugePaddedCircle = _hugeAvatarSize + 2;   static const _hugeColoredCircle = _hugePaddedCircle * 2 + 4;    \/\/\/ Whether this avatar uses a thumbnail as an image (low quality).   final bool isThumbnail;    @override   Widget build(BuildContext context) {     final picture = _CircularProfilePicture(       size: _avatarSize,       userData: streamagramUser,       fontSize: fontSize,       isThumbnail: isThumbnail,     );      if (!hasNewStory) {       return picture;     }     return Container(       width: _coloredCircle,       height: _coloredCircle,       decoration: const BoxDecoration(         color: Colors.red,         shape: BoxShape.circle,       ),       child: Center(child: picture),     );   } }  class _CircularProfilePicture extends StatelessWidget {   const _CircularProfilePicture({     Key? key,     required this.size,     required this.userData,     required this.fontSize,     this.isThumbnail = false,   }) : super(key: key);    final StreamagramUser userData;    final double size;   final double fontSize;    final bool isThumbnail;    @override   Widget build(BuildContext context) {     final profilePhoto = isThumbnail         ? userData.profilePhotoThumbnail         : userData.profilePhotoResized;      return (profilePhoto == null)         ? Container(             width: size,             height: size,             decoration: const BoxDecoration(               color: AppColors.secondary,               shape: BoxShape.circle,             ),             child: Center(               child: Text(                 '${userData.firstName[0]}${userData.lastName[0]}',                 style: TextStyle(fontSize: fontSize),               ),             ),           )         : SizedBox(             width: size,             height: size,             child: CachedNetworkImage(               imageUrl: profilePhoto,               fit: BoxFit.contain,               imageBuilder: (context, imageProvider) => Container(                 width: size,                 height: size,                 decoration: BoxDecoration(                   shape: BoxShape.circle,                   image:                       DecorationImage(image: imageProvider, fit: BoxFit.cover),                 ),               ),             ),           );   } }<\/code><\/pre>\n<p>\u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e \u0438\u0437\u0443\u0447\u0438\u0442\u044c \u044d\u0442\u043e\u0442 \u0432\u0438\u0434\u0436\u0435\u0442. \u0412\u0430\u0436\u043d\u044b\u043c \u043c\u043e\u043c\u0435\u043d\u0442\u043e\u043c \u0437\u0434\u0435\u0441\u044c \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0442\u043e, \u0447\u0442\u043e \u043e\u043d \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437\u043d\u044b\u0445 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u043e\u0432, \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u0438\u0445 \u0440\u0430\u0437\u043c\u0435\u0440\u0430\u0445 (\u043a \u043f\u0440\u0438\u043c\u0435\u0440\u0443 &#8212; tiny, large, huge \u0438 \u0442.\u0434.). \u0414\u0430\u043d\u043d\u044b\u0439 \u0432\u0438\u0434\u0436\u0435\u0442 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0432\u0441\u044f\u043a\u0438\u0439 \u0440\u0430\u0437, \u043a\u043e\u0433\u0434\u0430 \u0432\u044b \u0431\u0443\u0434\u0435\u0442\u0435 \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u044c \u043d\u0430 \u043f\u043e\u043a\u0430\u0437 \u0433\u043b\u0430\u0432\u043d\u043e\u0435 \u0444\u043e\u0442\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f (\u0435\u0433\u043e \u0430\u0432\u0430\u0442\u0430\u0440). \u0414\u0430\u043d\u043d\u044b\u0439 \u0432\u0438\u0434\u0436\u0435\u0442\u00a0 \u0442\u0430\u043a\u0436\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043f\u0430\u043a\u0435\u0442 <a href=\"https:\/\/pub.dev\/packages\/cached_network_image\" rel=\"noopener noreferrer nofollow\">cached_network_image package<\/a> \u0434\u043b\u044f \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439.<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u0431\u0430\u0440\u0440\u0435\u043b\u044c-\u0444\u0430\u0439\u043b <code>components\/app_widgets\/app_widgets.dart<\/code> \u0438 \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0439\u0442\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0444\u0430\u0439\u043b:<\/p>\n<pre><code class=\"dart\">export 'avatars.dart';<\/code><\/pre>\n<h2>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0432\u043a\u043b\u0430\u0434\u043a\u0443 \u043f\u0440\u043e\u0444\u0438\u043b\u044f<\/h2>\n<p>\u041a\u0430\u043a \u043c\u0438\u043d\u0438\u043c\u0443\u043c, \u0432\u043a\u043b\u0430\u0434\u043a\u0430 \u043f\u0440\u043e\u0444\u0438\u043b\u044f \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0434\u043e\u043b\u0436\u043d\u0430 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<ul>\n<li>\n<p>\u0433\u043b\u0430\u0432\u043d\u043e\u0435 \u0444\u043e\u0442\u043e \u0438 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435;<\/p>\n<\/li>\n<li>\n<p>\u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0430\u0445 \u0438 \u043f\u043e\u0434\u043f\u0438\u0441\u0447\u0438\u043a\u0430\u0445;<\/p>\n<\/li>\n<li>\n<p>\u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0438\u0439 \u043b\u0435\u0433\u043a\u043e \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0444\u0438\u043b\u044c;<\/p>\n<\/li>\n<li>\n<p>\u043b\u0435\u043d\u0442\u0443 \u043f\u043e\u0441\u0442\u043e\u0432, \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c;<\/p>\n<\/li>\n<li>\n<p>\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0435 \u043f\u043e\u0441\u0442\u044b.<\/p>\n<\/li>\n<\/ul>\n<p>\u0414\u0430\u043b\u0435\u0435, \u043c\u044b \u0434\u0435\u0442\u0430\u043b\u044c\u043d\u043e \u0440\u0430\u0437\u0431\u0435\u0440\u0435\u043c \u043a\u0430\u0436\u0434\u044b\u0439 \u0438\u0437 \u044d\u0442\u0438\u0445 \u043f\u0443\u043d\u043a\u0442\u043e\u0432.<\/p>\n<h2>\u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u043f\u0440\u043e\u0444\u0438\u043b\u044f<\/h2>\n<p>\u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u0444\u0430\u0439\u043b <code>components\/profile\/profile_page.dart<\/code> \u0438 \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0432 \u043d\u0435\u0433\u043e:<\/p>\n<pre><code class=\"dart\">import 'package:flutter\/material.dart'; import 'package:provider\/provider.dart'; import 'package:stream_feed_flutter_core\/stream_feed_flutter_core.dart';  import '..\/..\/app\/app.dart'; import '..\/app_widgets\/app_widgets.dart';  \/\/\/ {@template profile_page} \/\/\/ User profile page. List of user created posts. \/\/\/ {@endtemplate} class ProfilePage extends StatelessWidget {   \/\/\/ {@macro profile_page}   const ProfilePage({Key? key}) : super(key: key);    @override   Widget build(BuildContext context) {     return FlatFeedCore(       feedGroup: 'user',       loadingBuilder: (context) =>           const Center(child: CircularProgressIndicator()),       errorBuilder: (context, error) => const Center(         child: Text('Error loading profile'),       ),       emptyBuilder: (context) => const CustomScrollView(         slivers: [           SliverToBoxAdapter(             child: _ProfileHeader(               numberOfPosts: 0,             ),           ),           SliverToBoxAdapter(             child: _EditProfileButton(),           ),           SliverToBoxAdapter(             child: SizedBox(height: 24),           ),           SliverFillRemaining(child: _NoPostsMessage())         ],       ),       feedBuilder: (context, activities) {         return Text('TODO'); \/\/ TODO show activities       },     );   } }  class _EditProfileButton extends StatelessWidget {   const _EditProfileButton({Key? key}) : super(key: key);    @override   Widget build(BuildContext context) {     return Padding(       padding: const EdgeInsets.symmetric(horizontal: 8.0),       child: OutlinedButton(         onPressed: () {           \/\/ TODO handle onPressed         },         child: const Text('Edit Profile'),       ),     );   } }  class _ProfileHeader extends StatelessWidget {   const _ProfileHeader({     Key? key,     required this.numberOfPosts,   }) : super(key: key);    final int numberOfPosts;    static const _statitisticsPadding =       EdgeInsets.symmetric(horizontal: 12, vertical: 8.0);    @override   Widget build(BuildContext context) {     final feedState = context.watch&lt;AppState>();     final streamagramUser = feedState.streamagramUser;     if (streamagramUser == null) return const SizedBox.shrink();     return Column(       children: [         Row(           children: [             Padding(               padding: const EdgeInsets.all(8.0),               child: Avatar.big(                 streamagramUser: streamagramUser,               ),             ),             const Spacer(),             Row(               mainAxisSize: MainAxisSize.min,               children: [                 Padding(                   padding: _statitisticsPadding,                   child: Column(                     children: [                       Text(                         '$numberOfPosts',                         style: AppTextStyle.textStyleBold,                       ),                       const Text(                         'Posts',                         style: AppTextStyle.textStyleLight,                       ),                     ],                   ),                 ),                 Padding(                   padding: _statitisticsPadding,                   child: Column(                     children: [                       Text(                         '${FeedProvider.of(context).bloc.currentUser?.followersCount ?? 0}',                         style: AppTextStyle.textStyleBold,                       ),                       const Text(                         'Followers',                         style: AppTextStyle.textStyleLight,                       ),                     ],                   ),                 ),                 Padding(                   padding: _statitisticsPadding,                   child: Column(                     children: [                       Text(                         '${FeedProvider.of(context).bloc.currentUser?.followingCount ?? 0}',                         style: AppTextStyle.textStyleBold,                       ),                       const Text(                         'Following',                         style: AppTextStyle.textStyleLight,                       ),                     ],                   ),                 ),               ],             ),           ],         ),         Align(           alignment: Alignment.centerLeft,           child: Padding(             padding: const EdgeInsets.all(8.0),             child: Text(streamagramUser.fullName,                 style: AppTextStyle.textStyleBoldMedium),           ),         ),       ],     );   } }  class _NoPostsMessage extends StatelessWidget {   const _NoPostsMessage({     Key? key,   }) : super(key: key);    @override   Widget build(BuildContext context) {     return Column(       mainAxisAlignment: MainAxisAlignment.center,       children: [         const Text('This is too empty'),         const SizedBox(height: 12),         ElevatedButton(           onPressed: () {             \/\/ TODO handle onPressed           },           child: const Text('Add a post'),         )       ],     );   } }<\/code><\/pre>\n<p>\u0412 \u044d\u0442\u043e\u043c \u0444\u0430\u0439\u043b\u0435 \u043c\u044b \u043d\u0430\u043a\u043e\u043d\u0435\u0446 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0438\u0434\u0436\u0435\u0442\u044b \u0438\u0437 \u043f\u0430\u043a\u0435\u0442\u0430 <strong>stream_chat_flutter_core<\/strong>, \u0432 \u0446\u0435\u043b\u044f\u0445 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439 \u0432 \u043b\u0435\u043d\u0442\u0435. \u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u0437\u0443\u0447\u0438\u0442\u044c \u044d\u0442\u0443 \u0447\u0430\u0441\u0442\u044c \u043a\u043e\u0434\u0430 \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e \u0432 \u0443\u0434\u043e\u0431\u043d\u043e\u043c \u0434\u043b\u044f \u0432\u0430\u0441 \u0442\u0435\u043c\u043f\u0435. \u0421\u0435\u0439\u0447\u0430\u0441 \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043e\u0431\u0441\u0443\u0434\u0438\u043c \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0432\u0430\u0436\u043d\u044b\u0435 \u0435\u0433\u043e \u0447\u0430\u0441\u0442\u0438:<\/p>\n<ul>\n<li>\n<p><strong>FlatFeedCore<\/strong> \u0442\u0440\u0435\u0431\u0443\u0435\u0442, \u0447\u0442\u043e\u0431\u044b \u0432\u044b \u0443\u043a\u0430\u0437\u0430\u043b\u0438 <code>feedGroup<\/code>. \u0414\u043b\u044f \u043d\u0430\u0448\u0435\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u043f\u0440\u043e\u0444\u0438\u043b\u044f \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u0437\u0434\u0435\u0441\u044c \u00abuser\u00bb. \u041d\u0435 \u0437\u0430\u0431\u044b\u0432\u0430\u0439\u0442\u0435, \u0447\u0442\u043e \u044d\u0442\u043e \u0438\u043c\u0435\u043d\u043d\u043e \u0442\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u0447\u0442\u043e \u043c\u044b \u0443\u043a\u0430\u0437\u0430\u043b\u0438 \u0432 \u0441\u0430\u043c\u043e\u043c \u043d\u0430\u0447\u0430\u043b\u0435 \u0441\u0442\u0430\u0442\u044c\u0438;<\/p>\n<\/li>\n<li>\n<p><strong>FlatFeedCore<\/strong> \u0438\u043c\u0435\u0435\u0442 \u0447\u0435\u0442\u044b\u0440\u0435 \u0431\u0438\u043b\u0434\u0435\u0440\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0443\u0436\u043d\u044b \u043d\u0430\u043c \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439 (<code>loadingBuilder<\/code>, <code>errorBuilder<\/code>, <code>emptyBuilder<\/code>, \u0438 <code>feedBuilder<\/code>);<\/p>\n<\/li>\n<li>\n<p><code>emptyBuilder<\/code> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 <strong>CustomScrollView<\/strong>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442 \u0442\u0430\u043a\u0438\u0435 \u0432\u0438\u0434\u0436\u0435\u0442\u044b \u043a\u0430\u043a: <strong>_ProfileHeader, _EditProfileButton<\/strong>, \u0438 <strong>_NoPostsMessage;<\/strong><\/p>\n<\/li>\n<li>\n<p><code>feedBuilder<\/code> \u0432\u044b \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u0435 \u043f\u043e\u0437\u0436\u0435;<\/p>\n<\/li>\n<li>\n<p>\u0432\u0438\u0434\u0436\u0435\u0442 <strong>_ProfileHeader <\/strong>\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 <strong>Provider<\/strong> \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0441\u043b\u0435\u0434\u0438\u0442\u044c \u0437\u0430 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c <strong>AppState<\/strong>;<\/p>\n<\/li>\n<li>\n<p>\u0432 \u044d\u0442\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u043a\u043e\u0434\u0430 \u0432\u044b \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e TODO \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432, \u0442\u0440\u0435\u0431\u0443\u044e\u0449\u0438\u0445 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438, \u043d\u043e \u043a \u043d\u0438\u043c \u043c\u044b \u0432\u0435\u0440\u043d\u0435\u043c\u0441\u044f \u0447\u0443\u0442\u044c \u043f\u043e\u0437\u0436\u0435.<\/p>\n<\/li>\n<\/ul>\n<p>\u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u0432\u0438\u0434\u0436\u0435\u0442\u0443 <strong>FlatFeedCore <\/strong>\u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u043e\u0431 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0445 \u043f\u043e\u0441\u0442\u0430\u0445 (\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439) \u0438\u0437 \u0432\u0430\u0448\u0435\u0439 \u043b\u0435\u043d\u0442\u044b \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c\u0441\u044f \u043f\u0440\u043e\u0449\u0435, \u0438 \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c \u0438\u0445 \u043a\u0430\u043a \u043f\u043e\u0436\u0435\u043b\u0430\u0435\u0442\u0435.<strong> <\/strong>\u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0440\u044f\u0434 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u0440\u0438\u0441\u0432\u043e\u0438\u0442\u044c \u044d\u0442\u043e\u043c\u0443 \u0432\u0438\u0434\u0436\u0435\u0442\u0443 \u0432 \u0446\u0435\u043b\u044f\u0445 \u0443\u043b\u0443\u0447\u0448\u0435\u043d\u0438\u044f \u043f\u0430\u0433\u0438\u043d\u0430\u0446\u0438\u0438 \u0438 \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e \u0432 \u0432\u0430\u0448\u0435\u0439 \u043b\u0435\u043d\u0442\u0435. \u041e\u0434\u043d\u0430\u043a\u043e \u043f\u043e\u043a\u0430 \u0447\u0442\u043e, \u043c\u044b \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u0433\u043b\u0443\u0431\u043e\u043a\u043e \u0443\u0433\u043b\u0443\u0431\u043b\u044f\u0442\u044c\u0441\u044f \u0432 \u044d\u0442\u043e. \u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u0437\u0443\u0447\u0438\u0442\u044c \u044d\u0442\u043e\u0442 \u0432\u043e\u043f\u0440\u043e\u0441 \u043f\u043e\u0441\u043b\u0435 \u043f\u0440\u043e\u0447\u0442\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438.<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u0431\u0430\u0440\u0440\u0435\u043b\u044c-\u0444\u0430\u0439\u043b <code>components\/profile\/profile.dart<\/code> \u0438 \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0442\u0443\u0434\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<pre><code class=\"dart\">export 'profile_page.dart';<\/code><\/pre>\n<p>\u0417\u0430\u0442\u0435\u043c \u0432\u0435\u0440\u043d\u0438\u0442\u0435\u0441\u044c \u043e\u0431\u0440\u0430\u0442\u043d\u043e \u043a <code>components\/home\/home_screen.dart<\/code> \u0438 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e <code>_homePages<\/code>, \u0447\u0442\u043e\u0431\u044b \u043e\u043d\u0430 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u043b\u0430 <strong>ProfilePage<\/strong>. \u042d\u0442\u043e \u0434\u043e\u043b\u0436\u043d\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code class=\"dart\">... import '..\/profile\/profile.dart'; \/\/ ADD IMPORT ... \/\/\/ List of pages available from the home screen.   static const List&lt;Widget> _homePages = &lt;Widget>[     Center(child: Text('TimelinePage')),     Center(child: Text('SearchPage')),     ProfilePage(), \/\/ MODIFY THIS   ];<\/code><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u0432\u044b \u0441\u0435\u0439\u0447\u0430\u0441 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0438 \u043e\u0442\u043a\u0440\u043e\u0435\u0442\u0435 \u0432\u043a\u043b\u0430\u0434\u043a\u0443 \u043f\u0440\u043e\u0444\u0438\u043b\u044f, \u0442\u043e \u0435\u0435 \u0432\u0438\u0434 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u043f\u043e\u0445\u043e\u0436\u0438\u043c \u043d\u0430 \u044d\u0442\u043e:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/fd4\/1c6\/ca3\/fd41c6ca3250656b39af88c800cea0f5.png\" width=\"293\" height=\"633\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/fd4\/1c6\/ca3\/fd41c6ca3250656b39af88c800cea0f5.png\"\/><\/figure>\n<h2>\u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u044d\u043a\u0440\u0430\u043d \u00ab\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0444\u0438\u043b\u044c\u00bb<\/h2>\n<p>\u042d\u043a\u0440\u0430\u043d \u00ab\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0444\u0438\u043b\u044c\u00bb (Edit Profile) \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0435\u0433\u043e \u0438\u043c\u044f) \u0438 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u0433\u043b\u0430\u0432\u043d\u043e\u0435 \u0444\u043e\u0442\u043e \u043f\u0440\u043e\u0444\u0438\u043b\u044f. \u041a\u043e\u043d\u0435\u0447\u043d\u043e, \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0438 \u0440\u0430\u0441\u0448\u0438\u0440\u0438\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u044d\u0442\u043e\u0433\u043e \u044d\u043a\u0440\u0430\u043d\u0430, \u0434\u043e\u0431\u0430\u0432\u0438\u0432 \u0432 \u043d\u0435\u0433\u043e \u0440\u044f\u0434 \u0434\u0440\u0443\u0433\u0438\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0435\u0441\u043b\u0438 \u043f\u043e\u0436\u0435\u043b\u0430\u0435\u0442\u0435, \u043d\u043e \u043d\u0430 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0442\u043e\u0431\u0440\u0430\u0437\u0438\u0442\u044c \u0433\u043b\u0430\u0432\u043d\u043e\u0435 \u0444\u043e\u0442\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f, \u0435\u0433\u043e \u043e\u0431\u044b\u0447\u043d\u043e\u0435 \u0438\u043c\u044f \u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0435.<\/p>\n<h2>\u041e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c AppState<\/h2>\n<p>\u041f\u0435\u0440\u0435\u0434 \u0442\u0435\u043c \u043a\u0430\u043a \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043a \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044e UI, \u0432\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u043a\u043b\u0430\u0441\u0441 <strong>AppState<\/strong>.<\/p>\n<p>\u041e\u0442\u043a\u0440\u043e\u0439\u0442\u0435 <code>app\/state\/app_state.dart<\/code> \u0438 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u0435 \u0435\u0433\u043e \u043a\u0430\u043a \u0443\u043a\u0430\u0437\u0430\u043d\u043e \u043d\u0438\u0436\u0435:<\/p>\n<pre><code class=\"dart\">class AppState extends ChangeNotifier {  ...  var isUploadingProfilePicture = false;  ...  \/\/\/ Uploads a new profile picture from the given [filePath].   \/\/\/   \/\/\/ This will call [notifyListeners] and update the local [_streamagramUser] state.   Future&lt;void> updateProfilePhoto(String filePath) async {     \/\/ Upload the original image     isUploadingProfilePicture = true;     notifyListeners();      final imageUrl = await client.images.upload(AttachmentFile(path: filePath));     if (imageUrl == null) {       debugPrint('Could not upload the image. Not setting profile picture');       isUploadingProfilePicture = false;       notifyListeners();       return;     }     \/\/ Get resized images using the Stream Feed client.     final results = await Future.wait([       client.images.getResized(         imageUrl,         const Resize(500, 500),       ),       client.images.getResized(         imageUrl,         const Resize(50, 50),       )     ]);      \/\/ Update the current user data state.     _streamagramUser = _streamagramUser?.copyWith(       profilePhoto: imageUrl,       profilePhotoResized: results[0],       profilePhotoThumbnail: results[1],     );      isUploadingProfilePicture = false;      \/\/ Upload the new user data for the current user.     if (_streamagramUser != null) {       await client.currentUser!.update(_streamagramUser!.toMap());     }      notifyListeners();   }<\/code><\/pre>\n<p>\u041a\u043e\u0434 \u0432\u044b\u0448\u0435 \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f <code>isUploadingProfilePicture<\/code>, \u0434\u043b\u044f \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u0437\u0430\u0434\u0430\u043d\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <strong>false<\/strong>.<\/p>\n<p>\u041c\u0435\u0442\u043e\u0434 <code>updateProfilePhoto<\/code> \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<ol>\n<li>\n<p>\u0421\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u0442 \u043f\u0443\u0442\u044c \u043a \u0444\u0430\u0439\u043b\u0443 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f;<\/p>\n<\/li>\n<li>\n<p>\u041c\u0435\u043d\u044f\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 <code>isUploadingProfilePicture<\/code> \u043d\u0430<strong> true<\/strong>. \u0412\u044b \u0441\u043c\u043e\u0436\u0435\u0442\u0435 \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u044d\u0442\u0443 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u0432 \u0432\u0430\u0448\u0435\u043c UI;<\/p>\n<\/li>\n<li>\n<p>\u0417\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442 \u0444\u0430\u0439\u043b \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043d\u0430 Stream CDN, \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 <strong>StreamFeedClient <\/strong>\u0438<strong> AttachmentFile<\/strong>;<\/p>\n<\/li>\n<li>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043c\u0435\u0442\u043e\u0434 getResized, \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u043d\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u043a\u043e\u0433\u0434\u0430 \u0434\u043b\u044f \u0444\u043e\u0442\u043e \u043f\u0440\u043e\u0444\u0438\u043b\u044f \u0432\u044b\u0431\u0440\u0430\u043d \u0440\u0430\u0437\u043c\u0435\u0440 tiny \u0438\u043b\u0438 small;<\/p>\n<\/li>\n<li>\n<p>\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u043d\u043e\u0432\u044b\u0439 URL \u0432\u0430\u0448\u0435\u0433\u043e \u0444\u043e\u0442\u043e \u0432 <code>_streamagramUser<\/code>;<\/p>\n<\/li>\n<li>\n<p>\u0421\u043d\u043e\u0432\u0430 \u043c\u0435\u043d\u044f\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 <code>isUploadingProfilePicture<\/code> \u043d\u0430 <strong>false<\/strong>;<\/p>\n<\/li>\n<li>\n<p>\u041e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0432 \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432\u044b\u0437\u043e\u0432\u043e\u043c \u043c\u0435\u0442\u043e\u0434\u0430 <code>update<\/code> \u0434\u043b\u044f <code>currentUser<\/code>.<\/p>\n<\/li>\n<\/ol>\n<p>\u042d\u0442\u043e\u0442 \u043a\u043e\u0434 \u0442\u0430\u043a\u0436\u0435 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u043c\u0435\u0442\u043e\u0434 <code>notifyListeners<\/code> \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437 \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c UI.<\/p>\n<h2>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0432\u044b\u0431\u043e\u0440\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043a\u0430\u043a \u0432 Instagram*<\/h2>\n<p>\u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0432\u043d\u0435\u0434\u0440\u0438\u0442\u044c \u0432 \u043d\u0430\u0448 \u043a\u043b\u043e\u043d \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0443\u044e \u0432\u044b\u0431\u0438\u0440\u0430\u0442\u044c \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0438\u0437 \u0433\u0430\u043b\u0435\u0440\u0435\u0438 \u043d\u0430\u0448\u0435\u0433\u043e \u0441\u043c\u0430\u0440\u0442\u0444\u043e\u043d\u0430 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0434\u043b\u044f \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u0438\u043b\u0438 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0433\u043b\u0430\u0432\u043d\u043e\u0433\u043e \u0444\u043e\u0442\u043e \u043f\u0440\u043e\u0444\u0438\u043b\u044f), \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0430\u043a\u0435\u0442 <a href=\"https:\/\/pub.dev\/packages\/image_picker\" rel=\"noopener noreferrer nofollow\">image_picker<\/a>.<\/p>\n<p>\u041f\u043e <a href=\"https:\/\/pub.dev\/packages\/image_picker#installation\" rel=\"noopener noreferrer nofollow\">\u0441\u0441\u044b\u043b\u043a\u0435<\/a> \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043d\u0430\u0439\u0442\u0438 \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0430\u0446\u0438\u0438 \u043f\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0435. \u0412 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b (iOS \u0438\u043b\u0438 Android), \u0448\u0430\u0433\u0438 \u043c\u043e\u0433\u0443\u0442 \u0440\u0430\u0437\u043b\u0438\u0447\u0430\u0442\u044c\u0441\u044f.<\/p>\n<h2>\u042d\u043a\u0440\u0430\u043d \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0444\u0438\u043b\u044f (UI)<\/h2>\n<p>\u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u0444\u0430\u0439\u043b <code>components\/profile\/edit_profile_screen.dart<\/code> \u0438 \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<pre><code class=\"dart\">import 'package:flutter\/material.dart'; import 'package:image_picker\/image_picker.dart'; import 'package:provider\/provider.dart';  import '..\/..\/app\/app.dart'; import '..\/app_widgets\/app_widgets.dart';  \/\/\/ {@template edit_profile_page} \/\/\/ Screen to edit a user's profile info. \/\/\/ {@endtemplate} class EditProfileScreen extends StatelessWidget {   \/\/\/ {@macro edit_profile_page}   const EditProfileScreen({     Key? key,   }) : super(key: key);    \/\/\/ Custom route to this screen. Animates from the bottom up.   static Route get route => PageRouteBuilder(         pageBuilder: (context, animation, secondaryAnimation) =>             const EditProfileScreen(),         transitionsBuilder: (context, animation, secondaryAnimation, child) {           final tween = Tween(begin: const Offset(0.0, 1.0), end: Offset.zero)               .chain(CurveTween(curve: Curves.easeOutQuint));           final offsetAnimation = animation.drive(tween);           return SlideTransition(             position: offsetAnimation,             child: child,           );         },       );    @override   Widget build(BuildContext context) {     final streamagramUser = context         .select&lt;AppState, StreamagramUser?>((value) => value.streamagramUser);     if (streamagramUser == null) {       return const Scaffold(         body: Center(           child: Text('You should not see this.\\nUser data is empty.'),         ),       );     }     return Scaffold(       appBar: AppBar(         leading: TextButton(           onPressed: () {             Navigator.of(context).pop();           },           child: Text(             'Cancel',             style: (Theme.of(context).brightness == Brightness.dark)                 ? const TextStyle(color: AppColors.light)                 : const TextStyle(color: AppColors.dark),           ),         ),         leadingWidth: 80,         title: const Text(           ' Edit profile',           style: TextStyle(fontSize: 15, fontWeight: FontWeight.w600),         ),         actions: [           TextButton(             onPressed: () {               Navigator.of(context).pop();             },             child: const Text('Done'),           ),         ],       ),       body: ListView(         children: [           const _ChangeProfilePictureButton(),           const Divider(             color: Colors.grey,           ),           Padding(             padding: const EdgeInsets.all(8),             child: Row(               children: [                 const SizedBox(                   width: 100,                   child: Text(                     'Name',                     style: AppTextStyle.textStyleBoldMedium,                   ),                 ),                 Text(                   '${streamagramUser.fullName} ',                   style: AppTextStyle.textStyleBoldMedium,                 ),               ],             ),           ),           Padding(             padding: const EdgeInsets.all(8),             child: Row(               children: [                 const SizedBox(                   width: 100,                   child: Text(                     'Username',                     style: AppTextStyle.textStyleBoldMedium,                   ),                 ),                 Text(                   '${context.appState.user.id} ',                   style: AppTextStyle.textStyleBoldMedium,                 ),               ],             ),           ),           const Divider(color: Colors.grey),         ],       ),     );   } }  class _ChangeProfilePictureButton extends StatefulWidget {   const _ChangeProfilePictureButton({     Key? key,   }) : super(key: key);    @override   __ChangeProfilePictureButtonState createState() =>       __ChangeProfilePictureButtonState(); }  class __ChangeProfilePictureButtonState     extends State&lt;_ChangeProfilePictureButton> {   final _picker = ImagePicker();    Future&lt;void> _changePicture() async {     if (context.appState.isUploadingProfilePicture == true) {       return;     }      final pickedFile = await _picker.pickImage(       source: ImageSource.gallery,       maxWidth: 800,       maxHeight: 800,       imageQuality: 70,     );     if (pickedFile != null) {       await context.appState.updateProfilePhoto(pickedFile.path);     } else {       context.removeAndShowSnackbar('No picture selected');     }   }    @override   Widget build(BuildContext context) {     final streamagramUser = context         .select&lt;AppState, StreamagramUser>((value) => value.streamagramUser!);     final isUploadingProfilePicture = context         .select&lt;AppState, bool>((value) => value.isUploadingProfilePicture);     return Padding(       padding: const EdgeInsets.all(8.0),       child: Column(         mainAxisSize: MainAxisSize.min,         children: [           SizedBox(             height: 150,             child: Center(               child: isUploadingProfilePicture                   ? const CircularProgressIndicator()                   : GestureDetector(                       onTap: _changePicture,                       child: Avatar.huge(streamagramUser: streamagramUser),                     ),             ),           ),           GestureDetector(             onTap: _changePicture,             child: const Text('Change Profile Photo',                 style: AppTextStyle.textStyleAction),           ),         ],       ),     );   } }<\/code><\/pre>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043c\u0441\u044f \u043d\u0430 \u044d\u0442\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u043a\u043e\u0434\u0430:<\/p>\n<ul>\n<li>\n<p>\u0437\u0434\u0435\u0441\u044c \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 <strong>PageRouteBuilder, <\/strong>\u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 <strong>SlideTransition<\/strong>. \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u043f\u043b\u0430\u0432\u043d\u043e \u0441\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e \u043a\u0430\u043a \u0432\u044b \u0435\u0451 \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u0435\u0442\u0435, \u043f\u043e\u0434\u043e\u0431\u043d\u043e \u0442\u043e\u043c\u0443 \u043a\u0430\u043a \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u043d\u043e \u0432 Instagram;<\/p>\n<\/li>\n<li>\n<p>\u0442\u0430\u043a\u0436\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 UI-\u0432\u0438\u0434\u0436\u0435\u0442\u044b \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435;<\/p>\n<\/li>\n<li>\n<p>\u043c\u0435\u0442\u043e\u0434 <code>_changePicture<\/code> \u043c\u044b \u0443\u0436\u0435 \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u0440\u0430\u043d\u0435\u0435 \u0432 \u0441\u0442\u0430\u0442\u044c\u0435. \u042d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043f\u0430\u043a\u0435\u0442 <a href=\"https:\/\/pub.dev\/packages\/image_picker\" rel=\"noopener noreferrer nofollow\">image_picker<\/a> \u0434\u043b\u044f \u0432\u044b\u0431\u043e\u0440\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0438\u0437 \u0433\u0430\u043b\u0435\u0440\u0435\u0438 \u0438 \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0435\u0433\u043e \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438\u00a0 \u043c\u0435\u0442\u043e\u0434\u0430 updateProfilePhoto;<\/p>\n<\/li>\n<li>\n<p>\u0437\u0434\u0435\u0441\u044c \u043c\u044b \u0442\u0430\u043a\u0436\u0435, \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u0440\u0430\u0437\u043c\u0435\u0440 \u0438 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c\u043e\u0433\u043e \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <strong>maxWidth<\/strong>, <strong>maxHeight<\/strong>, \u0438 <strong>imageQuality<\/strong>.<\/p>\n<\/li>\n<\/ul>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0432\u0430\u0448 \u044d\u043a\u0440\u0430\u043d \u00ab\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0444\u0438\u043b\u044c\u00bb \u0434\u043e\u043b\u0436\u0435\u043d \u043f\u0440\u0438\u043d\u044f\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0432\u0438\u0434:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/06f\/d54\/052\/06fd54052e54e401e51fb21509e35b6a.png\" width=\"293\" height=\"633\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/06f\/d54\/052\/06fd54052e54e401e51fb21509e35b6a.png\"\/><\/figure>\n<p>\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u0435 \u0431\u0430\u0440\u0440\u0435\u043b\u044c-\u0444\u0430\u0439\u043b <code>components\/profile\/profile.dart<\/code>\u00a0 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code class=\"dart\">export 'edit_profile_screen.dart'; \/\/ ADD THIS export 'profile_page.dart';<\/code><\/pre>\n<p>\u0414\u043b\u044f \u0444\u0430\u0439\u043b\u0430 <code>components\/profile\/profile_page.dart<\/code>\u00a0 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u0435 TODO \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439 \u0432 \u0432\u0438\u0434\u0436\u0435\u0442\u0435 <code>_EditProfileButton<\/code><\/p>\n<pre><code class=\"dart\">...  import 'package:stream_agram\/components\/profile\/edit_profile_screen.dart';  ...  class _EditProfileButton extends StatelessWidget {   const _EditProfileButton({Key? key}) : super(key: key);    @override   Widget build(BuildContext context) {     return Padding(       padding: const EdgeInsets.symmetric(horizontal: 8.0),       child: OutlinedButton(         onPressed: () {           Navigator.of(context).push(EditProfileScreen.route); \/\/ ADD THIS         },         child: const Text('Edit Profile'),       ),     );   } }  ...<\/code><\/pre>\n<p>\u0423\u0440\u0430!!! ?<\/p>\n<p>\u0415\u0441\u043b\u0438 \u0432\u044b \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u043b\u0438 \u0432\u0441\u0435 \u0448\u0430\u0433\u0438 ,\u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0435 \u0432\u044b\u0448\u0435, \u0442\u0435\u043f\u0435\u0440\u044c \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u0432\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u043e\u0444\u0438\u043b\u044f \u0432\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0438\u043c\u0435\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043d\u0430 \u0430\u0432\u0430\u0442\u0430\u0440 \u0432\u043c\u0435\u0441\u0442\u043e \u0437\u0430\u0433\u043b\u0443\u0448\u043a\u0438 \u0432 \u0432\u0438\u0434\u0435 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u043e\u0432, \u043a\u0430\u043a \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043d\u0438\u0436\u0435:<\/p>\n<div class=\"tm-iframe_temp\" data-src=\"https:\/\/embedd.srv.habr.com\/iframe\/645659167942b7fb9d1ab525\" data-style=\"\" id=\"645659167942b7fb9d1ab525\" width=\"\"><\/div>\n<p>\u041d\u0430 \u0441\u0435\u0433\u043e\u0434\u043d\u044f \u0432\u0441\u0435. \u041f\u043e\u0441\u0442\u0430\u0440\u0430\u044e\u0441\u044c \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044e\u044e \u0442\u0440\u0435\u0442\u044c\u044e \u0447\u0430\u0441\u0442\u044c \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0430 \u0432\u044b\u043b\u043e\u0436\u0438\u0442\u044c \u0432 \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0435\u0435 \u0432\u0440\u0435\u043c\u044f.<\/p>\n<p>\u0422\u0440\u0435\u0442\u044c\u044e \u0447\u0430\u0441\u0442\u044c \u0441\u0442\u0430\u0442\u044c\u0438 \u0447\u0438\u0442\u0430\u0439\u0442\u0435 <a href=\"https:\/\/habr.com\/ru\/articles\/733748\/\" rel=\"noopener noreferrer nofollow\">\u0442\u0443\u0442<\/a>.<\/p>\n<p><em>Instagram* &#8212; \u0437\u0430\u043f\u0440\u0435\u0449\u0435\u043d\u043d\u0430\u044f \u0432 \u0420\u043e\u0441\u0441\u0438\u0438 \u0441\u043e\u0446\u0438\u0430\u043b\u044c\u043d\u0430\u044f \u0441\u0435\u0442\u044c.<\/em><\/p>\n<p><em>\u0422\u0430\u043a\u0436\u0435 \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u043f\u043e\u0434\u043f\u0438\u0441\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u043c\u043e\u0439 \u043a\u0430\u043d\u0430\u043b \u0438 \u043d\u0430 \u043a\u0430\u043d\u0430\u043b \u043c\u043e\u0435\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430:<br \/>\u0421\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043a\u0430\u043d\u0430\u043b \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0432 \u0442\u0435\u043b\u0435\u0433\u0440\u0430\u043c:\u00a0<\/em><a href=\"https:\/\/t.me\/dom24x7\" rel=\"noopener noreferrer nofollow\"><em>https:\/\/t.me\/dom24x7<\/em><\/a><em><br \/>\u0421\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043c\u043e\u0439 \u043a\u0430\u043d\u0430\u043b:\u00a0<\/em><a href=\"https:\/\/t.me\/evgaj\" rel=\"noopener noreferrer nofollow\"><em>https:\/\/t.me\/evgaj<\/em><\/a><\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/730104\/\"> https:\/\/habr.com\/ru\/articles\/730104\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\"><\/figure>\n<p>\u041f\u0440\u0438\u0432\u0435\u0442! \u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u044e \u0432\u044b\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u0432\u043e\u0434 \u0441\u0442\u0430\u0442\u044c\u0438, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b \u043a\u0430\u043a \u043e\u0441\u043d\u043e\u0432\u0443 \u0434\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0441\u043e\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430 \u0432 \u043d\u0430\u0448\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435 <a href=\"https:\/\/dom24x7.ru\" rel=\"noopener noreferrer nofollow\">Dom24x7<\/a>, \u0433\u0434\u0435 \u043b\u044e\u0434\u0438 \u043c\u043e\u0433\u0443\u0442 \u043e\u0431\u0449\u0430\u0442\u044c\u0441\u044f \u0434\u0440\u0443\u0433 \u0441 \u0434\u0440\u0443\u0433\u043e\u043c, \u0440\u0435\u0448\u0430\u0442\u044c \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u044e\u0449\u0438\u0435 \u0431\u044b\u0442\u043e\u0432\u044b\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0441 \u0423\u041a\/\u0422\u0421\u0416. \u041f\u0435\u0440\u0432\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u0441\u0442\u0430\u0442\u044c\u0438 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c <a href=\"https:\/\/habr.com\/ru\/articles\/727794\/\" rel=\"noopener noreferrer nofollow\">\u0442\u0443\u0442<\/a>.<\/p>\n<h2>\u041f\u0438\u0448\u0435\u043c \u043a\u043e\u0434 \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0433\u043e \u0438\u043d\u0441\u0442\u0430\u0433\u0440\u0430\u043c \u043a\u043b\u043e\u043d\u0430<\/h2>\n<p>\u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u043c\u044b \u0434\u043e\u0431\u0440\u0430\u043b\u0438\u0441\u044c \u0434\u043e \u0441\u0430\u043c\u043e\u0439 \u0438\u043d\u0442\u0440\u0438\u0433\u0443\u044e\u0449\u0435\u0439 \u0447\u0430\u0441\u0442\u0438 \u0441\u0442\u0430\u0442\u044c\u0438.<\/p>\n<p>\u041f\u0435\u0440\u0435\u0434 \u0442\u0435\u043c \u043a\u0430\u043a \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0431\u044b\u0441\u0442\u0440\u043e \u043e\u0431\u0441\u0443\u0434\u0438\u043c \u043f\u043e\u0434\u0445\u043e\u0434, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043c\u044b \u043f\u043e\u0434\u043e\u0439\u0434\u0435\u043c \u043a \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044e \u043d\u0430\u0448\u0435\u0433\u043e \u043a\u043b\u043e\u043d\u0430.<\/p>\n<p>\u041d\u0430\u0448 Stream-agram \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u0442\u044c \u0438\u0437 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 UI, \u043e\u0442 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u043e\u0442\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u043e\u0437\u0436\u0435 \u0432 \u0441\u0442\u0430\u0442\u044c\u0435. \u042d\u0442\u043e \u0442\u0430\u043a\u0438\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u043a\u0430\u043a:<\/p>\n<ul>\n<li>\n<p><strong>\u042d\u043a\u0440\u0430\u043d \u0432\u0445\u043e\u0434\u0430<\/strong> (mock-\u043e\u0431\u044a\u0435\u043a\u0442): \u0442\u0430\u043c, \u0433\u0434\u0435 \u043c\u044b \u0432\u0445\u043e\u0434\u0438\u043c \u0432 \u0441\u0432\u043e\u0439 \u043f\u0440\u043e\u0444\u0438\u043b\u044c;<\/p>\n<\/li>\n<li>\n<p><strong>\u0413\u043b\u0430\u0432\u043d\u044b\u0439 \u044d\u043a\u0440\u0430\u043d<\/strong>: \u043e\u0442\u043a\u0443\u0434\u0430 \u043c\u044b \u0441\u043c\u043e\u0436\u0435\u043c \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u0442\u044c \u0432 \u0434\u0440\u0443\u0433\u0438\u0435 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f (\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0442\u0430\u043c \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u043a\u0440\u044b\u0442\u0430 \u0445\u0440\u043e\u043d\u043e\u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u043b\u0435\u043d\u0442\u0430);<\/p>\n<\/li>\n<li>\n<p><strong>\u0421\u0430\u043c\u0443 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0441 \u0445\u0440\u043e\u043d\u043e\u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u043b\u0435\u043d\u0442\u043e\u0439<\/strong> (\u0434\u043e\u043c\u0430\u0448\u043d\u044f\u044f \u0432\u043a\u043b\u0430\u0434\u043a\u0430): \u043c\u0435\u0441\u0442\u043e, \u0433\u0434\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441\u043c\u043e\u0442\u0440\u0438\u0442 \u043f\u043e\u0441\u0442\u044b \u0442\u0435\u0445 \u043d\u0430 \u043a\u043e\u0433\u043e \u043f\u043e\u0434\u043f\u0438\u0441\u0430\u043d;<\/p>\n<\/li>\n<li>\n<p><strong>\u0412\u043a\u043b\u0430\u0434\u043a\u0443 \u043b\u0438\u0447\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0444\u0438\u043b\u044f<\/strong>: \u0442\u0430\u043c, \u0433\u0434\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0430 \u0432\u0441\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e \u043f\u0440\u043e\u0444\u0438\u043b\u0435, \u0432\u043a\u043b\u044e\u0447\u0430\u044f \u043e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u0441\u0442\u044b;<\/p>\n<\/li>\n<li>\n<p><strong>\u0412\u043a\u043b\u0430\u0434\u043a\u0443 \u043f\u043e\u0438\u0441\u043a\u0430<\/strong>: \u043e\u0442\u043a\u0443\u0434\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0434\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u0438 \u043e\u0442\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u043e\u0442 \u0434\u0440\u0443\u0433\u0438\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439;<\/p>\n<\/li>\n<li>\n<p><strong>\u042d\u043a\u0440\u0430\u043d \u00ab\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0444\u0438\u043b\u044c\u00bb<\/strong>: \u0442\u0430\u043c, \u0433\u0434\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043c\u043e\u0436\u0435\u0442 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u043e\u0441\u043d\u043e\u0432\u043d\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043f\u0440\u043e\u0444\u0438\u043b\u044f \u0438 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0435 \u0444\u043e\u0442\u043e;<\/p>\n<\/li>\n<li>\n<p><strong>\u042d\u043a\u0440\u0430\u043d \u00ab\u041d\u043e\u0432\u0430\u044f \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u044f\u00bb<\/strong>: \u0442\u0430\u043c, \u0433\u0434\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0435 \u043f\u043e\u0441\u0442\u044b (\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f) \u0432 \u0441\u0432\u043e\u0439 \u043f\u0440\u043e\u0444\u0438\u043b\u044c.<\/p>\n<\/li>\n<\/ul>\n<p>\u041c\u044b \u043d\u0430\u0447\u043d\u0435\u043c \u0441 \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u043d\u044b\u0445 \u0432\u0435\u0440\u0441\u0438\u0439 \u044d\u0442\u0438\u0445 \u0432\u043a\u043b\u0430\u0434\u043e\u043a \u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446 \u0438 \u0431\u0443\u0434\u0435\u043c \u0432\u043d\u043e\u0441\u0438\u0442\u044c \u0432 \u043d\u0438\u0445 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0448\u0430\u0433 \u0437\u0430 \u0448\u0430\u0433\u043e\u043c, \u043f\u043e \u043c\u0435\u0440\u0435 \u0442\u043e\u0433\u043e \u043a\u0430\u043a \u0431\u0443\u0434\u0435\u043c \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0432 \u043d\u0430\u0448\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439. \u041a\u043e\u043d\u0435\u0447\u043d\u044b\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c \u0441\u0442\u0430\u043d\u0435\u0442 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0438\u0434\u0435\u043d\u0442\u0438\u0447\u043d\u044b\u0439 \u043a\u043b\u043e\u043d Instagram*.<\/p>\n<h2>\u0424\u0430\u0439\u043b Flutter \u0438 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043f\u0430\u043f\u043e\u043a<\/h2>\n<p>\u041a\u0430\u0436\u0434\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u043c \u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0441\u0432\u043e\u0435\u0439 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u043f\u0430\u043f\u043e\u043a. \u0422\u0443 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435, \u043d\u0438 \u0432 \u043a\u043e\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0435\u043b\u044c\u0437\u044f \u0441\u0447\u0438\u0442\u0430\u0442\u044c \u043b\u0443\u0447\u0448\u0435 \u043a\u0430\u043a\u043e\u0439-\u043b\u0438\u0431\u043e \u0434\u0440\u0443\u0433\u043e\u0439. \u042d\u0442\u043e \u043b\u0438\u0448\u044c \u043e\u0434\u0438\u043d \u0438\u0437 \u0443\u0434\u043e\u0431\u043d\u044b\u0445 \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u0432 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0434 \u0434\u043b\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<p>\u042d\u0442\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u0443\u0435\u0442 \u0432\u0435\u0441\u044c \u043a\u043e\u0434 \u043f\u043e\u0434 \u0434\u0432\u0435 \u043f\u0430\u043f\u043a\u0438 \u0432\u0435\u0440\u0445\u043d\u0435\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f: <strong>app<\/strong> \u0438 <strong>components<\/strong>.<\/p>\n<p>\u0412 <strong>components<\/strong> \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432\u0441\u0435, \u0447\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043e \u0432 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u043c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0435 &#8212; \u0435\u0433\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b. \u0414\u0440\u0443\u0433\u0438\u043c\u0438 \u0441\u043b\u043e\u0432\u0430\u043c\u0438 \u044d\u0442\u043e \u0431\u0443\u0434\u0443\u0442 \u043a\u0443\u0441\u043e\u0447\u043a\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u043c\u043e\u0433\u0443\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u043e\u0442 \u0434\u0440\u0443\u0433\u0438\u0445 \u0435\u0433\u043e \u0447\u0430\u0441\u0442\u0435\u0439; \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 &#8212; \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b\/\u0432\u043a\u043b\u0430\u0434\u043a\u0438, \u043a\u043d\u043e\u043f\u043a\u0438, \u0438 \u0432\u0438\u0434\u0436\u0435\u0442\u044b. \u041a\u0430\u0442\u0430\u043b\u043e\u0433 <strong>component<\/strong> \u0431\u0443\u0434\u0435\u0442 \u0442\u0430\u043a\u0436\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u043f\u0430\u043f\u043a\u0443 \u0441 \u0438\u043c\u0435\u043d\u0435\u043c<strong> app_widgets<\/strong>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0432\u0441\u0435 \u043e\u0431\u0449\u0438\u0435 \u0432\u0438\u0434\u0436\u0435\u0442\u044b, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0435 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438.<\/p>\n<p>\u041a\u0430\u0442\u0430\u043b\u043e\u0433<strong> app<\/strong> \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043a\u043b\u0430\u0441\u0441\u044b, \u043e\u0442\u043d\u043e\u0441\u044f\u0449\u0438\u0435\u0441\u044f \u043a\u043e \u0432\u0441\u0435\u043c\u0443 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044e, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043a\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, app state \u0438 navigation.<\/p>\n<p>\u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0430\u043a\u043a\u0443\u0440\u0430\u0442\u043d\u043e \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c\u044b\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b, \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0444\u0430\u0439\u043b\u044b Barrel (\u0434\u0430\u043b\u0435\u0435 \u043f\u0440\u043e\u0441\u0442\u043e &#8212; \u0431\u0430\u0440\u0440\u0435\u043b\u044c-\u0444\u0430\u0439\u043b\u044b).<\/p>\n<blockquote>\n<p>\u0411\u0430\u0440\u0440\u0435\u043b\u044c-\u0444\u0430\u0439\u043b\u044b \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u0441\u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c\u044b\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u0438\u0437 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043f\u0430\u043f\u043e\u043a \u0432 \u043e\u0434\u0438\u043d \u0443\u0434\u043e\u0431\u043d\u044b\u0439 \u0444\u0430\u0439\u043b.<\/p>\n<\/blockquote>\n<p>\u041a \u043a\u043e\u043d\u0446\u0443 \u0441\u0442\u0430\u0442\u044c\u0438 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0432\u0430\u0448\u0438\u0445 \u043f\u0430\u043f\u043e\u043a \u0438 \u0444\u0430\u0439\u043b\u043e\u0432 \u0434\u043e\u043b\u0436\u043d\u0430 \u0438\u043c\u0435\u0442\u044c \u043f\u043e\u0445\u043e\u0436\u0438\u0439 \u0432\u0438\u0434. \u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043b\u0438\u0431\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0432\u0441\u0451 \u044d\u0442\u043e \u0441\u0435\u0439\u0447\u0430\u0441 \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e, \u043b\u0438\u0431\u043e \u043f\u043e\u0437\u0436\u0435 \u043f\u043e \u043c\u0435\u0440\u0435 \u043f\u0440\u043e\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u044f \u0441\u0442\u0430\u0442\u044c\u0438.<\/p>\n<pre><code>\u251c\u2500\u2500 lib |   \u251c\u2500\u2500 app \u2502   \u2502   \u251c\u2500\u2500 navigation \u2502   \u2502   \u2502   \u2514\u2500\u2500 custom_rect_tween.dart |   |   |   \u2514\u2500\u2500 hero_dialog_route.dart |   |   |   \u2514\u2500\u2500 navigation.dart * |   |   \u251c\u2500\u2500 state |   |   |   \u251c\u2500\u2500 models |   |   |   |   \u2514\u2500\u2500 models.dart * |   |   |   |   \u2514\u2500\u2500 user.dart |   |   |   \u2514\u2500\u2500 app_state.dart |   |   |   \u2514\u2500\u2500 demo_users.dart |   |   |   \u2514\u2500\u2500 state.dart * |   |   \u2514\u2500\u2500 app.dart * |   |   \u2514\u2500\u2500 stream_agram.dart |   |   \u2514\u2500\u2500 theme.dart |   |   \u2514\u2500\u2500 utils.dart |   \u251c\u2500\u2500 components \u2502   \u2502   \u251c\u2500\u2500 app_widgets \u2502   \u2502   \u2502   \u2514\u2500\u2500 app_widgets.dart * |   |   |   \u2514\u2500\u2500 avatars.dart |   |   |   \u2514\u2500\u2500 comment_box.dart |   |   |   \u2514\u2500\u2500 favorite_icon.dart |   |   |   \u2514\u2500\u2500 tap_fade_icon.dart |   |   \u251c\u2500\u2500 comments |   |   |   \u251c\u2500\u2500 state |   |   |   |   \u2514\u2500\u2500 comment_state.dart * |   |   |   |   \u2514\u2500\u2500 state.dart |   |   |   \u2514\u2500\u2500 comment_screen.dart |   |   |   \u2514\u2500\u2500 comments.dart * \u2502   \u2502   \u251c\u2500\u2500 home \u2502   \u2502   \u2502   \u2514\u2500\u2500 home_screen.dart |   |   |   \u2514\u2500\u2500 home.dart * |   |   \u251c\u2500\u2500 login |   |   |   \u2514\u2500\u2500 login_screen.dart |   |   |   \u2514\u2500\u2500 login.dart * \u2502   \u2502   \u251c\u2500\u2500 new_post \u2502   \u2502   \u2502   \u2514\u2500\u2500 new_post_screen.dart |   |   |   \u2514\u2500\u2500 new_post.dart * |   |   \u251c\u2500\u2500 profile |   |   |   \u2514\u2500\u2500 edit_profile_screen.dart |   |   |   \u2514\u2500\u2500 profile_page.dart |   |   |   \u2514\u2500\u2500 profile.dart * \u2502   \u2502   \u251c\u2500\u2500 search \u2502   \u2502   \u2502   \u2514\u2500\u2500 search_page.dart |   |   |   \u2514\u2500\u2500 search.dart * |   |   \u2514\u2500\u2500 timeline |   |   |   \u251c\u2500\u2500 widgets |   |   |   |   \u2514\u2500\u2500 post_card.dart |   |   |   |   \u2514\u2500\u2500 widgets.dart * |   |       \u2514\u2500\u2500 timeline_page.dart |   |       \u2514\u2500\u2500 timeline.dart * \u2502   \u2514\u2500\u2500 main.dart \u251c\u2500\u2500 pubspec.lock \u251c\u2500\u2500 pubspec.yaml<\/code><\/pre>\n<blockquote>\n<p>\u26a0\ufe0f \u0417\u0430\u043c\u0435\u0442\u044c\u0442\u0435, \u0447\u0442\u043e \u0431\u0430\u0440\u0440\u0435\u043b\u044c-\u0444\u0430\u0439\u043b\u044b \u043f\u043e\u043c\u0435\u0447\u0435\u043d\u044b \u0437\u0432\u0435\u0437\u0434\u043e\u0447\u043a\u043e\u0439 \u00ab*\u00bb<\/p>\n<\/blockquote>\n<h2>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0433\u043e Instagram<\/h2>\n<p>\u041a\u0430\u043a \u0443\u0436\u0435 \u0431\u044b\u043b\u043e \u0443\u043f\u043e\u043c\u044f\u043d\u0443\u0442\u043e \u0432\u044b\u0448\u0435, \u0432 \u0446\u0435\u043b\u044f\u0445 \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u0438, \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u0437\u0430\u0445\u0430\u0440\u0434\u043a\u043e\u0434\u0438\u043c \u043d\u0430\u0448\u0438\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439, \u0442\u043e \u0435\u0441\u0442\u044c \u0437\u0430\u043f\u043e\u043b\u043d\u0438\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u043d\u0438\u0445 \u0432\u0440\u0443\u0447\u043d\u0443\u044e.<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u0444\u0430\u0439\u043b <code>app\/state\/demo_users.dart<\/code> \u0438 \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0432 \u043d\u0435\u0433\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<pre><code class=\"dart\">import 'package:stream_feed_flutter_core\/stream_feed_flutter_core.dart';  \/\/\/ Demo application users. enum DemoAppUser {   sahil,   sacha,   reuben,   gordon, }  \/\/\/ Convenient class Extension on [DemoAppUser] enum extension DemoAppUserX on DemoAppUser {   \/\/\/ Convenient method Extension to generate an [id] from [DemoAppUser] enum   String? get id => {         DemoAppUser.sahil: 'sahil-kumar',         DemoAppUser.sacha: 'sacha-arbonel',         DemoAppUser.reuben: 'reuben-turner',         DemoAppUser.gordon: 'gordon-hayes',       }[this];    \/\/\/ Convenient method Extension to generate a [name] from [DemoAppUser] enum   String? get name => {         DemoAppUser.sahil: 'Sahil Kumar',         DemoAppUser.sacha: 'Sacha Arbonel',         DemoAppUser.reuben: 'Reuben Turner',         DemoAppUser.gordon: 'Gordon Hayes',       }[this];    \/\/\/ Convenient method Extension to generate [data] from [DemoAppUser] enum   Map&lt;String, Object>? get data => {         DemoAppUser.sahil: {           'first_name': 'Sahil',           'last_name': 'Kumar',           'full_name': 'Sahil Kumar',         },         DemoAppUser.sacha: {           'first_name': 'Sacha',           'last_name': 'Arbonel',           'full_name': 'Sacha Arbonel',         },         DemoAppUser.reuben: {           'first_name': 'Reuben',           'last_name': 'Turner',           'full_name': 'Reuben Turner',         },         DemoAppUser.gordon: {           'first_name': 'Gordon',           'last_name': 'Hayes',           'full_name': 'Gordon Hayes',         },       }[this];    \/\/\/ Convenient method Extension to generate a [token] from [DemoAppUser] enum   Token? get token => &lt;DemoAppUser, Token>{         DemoAppUser.sahil: const Token(''), \/\/ TODO add token         DemoAppUser.sacha: const Token(''), \/\/ TODO add token         DemoAppUser.reuben: const Token(''), \/\/ TODO add token         DemoAppUser.gordon: const Token(''), \/\/ TODO add token       }[this]; }<\/code><\/pre>\n<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0444\u0430\u0439\u043b\u0435 \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e <strong>TODO<\/strong> \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c <strong>String<\/strong> \u0442\u043e\u043a\u0435\u043d\u044b, \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0435 \u0440\u0430\u043d\u0435\u0435. \u041e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0435 \u0442\u043e\u043a\u0435\u043d\u044b \u0434\u043b\u044f \u043d\u0443\u0436\u043d\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u0432\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0435 \u0434\u0440\u0443\u0433\u0438\u0435 \u0438\u043c\u0435\u043d\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439, \u0442\u043e \u0432\u0430\u043c \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0441\u0442\u0440\u043e\u043a\u0438 \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0444\u0430\u0439\u043b\u0435.<\/p>\n<p>\u041a\u043e\u0434 \u0432\u044b\u0448\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0432 \u0441\u0435\u0431\u0435 enum \u043a\u043b\u0430\u0441\u0441 <strong>DemoAppUser<\/strong> c \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435\u043c <strong>DemoAppUserX<\/strong>. \u0421\u0434\u0435\u043b\u0430\u043d\u043e \u044d\u0442\u043e \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043c\u044b \u043c\u043e\u0433\u043b\u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0434\u0440\u0443\u0433\u0438\u043c \u0434\u0430\u043d\u043d\u044b\u043c (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u043a \u0442\u043e\u043a\u0435\u043d\u0430\u043c \u0438\u043b\u0438 \u043a \u0438\u043c\u0435\u043d\u0430\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439). \u042d\u0442\u043e\u0442 \u0444\u0430\u0439\u043b \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043a\u0440\u0438\u0442\u0438\u0447\u043d\u043e \u0432\u0430\u0436\u043d\u044b\u043c, \u0438 \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0432\u0430\u0448\u0438\u0445 \u0444\u0435\u0439\u043a\u043e\u0432\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u043b\u044e\u0431\u044b\u043c \u0434\u0440\u0443\u0433\u0438\u043c \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u043c.<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u0431\u0430\u0440\u0440\u0435\u043b\u044c-\u0444\u0430\u0439\u043b \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439 <code>app\/state\/state.dart<\/code> \u0438 \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0439\u0442\u0435 \u0435\u0433\u043e:<\/p>\n<pre><code class=\"dart\">export 'demo_users.dart';<\/code><\/pre>\n<p>\u0414\u0430\u043b\u0435\u0435, \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0431\u0430\u0440\u0440\u0435\u043b\u044c-\u0444\u0430\u0439\u043b \u0443\u0440\u043e\u0432\u043d\u044f \u0432\u044b\u0448\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u043c\u0435\u0435\u0442 \u0432\u0438\u0434 <code>app\/app.dart<\/code> \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0439\u0442\u0435 \u0435\u0433\u043e:<\/p>\n<pre><code class=\"dart\">export 'state\/state.dart';<\/code><\/pre>\n<h2>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0442\u0435\u043c\u044b \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0433\u043e \u0438\u043d\u0441\u0442\u0440\u0430\u0433\u0440\u0430\u043c \u043a\u043b\u043e\u043d\u0430<\/h2>\n<p>\u041c\u044b \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u043c\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u0435 \u0436\u0435 \u0446\u0432\u0435\u0442\u0430 \u0438 \u0448\u0440\u0438\u0444\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u044b \u0432\u0438\u0434\u0438\u0442\u0435 \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0435\u0433\u043e \u0418\u043d\u0441\u0442\u0430\u0433\u0440\u0430\u043c\u0430, \u0434\u043b\u044f \u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u043d\u0430\u0448\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0434\u0430\u0432\u0430\u043b\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c \u0442\u0435 \u0436\u0435 \u044d\u043c\u043e\u0446\u0438\u0438, \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438. \u041c\u044b \u0442\u0430\u043a\u0436\u0435 \u0445\u043e\u0442\u0438\u043c \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u0432 \u043d\u0430\u0448\u0435\u043c \u043a\u043b\u043e\u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0434\u043d\u0435\u0432\u043d\u043e\u0439 \u2600\ufe0f \u0438 \u043d\u043e\u0447\u043d\u043e\u0439 ? \u0440\u0435\u0436\u0438\u043c\u044b. \u041e\u0441\u043d\u043e\u0432\u043d\u044b\u0439 \u0440\u0435\u0436\u0438\u043c \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u0432\u0438\u0441\u0435\u0442\u044c \u043e\u0442 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b. \u0412 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u0430 \u0441\u043c\u0435\u043d\u0430 \u0440\u0435\u0436\u0438\u043c\u043e\u0432 \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0434\u043d\u0435\u0432\u043d\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u044d\u0442\u043e \u0441\u043b\u0435\u0433\u043a\u0430 \u0432\u044b\u0445\u043e\u0434\u0438\u0442 \u0437\u0430 \u0440\u0430\u043c\u043a\u0438 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0446\u0435\u043b\u0438 \u043d\u0430\u0448\u0435\u0439 \u0441\u0442\u0430\u0442\u044c\u0438.<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 <code>app\/theme.dart<\/code> \u0438 \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<pre><code class=\"dart\">import 'package:flutter\/material.dart';  \/\/\/ Global reference to application colors. abstract class AppColors {   \/\/\/ Dark color.   static const dark = Colors.black;    static const light = Color(0xFFFAFAFA);    \/\/\/ Grey background accent.   static const grey = Color(0xFF262626);    \/\/\/ Primary text color   static const primaryText = Colors.white;    \/\/\/ Secondary color.   static const secondary = Color(0xFF0095F6);    \/\/\/ Color to use for favorite icons (indicating a like).   static const like = Colors.red;    \/\/\/ Grey faded color.   static const faded = Colors.grey;    \/\/\/ Light grey color   static const ligthGrey = Color(0xFFEEEEEE);    \/\/\/ Top gradient color used in various UI components.   static const topGradient = Color(0xFFE60064);    \/\/\/ Bottom gradient color used in various UI components.   static const bottomGradient = Color(0xFFFFB344); }  \/\/\/ Global reference to application [TextStyle]s. abstract class AppTextStyle {   \/\/\/ A medium bold text style.   static const textStyleBoldMedium = TextStyle(     fontWeight: FontWeight.w600,   );    \/\/\/ A bold text style.   static const textStyleBold = TextStyle(     fontWeight: FontWeight.bold,   );    static const textStyleSmallBold = TextStyle(     fontWeight: FontWeight.bold,     fontSize: 13,   );    \/\/\/ A faded text style. Uses [AppColors.faded].   static const textStyleFaded =       TextStyle(color: AppColors.faded, fontWeight: FontWeight.w400);    \/\/\/ A faded text style. Uses [AppColors.faded].   static const textStyleFadedSmall = TextStyle(       color: AppColors.faded, fontWeight: FontWeight.w400, fontSize: 11);    \/\/\/ A faded text style. Uses [AppColors.faded].   static const textStyleFadedSmallBold = TextStyle(       color: AppColors.faded, fontWeight: FontWeight.w500, fontSize: 11);    \/\/\/ Light text style.   static const textStyleLight = TextStyle(fontWeight:<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-391971","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/391971","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=391971"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/391971\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=391971"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=391971"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=391971"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}