From 7b1b60270cf683b22a24524e372f783a6a28a5b9 Mon Sep 17 00:00:00 2001 From: Vitaliy Zarubin Date: Thu, 22 Jun 2023 18:36:28 +0300 Subject: [PATCH] [flutter_example_packages] Add app, start home page --- example/.gitignore | 47 ++ example/.metadata | 30 + example/README.md | 16 + example/analysis_options.yaml | 1 + example/assets/images/logo-head.png | Bin 0 -> 18385 bytes example/aurora/.gitignore | 1 + example/aurora/CMakeLists.txt | 47 ++ ....auroraos.flutter_example_packages.desktop | 12 + example/aurora/icons/108x108.png | Bin 0 -> 3940 bytes example/aurora/icons/128x128.png | Bin 0 -> 4189 bytes example/aurora/icons/172x172.png | Bin 0 -> 4191 bytes example/aurora/icons/86x86.png | Bin 0 -> 3359 bytes example/aurora/main.cpp | 9 + .../ru.auroraos.flutter_example_packages.spec | 31 + example/data/raw/flutter.svg | 1 + example/data/raw/icon.png | Bin 0 -> 11470 bytes example/data/raw/links | 2 + example/data/raw/logo-head.svg | 1 + example/data/raw/package.svg | 1 + example/l10n.yaml | 3 + example/lib/app.dart | 33 + example/lib/base/build/build.config.dart | 3 + example/lib/base/build/build.debug.dart | 6 + example/lib/base/build/build.release.dart | 6 + example/lib/base/di/app_di.dart | 38 +- example/lib/extensions/keys_ext.dart | 18 + example/lib/l10n/app_en.arb | 3 + example/lib/l10n/app_ru.arb | 3 + example/lib/main.dart | 9 + example/lib/main.release.dart | 9 + example/lib/model.dart | 8 + example/lib/pages/battery_plus/model.dart | 8 + example/lib/pages/battery_plus/page.dart | 31 + example/lib/pages/device_info_plus/model.dart | 8 + example/lib/pages/device_info_plus/page.dart | 31 + .../flutter_local_notifications/model.dart | 8 + .../flutter_local_notifications/page.dart | 31 + .../pages/flutter_secure_storage/model.dart | 8 + .../pages/flutter_secure_storage/page.dart | 31 + example/lib/pages/home/model.dart | 8 + example/lib/pages/home/page.dart | 237 +++++++ .../lib/pages/package_info_plus/model.dart | 8 + example/lib/pages/package_info_plus/page.dart | 31 + example/lib/pages/path_provider/model.dart | 8 + example/lib/pages/path_provider/page.dart | 31 + .../lib/pages/shared_preferences/model.dart | 8 + .../lib/pages/shared_preferences/page.dart | 31 + example/lib/pages/wakelock/model.dart | 8 + example/lib/pages/wakelock/page.dart | 31 + example/lib/pages/xdga_directories/model.dart | 8 + example/lib/pages/xdga_directories/page.dart | 31 + example/lib/theme/colors.dart | 7 + example/lib/theme/radius.dart | 7 + example/lib/theme/theme.dart | 54 ++ example/lib/widgets/layouts/page_layout.dart | 38 ++ example/pubspec.lock | 614 ++++++++++++++++++ example/pubspec.yaml | 45 ++ example/run.sh | 94 +++ example/web/favicon.png | Bin 0 -> 917 bytes example/web/icons/Icon-192.png | Bin 0 -> 5292 bytes example/web/icons/Icon-512.png | Bin 0 -> 8252 bytes example/web/icons/Icon-maskable-192.png | Bin 0 -> 5594 bytes example/web/icons/Icon-maskable-512.png | Bin 0 -> 20998 bytes example/web/index.html | 58 ++ example/web/manifest.json | 35 + 65 files changed, 1872 insertions(+), 14 deletions(-) create mode 100644 example/.gitignore create mode 100644 example/.metadata create mode 100644 example/README.md create mode 100644 example/analysis_options.yaml create mode 100644 example/assets/images/logo-head.png create mode 100644 example/aurora/.gitignore create mode 100644 example/aurora/CMakeLists.txt create mode 100644 example/aurora/desktop/ru.auroraos.flutter_example_packages.desktop create mode 100644 example/aurora/icons/108x108.png create mode 100644 example/aurora/icons/128x128.png create mode 100644 example/aurora/icons/172x172.png create mode 100644 example/aurora/icons/86x86.png create mode 100644 example/aurora/main.cpp create mode 100644 example/aurora/rpm/ru.auroraos.flutter_example_packages.spec create mode 100644 example/data/raw/flutter.svg create mode 100644 example/data/raw/icon.png create mode 100644 example/data/raw/links create mode 100644 example/data/raw/logo-head.svg create mode 100644 example/data/raw/package.svg create mode 100644 example/l10n.yaml create mode 100644 example/lib/app.dart create mode 100644 example/lib/base/build/build.config.dart create mode 100644 example/lib/base/build/build.debug.dart create mode 100644 example/lib/base/build/build.release.dart create mode 100644 example/lib/extensions/keys_ext.dart create mode 100644 example/lib/l10n/app_en.arb create mode 100644 example/lib/l10n/app_ru.arb create mode 100644 example/lib/main.dart create mode 100644 example/lib/main.release.dart create mode 100644 example/lib/model.dart create mode 100644 example/lib/pages/battery_plus/model.dart create mode 100644 example/lib/pages/battery_plus/page.dart create mode 100644 example/lib/pages/device_info_plus/model.dart create mode 100644 example/lib/pages/device_info_plus/page.dart create mode 100644 example/lib/pages/flutter_local_notifications/model.dart create mode 100644 example/lib/pages/flutter_local_notifications/page.dart create mode 100644 example/lib/pages/flutter_secure_storage/model.dart create mode 100644 example/lib/pages/flutter_secure_storage/page.dart create mode 100644 example/lib/pages/home/model.dart create mode 100644 example/lib/pages/home/page.dart create mode 100644 example/lib/pages/package_info_plus/model.dart create mode 100644 example/lib/pages/package_info_plus/page.dart create mode 100644 example/lib/pages/path_provider/model.dart create mode 100644 example/lib/pages/path_provider/page.dart create mode 100644 example/lib/pages/shared_preferences/model.dart create mode 100644 example/lib/pages/shared_preferences/page.dart create mode 100644 example/lib/pages/wakelock/model.dart create mode 100644 example/lib/pages/wakelock/page.dart create mode 100644 example/lib/pages/xdga_directories/model.dart create mode 100644 example/lib/pages/xdga_directories/page.dart create mode 100644 example/lib/theme/colors.dart create mode 100644 example/lib/theme/radius.dart create mode 100644 example/lib/theme/theme.dart create mode 100644 example/lib/widgets/layouts/page_layout.dart create mode 100644 example/pubspec.lock create mode 100644 example/pubspec.yaml create mode 100755 example/run.sh create mode 100644 example/web/favicon.png create mode 100644 example/web/icons/Icon-192.png create mode 100644 example/web/icons/Icon-512.png create mode 100644 example/web/icons/Icon-maskable-192.png create mode 100644 example/web/icons/Icon-maskable-512.png create mode 100644 example/web/index.html create mode 100644 example/web/manifest.json diff --git a/example/.gitignore b/example/.gitignore new file mode 100644 index 0000000..3db3823 --- /dev/null +++ b/example/.gitignore @@ -0,0 +1,47 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +/build/ + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release + +# Aurora generated +/aurora/flutter diff --git a/example/.metadata b/example/.metadata new file mode 100644 index 0000000..8a5abeb --- /dev/null +++ b/example/.metadata @@ -0,0 +1,30 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled. + +version: + revision: 135454af32477f815a7525073027a3ff9eff1bfd + channel: aurora + +project_type: app + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: 135454af32477f815a7525073027a3ff9eff1bfd + base_revision: 135454af32477f815a7525073027a3ff9eff1bfd + - platform: aurora + create_revision: 135454af32477f815a7525073027a3ff9eff1bfd + base_revision: 135454af32477f815a7525073027a3ff9eff1bfd + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/example/README.md b/example/README.md new file mode 100644 index 0000000..d92661a --- /dev/null +++ b/example/README.md @@ -0,0 +1,16 @@ +# flutter_example_packages + +A new Flutter project. + +## Getting Started + +This project is a starting point for a Flutter application. + +A few resources to get you started if this is your first Flutter project: + +- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab) +- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook) + +For help getting started with Flutter development, view the +[online documentation](https://docs.flutter.dev/), which offers tutorials, +samples, guidance on mobile development, and a full API reference. diff --git a/example/analysis_options.yaml b/example/analysis_options.yaml new file mode 100644 index 0000000..f9b3034 --- /dev/null +++ b/example/analysis_options.yaml @@ -0,0 +1 @@ +include: package:flutter_lints/flutter.yaml diff --git a/example/assets/images/logo-head.png b/example/assets/images/logo-head.png new file mode 100644 index 0000000000000000000000000000000000000000..93bed9f2b636a9cd065c1fc0f57ca27bbcc0a408 GIT binary patch literal 18385 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

OGad1?vt0 zIGPFg4Pf0Y(EMoP9Cu*bWRsSVPp8;tp7*dtB6B(%NAzc@>^N-8Q+<=Z_22OSWie9v zZn^~RAH*)xv~gWCW-+{6!i$z;F$_45caNIeUJt<`g0+uY5eJoV&tu7j@T2N+*-@MB}gK7bWo!?k7)m~Z{i|woxYYe7w_!9RGAz_6PN6| zt4P$#8@tDc9-+>wWI{@cTt8?o9_{|ha@yo?D$dcB=3O`2>yjxz7l>xgHX;=E1cQAs z3EErga+lsDgP0Yg2?o)TAJth^4@fXU zC!4IyB6atU<+Z@Bo>O6OA(Wr{EEN^lfpPdp*xIxesuXn!iAVizR(}uDYGRrFBV;2h zJ>0`M>2^eZ((iL_q#Nt^b=K7boj!3Gk-k8^JAFxg3Oga@KuUTaneQ!uRp%6wI&ol# zMqwO&V3=y2k@Na3?d27#xRfgU2HS^kzANlc`HxBX-Yz=DtMsB)m5_Fy+NWxUp3(p6Q?`Z{4@V4~hKf zxokW4FB)E?v`C%4716yXhBbc$fQOkr((m><*?$N`81OoPX!eM!k+CA5YQLDdEMPSM za%)(Vdzq`Vd}RrU?nNM`Op9H;W-p06%l?lndU3ssbAZDw@c{nn9K*x3cK#JxMXxU-7uJB$t4 z2vQi_+9mTRA35{uv%0NySfLNJe5UuYHzzpj!`eZ_nXdSTNMAj@XTZtnUi`$^LId;6 z-7J;R{hY~PSV1~A^U?yfm;U37=MirWmfG2P*O$3IJDl`=O!-gWdjSeNC5hcpFhXW& zQ#Ejh*isxWD|l*r|Kp@7#{9oE*IH#o9D!4p6i{&ikFS9neUhSu$NK__Q-!9_?Ods=efd-y##byhu-Z%7aaEPSCiYF`3@7Vy zQ+m>vf@k%hgWU2mo#CAx9H};p1`AEBVOk8^Une_e*i%-@b`L@Pl{_(uQgg5?0Def+ ziz$tV_15ke;BV+y0w!BNKcu9OOutux7WPWTxi^`vo;Nhfs3}9^%*?`6$MhQs&hK;? zH^ION0D9P%s+jLuBdix_))o>%;A42l88IlbE;VtsqUoMg8$T|@U{mhXpHZe;~N5NL|XAN5q9w?hp`{ zo*n1;)jB2>sP$Nr46pkB5)vRJ^$b!AznA;!yTTRYCQJGqMo8C)XTORz6dO32-2v z5G}5E=Rzlz=AIIdm z*;veSPQ$`WSFLd-EN70$FnVDDOWjQR>xu`|G(0Ttrgb$N^v9FAx229P!5Q@7hid~6 ze7b^xdBCZsLl+rLF!1ah`~ah$ehk^G7Xl*4tL_|?T*9tqDQt5=!7M=_i3H3eDJJH`VS_N;r;}a1EU2g5Bx)E z{rsakD2duJ4+Me=VrueCcI!g_rAa-?$Aj+ZZz0xZOuhd~-jon8l#KnYe{1UT2~nTQwP zo1rz8RfT-RoWdb5%QLFwO#sFAvd8g>P9T%-6LYXe zUJ>i0+oD!FzI)*)>d_H#)P8kp4K@D+G1{4PLVz^LPd&|~RxVKvckf?A*$1mK)~bxt zCi$;XMhgE{lV8U*!c?x`@o zW%)za$8LB#r0m|S7qQLK8q$u{XAHPZ+u=6V1N=gwcpc57-6!2FhnUFN@sFfjBKTl0vkU*5 zohN)i4zfXrx!oR*{PEqI#eY&BNW6^n6qTITaTBOt@KQeo8Lp>B-Cu}qPKiXU5}A2EvF zG2gz!(&Lk0wTv?UnC<=PaqEO)9h-^TO$;dR`%(SttASs|| zWKENi*z8=`g(c6wDj-kRx{hvK8IBoa`sLOnt`xQ%V6j9|AGn80V|d4k{7vwxB7>>3 z1A)1aDt_oL-Wso)!Nb?@fPQ1f{6aaVO_3&OiXL4{sI3>yvT;i@Y<`xC)Sn zMf$7cg3iZD}sXJ8_`^9q_&2}f+1}CUM(D3VAyWiTb zjHGn1_D~+A7rCmB9b6-K>+Zf0D8{L8(rrQUe>DIAM&dtqUIqbO%PaNEX~etgjb3uu z{l=#Ms40Pey5E=l7!J<>2v~$#4m*>-681s#$!qIq1Ef_{ffcp94vht1MKWsLaT&i5 z_9?%psL8fpPy%uB1(X=QVmDaWWyP&DJCLxB>iuSNZYVc!6j6N*dcPqAd&);;A;#8 zpd{29tGJ%(DfdR~GTb_*n3A;P)&;}&4y2llhIM_oPl zM@Pt-ZqDgN56#W)72^t*WzIDSOZpN_ZZdU(xr_BID7+o0#n4p!lToSQ_nLIjA9ZFe zsFkC2cUQBkO}!*hRrK*Bx{BehBH~kh!K%dZ>l%TV#+JReuHPndYqTscMu4G0F%;zB z;Nfr^xHI=6vhc;F`0(zcWY-K-pnUi_$Ov6F@BjBFp&c+(q(Xk z?z4B{Oqy4m*l|9QFJM|KcYp#qrafA38lDA&zAg=DJ(o8!1BwMj;)Zw3{IDaSRSAaXGessm*z+}^ z6@tPQSENL^DU+^hvWoRWx*}bVme68}D=A1G)`sADxvfnoIVT6{pY3=e21O{5Qt%T&UU4Z{7xO zT_=w;=Ps*qHUeLY-q{BBlvM25HH89N;f+nbI)pKs(`9Cj#@NL=;xGzXM=jUeM4jqGWgfXS|+D$s{*5wXbosG;?Db$%HU*{b_Zo^#kD~J>@S7C(PR&+2*0Vx zhd*$p*v>Cvxh3gr+U-{AIlKHw|5=lqjb8wJ&EkJeW?NTE=NeZUceS~HA_z#}>WY#O zXZReE1NM&sh?+L!A!zt7$&g5$V~EQ^eV;ysY{lL}PC>Av?ItKrhRE5X1ONhC?T!+a zY1tdA?LQA}>MU~l1GK5#D%hcJtjR(|C}=0>&Y`Ue##&M%08xCH1T?4F$O+vsO$ z0KF02fwuq051a*_Y8OH-mSnEMyEjStJ-DETb=|W`*IzH5c+_^Tx~clVCcLe8#nbg= zbgD!2gRhTa`&&Xk^*J5g@{EIG43ADq4-qk>kY+CU)H>Mwp5V~kou@?Ibawo=7ZHrd zvp@GWP>07e0KGfE&1O=h`t!mchY$JF7w;A(aGt+FZV3%~=0j5TH(aV2)JcCmbWA>x zeR-!Vy}p9`?y3ADE1efC5Q+pjPMs#wlChEM@8TrT#*oc;%T)Smwk^ar73=8N87n7; z9l&kzJ%im=yia_NSSe^<;K(nUe`F5KJCM0k7u$wLM9lx%10cjyw8jX^v@bz#+?hIB zjeRC;zO;0(G2_y)zU`AR1J$^%ln&&|Py-5GzzeB6n-_co;3hUQ|JFF!-ZUe{K|Is2 zW?GpCGs_an!GwNoUg%)L><*c3***m;4ts|u&bzx=Nk_wgzxGWb(02IYB2P%X(u1yb zZ_Zlnoh@HHL+8>xEXT$jt!fco`b*peEzWv9Lq?yKv)clsjOU;9sT;X}s+7 z%5<22Y7$XujKxnpz*a^x0k?;Y&ErIIJ1K1CNDkf^J7=O-d1*&V=a4{OAgxy2XPW003Vx?lq_&yI`!N4tYg%kzgd8 z7_ch~%HW_CI`Na|r*z;WjIA}G?Ik8qwJJAEZqRdgopxqemQR$BU>4j6To?KREA^Apn=7YxL( z3c4FVY$++LUxKzYj>4e^5D3ta_Y+^Ur5>L;{ze7{sU`zWeF!fGUC*=rCv}5jkN>E} zW{2mXPeT*hlG^RIX9W3fy}`bQ`CK_@4B-e`*$6X)L%o0wYRv43-5C8NAxZ|J_Zst7 zc|X+|8T&sgjqUwqMT}?b{#%&(^PGEK;|^DRv)TiO@a=W(_>%~orPJu}R6!qcmR;TK z`FiXHu{{`vqVfxoe>jUC#o{oux|0B*Zul?64zytSZGCedk0)#Jd0#0Y#<1-Hp8s<2WMP&ZzfJ2t(E1CSZ&p+BS!5b4;lR{XhF zp;G8kPRPF3#N&m#@C&NsNpCE<+}u_~0@_6fsk4m!1n`A>f#^FTkfmDpwyUU!IjFbg zFl(gf>o8P1xcwjnii8spNjmb71B3mK zFa0e8?emHs{~Ap3ylG(W`p*Es5w}W@lLE9tFr8sNRt@IXPc~sl`O^JYE}B>`rSFeo z=`e}*n|~b+Ak@Lt%Z#`aJZh?Go~{s!LnoxJrF)8v)6PV9TNt9)B}}z^qYc$L17A{- z{nKj{enTY) z^BHuLaRxf!+^Mp&rPft!RyD#?k-w_x@kQ%|P*zI%IJZS{o7TdOQ}$y(b);Lf>i}4* zXsoncvmY-_@8Z&XI-Bc?dLKz+@IgyAnyFpStdaYkh&ZdEa&&yY&}z>*Y5R#y5oq%y zlF_Yrv@}V*z;|g*&S^dnP;cP*4)&m{I;<4t_f137wy)U6)qH^#=`(OjlIl7ZA|HNq z^0`qz$TlH(#A18^_u?fj*FgevbrB#1G<`3`>A{NhszX~9B@9Zbf(!vom3F`mZ7G!~ z?du@!B(L*AOZNNEBy-_q-nT%W8UikL^;yV7!p%DptFfr*XBXg{`SuN|Z0B z>7hNVxHF%KAhG6C?gXAsOyx*BxVI-+@w5ZOL=xX`6VQ$0X~Mw4z`im%cn%?*JJpS_ zdJ8Ibbu10Ra;kvvBbh&^d#Y+IEOhZ(U0?$x-_S4_hn=edk*WgHYkp`6AJA6*?S0Zn zBebn}`iKI@fS={$_JQFs8YK@jjO~vukmbCEy4Mgn9WEG>fok*< zoSue4qp>;Y@lJ9E1P|=$7}|}DPtGz7=H3u!xfrk}I$r7^>5LtcxnXbeU9aYI(*o^C zTlLYP*>5oacEb1)TDzirvZ(@&w#&d*KT+7z1J?(%{|aGp6v69c*}-4nfUH~Z-(Sj= zp=7yXg8^vX0(fC;QQ}zq>0l|g=kfpz`ZA)8;k_J8lK?%M^3~$4l#qa#Idw2Iu5IAP zF#@aE{e((D;f7ubS1H&UOU2oZTf{)o;*g8yqitTnkKrSk&ht8Blqw2V7@<{ky^qKq z=humhE3b}zmxCVa3nFvPhaJeBMs-x>ppb5eGFadnvn+OWu{f2L=~!rbGLi_E?1CR? zQ!|9033lh-x*uH&yaC%Y?l{|bCPDA`qj8sqp`w{RV#XpE$jbBtUte%{=sV8j&hEP+Ibz8d> zpUsY5*}_(20qxGQ-@qW@fg}Ku1e^>~+;l;6Jn&Z+BJ*C--Io2m41&sD<8|n`rY`2g=dp{g&%i)ib7PY5;=TE!(J&hYEJ5B`<^SU#P- z>}U9E4$zSv$ABwI?{fs4j{e^_b6Fg4O_h}u$gvkUe681gKNHwbmAb#aGz4s{=4zb^ z&I3^ldlRy!^>s|*vaw?E(t4pfYx?6)*{P5+e#!Q(4;8`yWp00i_ I>zopr0K^4=@Bjb+ literal 0 HcmV?d00001 diff --git a/example/aurora/.gitignore b/example/aurora/.gitignore new file mode 100644 index 0000000..d3896c9 --- /dev/null +++ b/example/aurora/.gitignore @@ -0,0 +1 @@ +flutter/ephemeral diff --git a/example/aurora/CMakeLists.txt b/example/aurora/CMakeLists.txt new file mode 100644 index 0000000..4ac17ca --- /dev/null +++ b/example/aurora/CMakeLists.txt @@ -0,0 +1,47 @@ +cmake_minimum_required(VERSION 3.10) +project(ru.auroraos.flutter_example_packages LANGUAGES CXX) + +include(GNUInstallDirs) + +set(BINARY_NAME ${CMAKE_PROJECT_NAME}) +set(FLUTTER_DIR ${CMAKE_CURRENT_SOURCE_DIR}/flutter) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +set(CMAKE_CXX_FLAGS "-Wall -Wextra") +set(CMAKE_CXX_FLAGS_RELEASE "-O3") + +set(CMAKE_SKIP_RPATH OFF) +set(CMAKE_INSTALL_RPATH "\$ORIGIN/../share/${BINARY_NAME}/lib") + +find_package(PkgConfig REQUIRED) +pkg_check_modules(FlutterEmbedder REQUIRED IMPORTED_TARGET flutter-embedder) + +add_executable(${BINARY_NAME} main.cpp ${FLUTTER_DIR}/generated_plugin_registrant.cpp) +target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::FlutterEmbedder) +target_include_directories(${BINARY_NAME} PRIVATE ${FLUTTER_DIR}) + +include(flutter/generated_plugins.cmake) + +set(PACKAGE_INSTALL_DIR ${CMAKE_INSTALL_DATADIR}/${BINARY_NAME}) +set(DESKTOP_INSTALL_DIR ${CMAKE_INSTALL_DATADIR}/applications) +set(ICONS_INSTALL_ROOT_DIR ${CMAKE_INSTALL_DATADIR}/icons/hicolor) + +add_custom_command(TARGET ${BINARY_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy + ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/libflutter-embedder.so + ${PROJECT_BINARY_DIR}/bundle/lib/libflutter-embedder.so) + +install(FILES ${PROJECT_BINARY_DIR}/bundle/icudtl.dat DESTINATION ${PACKAGE_INSTALL_DIR}) +install(DIRECTORY ${PROJECT_BINARY_DIR}/bundle/flutter_assets DESTINATION ${PACKAGE_INSTALL_DIR}) +install(DIRECTORY ${PROJECT_BINARY_DIR}/bundle/lib DESTINATION ${PACKAGE_INSTALL_DIR}) + +install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) +install(FILES desktop/${BINARY_NAME}.desktop DESTINATION ${DESKTOP_INSTALL_DIR}) + +foreach(ICONS_SIZE 86x86 108x108 128x128 172x172) + install(FILES icons/${ICONS_SIZE}.png + RENAME ${BINARY_NAME}.png + DESTINATION ${ICONS_INSTALL_ROOT_DIR}/${ICONS_SIZE}/apps/) +endforeach(ICONS_SIZE) diff --git a/example/aurora/desktop/ru.auroraos.flutter_example_packages.desktop b/example/aurora/desktop/ru.auroraos.flutter_example_packages.desktop new file mode 100644 index 0000000..37ffbea --- /dev/null +++ b/example/aurora/desktop/ru.auroraos.flutter_example_packages.desktop @@ -0,0 +1,12 @@ +[Desktop Entry] +Type=Application +Name=Flutter example packages +Comment=Application demonstrating the work of plugins. +Icon=ru.auroraos.flutter_example_packages +Exec=/usr/bin/ru.auroraos.flutter_example_packages +X-Nemo-Application-Type=silica-qt5 + +[X-Application] +Permissions= +OrganizationName=ru.auroraos +ApplicationName=flutter_example_packages diff --git a/example/aurora/icons/108x108.png b/example/aurora/icons/108x108.png new file mode 100644 index 0000000000000000000000000000000000000000..f7af7fcba2afd66e6898c5a6d7f810a2049e53d4 GIT binary patch literal 3940 zcmV-q51a6bP)EX>4Tx04R}tkv&MmKpe$iQ?*4Z4i*t{$WWauh!xRIt5AdrrB-Ow!Q|2pp-DrM z;^HW{799LotU9+0Yt2!bCVt}afBE>hzEl0u6Z503ls?%w0>9U#=pOf@^k09CV$ zbRsThb1P!t6+gyEO~3aW^Rx2RdJD`(qdg>;jFNZGRuzcH;!_KLb}<%U`JjQ=g>Q zT3X}?=-mb`u3MVC2VCv|15dhSNRH&EDHIC8`x$*x4(PiDx>w!an)^6?05a57@&-6K z1V)OKz2@=mV0&->o@w^?1KCP)&@3*f&j0`b24YJ`L;(K){{a7>y{D4^000SaNLh0L z01ejw01ejxLMWSf00007bV*G`2j>PB2@N=}+JPki000?uMObu0Z*6U5Zgc=ca%Ew3 zWn>_CX>@2HM@dakSAh-}000d;NklLbVn93402~EQ0+)fHP=)@(F9;8TWd~*h>wsmzWI(pYc0`l_ zt^tRE{Xm^iMSMVDMhzaI0{9Iu%>wn*qyf#qJHP>mOTSw`qPU@Ne_ zADVby8tjj(3D!7ej3xkY0hPvf>;OW_V7vsp2mHhuqm0y9pc**d?*`Wa)2(sISWN>e zfdUbD4p<6E*0^M>rX%O^Bhp*PNwW36whO0y-N_1bxxim2`d8v3_$?t z2_~d5wLmEfAdd2msfZ;Dm?aCCB@37Z%#sDnk_F5HX2}9(X+ULsr=!odnzPIAEO!RI}SRkMG3v7se-QQ8olm;*FiLBFt>{+Sc+-pqjnj zpPK^f87<2Cu9M8Y^Bzw1GiwerKeDPg=$%cQlw(R{t?xR?oI4+kYFHTLV*7fkowo)Cb;VpLZ_bnh;sz^%!q-)iGcBJvoU#TQ1RD zSSzRtY+<)=zA3Ou^cb&q)$vm2wyc4bF~FkoN=^o<*<%u{A8Ao4gZ0es%#JjeQKlm* zucR(e&8OaZrlrA(?t13ksl}-tunOnlfVJN{k1Mj%6oc`4u%7vyACMQ{YjrxzR7_sR zY5$vi;+w}+DScSQdYp~HdR|txW?dS5>cC=BIraW6?DD^2qIIulf$}a+^$6Ll5eF8P zmvh=*Z5pf+Jw|1)ftQtc$y4`}?UF|p)(TGhtJvpTU<$19dW?!-1M@p;#{{eqb&1Ky zs$#!y0axWbQ_^5%cOwfrYjMT@$XL;cL|9xZqtUmC{k{cUGyzsXSJ}|rz$;1(`SCrB zCCMWJ>vZ6^?D3VFV%>duf(_jblq&C%7yoa@nuZlvOe*J$e>1!M3u!fB&Kjr3spvk# z!j5;yQ~wM^EMR8VS!aBk_}E`&3any1&f4xKUg@kIv#^E@SWGIX(O1PM{!%WRWH8o- z&QjW0i#xWHu`JVpsZuFT{whB8zrsa1pL8F^DligMhMHKYd@$x=nGQ^qN@?`H#mD|K zE|~z!WoT^dK0{eY4X*e>ESU%_E|t;jtzu7Lv1!)5B6OBT9oxu{|JRtEvxWs&Tq>i< z_bWa&71lY*lpPiA+zG@EoOSvGs z(molFp|LvL%pzqcp4fJaj+wwzX#q{XEqvl%Ota0Ew!z3VG}edCvAAP9p4cZA88d;Y z;!Cs?Z06&@VlK!oldO9)ueNVXxj`!png&dj7I4nHh24eaw3v_veR_g5;T9GvJIIe8 zvS67BOqEJG=iSWSK)ES%RzO!-6+X{mWhVvE-2=kX#2M&<+q8=o^?OLh+3W_UN~JV= zH*?UWIm=~e{33jTMam!XM&BLqxE|Z>$o4{^u-Gytr8dh9Fts<4XBJU=xBR``c?3wT$Hb^dn!sXQ4 zy-yTn1xA8jgfCIv(Vqq%4l80`#n*vus2VtEc zA_kUHXZH;WTGC)#;#FlA-sndIr$O64CSiGJnF1@2T1P8WKExBN9b2|u)=x04E4iai zym0xT%}1W0u{v^za^(;B`)UV-)oWYJv7#*;D44-*6P~#A7#fwKvn zw(?6u!zfzGS)2Qzk>)gX)}&y0qx%Ln7}9dSa96WCcLpKBk@kB6lHL9m%9Nd1+3kO# z8%bsT6h98u@J8oheyVmq@FN~WV@>1||Io1mZ*(65oewt{@@stQ-o)F^7dfQbP+|sJ z8m|it=qf8Bmsq6iNOk+Oug&$u-FjI+!St@JY!C!w{}N88+@s6Tcr9|7rOIx+eR~Ih z1wGO-j^+O|?>J}iSHTVjT#o4&hy)x0@(@F2{JuG>$AD`w9fkF#Hbgw-pp;i$WsZO)nBgVnFleb5RW0+R6f$XXXlE_x;#$XLJz z18sU&l;=W|$Wgy~1guqj;r=z-oijN82saoqpf#o=q#|t~Xaz=swW0HrDIej99$+ji z&6sxAl&qgZ)=v%aY0?cIbNwstJ7454gRt&l11`pN1VO}ae-N5aPq3orGK-au@J6>W zRx~0{uk=dg9C!T_+wx`)3Rb`R47eQCF^um=n#a&s8M(;Pj@mH=YeazcN~`$F^(Md1 zo5ztSD2gMg^avt;hkzH2RpGG-YuJIQ!aR=WZ(?iS+$Vzd!#T~Z8?1?6VCkKYQawp5 zU}j374-uUn6L!4{X*%s4?d06~nq22GkjCb{AJXqu@Vnt_qqI|;=w+PvBRXuwToayf z9}Qi{b*Gb_#&g`h*2lB9e8xG$*hIwwX0~ib8N_=Iy(?fHxN>SfBW~Lm<{pz^9UHs zEf&d@n=D{vL(A9pQ5u#IFwmW|9&bW)9anoBG@K@+gh2fMss2yQhW*C#0L(3B%s?B_ z_jI@tdngU5Ne7uXJK6Mom<%0P`%S{9zDe%uD?j{^+s~qQ#2Y_G6b$AT$8ks(EMR6U zUpquuNJZz@=y@~w@`uoL4LaHgpZGtx-31Q!BllK45Ot8a{`Uxi!JHzp9@?;*jt3RT zX53_wdY6g91Qc5_t^Gzs*Fb5*b^LSU-`)b76KuJU-3<3aLZUn3;~Be~an5^4;yo+E zhQo-w9Cn}zGO}|9e?bPN4fnCbgl^mhr#A^q99#|er>Gshbvpkp7|blRkt4NO5oUIz z*^P5dNF*o}iV5D0qMZDi(5)ck2f*P1$;MFj1;40C^hSJ4w7DsAhLOciE5e4uh?Ir; zp#5jWB7XkrDo$(D$i+K4~7t@GaXi{aO z5igS*Zi;ievT9Dtn73-@+0L+N0*HcvbYlu%s_C8D-o704)))A#pz&fLjx64=BFtRr z*riS;IQu9P`~-VkT-DOs!}nZ5rYls)lpGg@Io(+iX&D5pAKEQS^5XafpDEDV5)z?^ zpGgiEMY+LI4=uxhCFPL5qr|D=6Z~{U++0s{PP?Yc#CpAyIPxjX8Qst_5?B&i8xx%> zMWUCsu!oyzLTgZM7(G5FI$Wa~T1M|5=CYq+@dOZ9#B&`bB#iWKY7`TJc556)jc$uTgEbDLMvWqH6i8TOk?~3ZM@8TS z&}xlG#;X-LAp%!`!&a1Kd~_WKu80T(flq-JYg{r`Eh$DpQP_kI)B#(8?*PLZpUkPd zQcSi2bwU-%eveQ^95@KP4cxNEDPwdi#pGa$(f2zXMhza4ui|(Mm`;YbuCiDf&``9ua3KRL($^;NIN9&Vqe$ntWZkD2xGs!y%EHs$ z?2gGCWbRp!8&<->#tiP|V@5C?{d^iW8ZzkFIG~-b+l7 z-snM`L}QTZ;@Q?$PzzZa7sLd6n9sm%&375(t3P9ua&~f%7!m zNRYV|!L}S^T<~Vh%4&gb+3?j>SdmUcE#AztKHuEayogtqS>OdK~r;f2;tM?(!DpO3tQaxxo|=?60M#4qm3^gfNMIaeGbC0X+Wd7XGSU9v+UK{(!2l<0F4Z z2mT;ee;0lYEj>f?$ctP6a8X)IP1z)PawFf}+hjScJ7R14ee;XdK;>p?EjkFKF6nkn zezpu%((Th!?kmovQhIID=q63!roY2o>{HxhOLL`|T;YJ27~}-Xr7XR^>|5}h(|Xs^ z#rZC4L2>G9kgYWQK>j9 zEr8TE4+aZu$bHzqzjYf`o)kvFM#o2LGziDsYUw9GK)rxoA>e?ctD>PYg<>uJnQvcm zQcLmvtugf64b`fk{l?zu^*URSz#CYXT@JupRtKSTj`<`j1YbH>FyCW zKf>wMyG=CoioKEh`^hya@3q#D1;EOofVEz;L zsIVzPz$sl=TW)bi%^1bQ1)Y!ZO|LD%t;s3n2MQ4MgdI7FtRcL7Y9rm7VODM%RGGR{p;KKsGJT4!` zk$)rNO7VBBHs)tGxLicd4xo0*hk-iT1svx-($A{b=@s2H`v%7DS8d4QJ2sbnN)DPiKk793BP3A54R#z%R zb*8eDfk6~%ee3}0U^K?5)7@H5LGL<;8vJAr?!u2Fd#^8A>I{S$Qx^u29xzQ!4Ycr( z6iSYrKq!~|8E$FM^2XBT)VyOS8YK=6X;QeF{p@Yk-U3SaONt%QHV@7%m5@VWloJZ% z1ua}=CCxDNJ$f{Dk??rSi3zB{{Yi>oYi7ipf-{^KdS$NwIU*%r8qND~A0f@ZZ_By42ZC>yn8L%U%I^bLXy2n`FEJyKwzbu)WrZc5XB+efu8 zqHayywRM73DdjX@`oc>dR?>!l?wm-1XG+Z?Yu6pMCOGJ`bjRVf(Jy)*ua;e@{as_c-S6jfoOTR*3#U8C|6 zmz$PZT*_|hZq;InzaAKUm6YqssMv1_>K&6nR`)Bl zDaZRXB761nI`dB&Xiy@=+^~Un3Qc)VAiJ5$@+vw$XP+?wk4>-7Nb@UO&at6Qn6v}h zsT*nkaR{v-%BD0keQ+wJ*S;7x5{e*7(?B|3nS@1+g`E<%G|Y z8kpQ$b7c%4W7%UEVk&sJryLW_er|IXO6Maxk~|nMd}v-YiZWa`R*B^O5i2n_Byrkac9$ z<8OsOzR%|b3DjnufVQ5L@^F$Wu`SrcGnyuGs-uqR1|1Xi(RXGO11$;TOU)$^QOXTtD@=&C2p3rxF z-xpgLDCw0vQMXd|@e-1S`JM1SEys^cSOc@9FhFBop48GSw%GPjLGGV#YHf+d6}j%A zLBFPSvV!k=$g8=7A->B_XDtcbmDn(BPauDj7}Zxg>gx1WO+>)!9~sfqx4wM;3VA6q zC6#z8K0w=PA7QhiCsu4=)qhe;gYWZY`Q1G^IGw~lXiuim!Fup)R0S;l*Y18{ZQQHi z-gh)}jl{w9o9jgTs)|}h^q@Q?8{G}MMM}HO!Q-WVd?pHm_LnXYJ2s*&#F-ae-2KQO2Neq^? zXH#Xox-t)H2kl4(yhijUdDc0srzilb6`0np%Z_||o{{+2dmalk%r~d*xEvKuHKdXE zM|Kk3#Tu8i3TU0drX9AIqDZVpZW%2mU1uDkpv|i_MqP3x+h;kf@RQ^A^R;PL2=SB-1Z`?_8Z@64$<2%SZe{cMM2Lt;& z`EN6v_iv6h+mO2kP7HR9ol|v#ICg1zcgDA!Q)%|tj3{*=DL~vBf3Gui@W5eQHk!uV z2WL*9sDM!$?BG;e;=5r zFWeu%0!_n&-Zr0C$5wW~Y)SuS`EO|$_-=H_ne++$?o%RG6UP4?uyPf_rnR%H6A3k} zld)me4`m~~Q#;Zl79Q^jS#=sW5p2}z4~-uenSXjL4EWR47>3V7P3`2XYyR5uM4d#2 zA1yG)JP?m8{ZTq;Xs2%SF-*5_1260#D#-z;vS0-#v$aGsZ5-bxb40Z()04gPwvPh` z6>Y(J1{1C+w74C1$&nDqHQF~*PSgOtCcuyr+2e1d7hmbH&%(HW>F9{=_bskJG6OAH zZ+#S@Z@LlcFF{h&lEZAeDFtOY_r(`=2e>I&DEeaf_HBfz8LbT)I20 zlGx($7MjHb01Elo?p#qWQ~yue@$slx`E<-@gZ258_CHja;Ku@6&JCsO?=_-&ca9)W zRsO#N0b&0>=bWuB>LIrnL9ZMkaU4HWeAor?{?z_=gv^=EOW#m(;%w_;G}7;>UPRTUXn|)+4#zJch<>~H42HmE+`~2@*D?ev%F~lddBBmNijoK7 zo<{xMF~&X@h#tiYZ!i(|zh{bE0VLAP*<0*&*F zi{kOmKg!mkuNyQwepem^C~50hPOFRAD9ba6fwkXfO-!p$ztY#iMpscQ#TTZ$u#T;O z@_D3P7cZY@P}UjJhjXGZvMK20ju;8BB^Ylgm$lT=!Dya}Sy}LjpY zP0VQCZblZvwldjRfzH;;!WlwZ^sE4b&O54I-QiD{>!=c;V1k$fNdKEpU6uX>`fw3$ zVa7L(1}UXL83^TII0|GH$-EeBq0dKMEyK^a4l451g%yj`rLaHB#i@37E8xlB5LE6} zr#~OI35*v1{@kkVUI;zn@NR?_L#lt`1&S~PZ^9N>ldOsuyx!x|u?jOpI-GFddf*M7>^Sv^ly&DH7UNWyToH9IQS3gSg0dF(kQR6wMXPex!h+ zlC;D)j#lp>X^6!;A8=*lK;}>L>O?EHD0aodJ524Wc(8U`P334C(4Y}A!t<-Xwe#R4ytz%^`I zWr1TVfj{`xwLHT1%1|d`aZ&sox4>Upg6cbE>aPU}#uy>t8X2=hnR|<;8QMuaY^ldP zn{!K>mxagrO%&BW1FRd81Fy<>21vRsa5?_eXCF;492i4dR*0(ijBA94wk7KZq5=D#-EBQN#l1l{hnuw#vK-5$6lW2(DHW-K1vA~c8x|pNihjcRW_00 zp0@S550|rAge)e!ewcN`-4U*g@q_nUQ(DC$UBzpqZ}{O?*g0%Fuij(7@+Ofb%k_#; zm0sdgg^eDKzp<%Wx-u^u_+6Ht>oZ7*_OP9RJ6aUa*ZC=3=LD-ddmZ2BVO*zA$@7jB znhst%x2*-VvFmrP09qCmkK5TTGya?f$<)~AwSpZs0YLL+cZ1aBvg@2ooyWY7Em?oI zFf`lD&gC5|KL*H+S^owpE1%O#%xYWN*>nlRoEDML zYB`8C-Od;_L6`BUVdX|&D9iI6+<5Dwu~wYGvoxi6ZNtQ&-7a;v@Y{;d-qKr)I2itL z@MwSXld$=EWC=&?JaChK6W{}~ixOwoOIS;$7wNpdApDiV3v9-7IeBIGDf9SipJMKJ zY*@g%%jI8>g%gDt*3UTsoa9t_3bl{A!g0QOiYk!WDIZbuJ~ISV_|rs4;vL2zWPteca0DjUdU zErqO9i<1Uc>TG|5rj@tvJGJme{V0mhVQBdJZj%4*shu`0;maCdN7=5UBRb$8d{5x- zkFPzb$j5)S><%54p1ygLUg#RWKYQ2DUh*C!1@eFpR4UrQEnWOf3G)+qpUn1(SyGh1 z&H-nH{J(3>Wl|^Jb*43cUdDFN;O1uUxY7n^b#IZS+J8E2yd1DxLjNRXdq_R^ftc=E z5%%u=vLlMcrMjKBd!7ciO7#)Xq@Tjf-K(3V1^Lz&$tR7^DPeN=x}ETlfXQOQl3;K1 zLt>`Kzh}m9NWNNw588GpzzI&d(ktQW*!Q2&2T-9oDKrNm#JBE_IOXfj6N^UQrFgSY zv6{ob44Hl1H)xa?W4N{LL3Ys05=ipFM)qS4N=Ll}NStH&3e~?!k$`OIk-b%4+1;G6 zmu=#?=R=;V7?5xc$iz2j*7ixb_Cp(d_DS`@D6)j>E}Gby*HFVZ(}n+MZU9$weD5(! zAm?eDY;##C9Yn?Uk4tI{qE)ycUSJbew2Ds(l8=mSB!lg3=5q)f6jSEy zny!1yX~ah`+q{OvMaC>W_|_^R^Nl2}UbF6S>3YU_efnB{LIu*%5DuYMcG+#M6$I@q z*h^)fxqIw|lA9m;#=BcT8613m#O37Uu=*&rgc zq6T>kZh|;vs3B+mVLFY40uc(92q^j~PJ{1M{zN3W>TLjpJ_JY}Q|~><7h0K3#3Ac7 zuOfC!%UPEW;v+vgLk}#x?MrG+bo>4@8I>4vPciTNFTq{9gm@c$WjRs?SCuZ3eA9m)}DLu#7Qi%6~iLADlF(ONv)TE#;uP0 zcYE}qxjfa1IgQZHzTbzvX+NTO!_oaZvFmq#fwgQWvfJzvupi8GU zfan-IeOpP0;MyNCvNtKMt{Wu?hWEb*OJWcrf1aGCvz!;&C(*jA(FBLj*q2ph`a;T- zjA0l&+bvpHYi2FXPw@BYmN|NLZQZK$?4TEJ5axF9r@9wy7B=~_GHPI)->H8z=&~2= ze)5Fx_Qk5=5l{K56@rKOdUlF!4c21jYSKkuVWoYSr#$Sa3h90L^3I5!B2qfiwT!Rs z#VYBOO#NA`ie}a(hpXtEbPfZ48&AAex93vVw-u6EY-3vjh}vS4-N-rexiLub6xXIM zXky5ZPo_gBJs`pd#HraMg?L>Ql&a1hEFnm6)%Cv=1W$}lOs1Oz^-GJu1fD}tjYD>! z%wZx;mzQrb{T9aVpMqjw`A@=dm^A2yUW5(uAEX;a#Tf8FInZ$C{`O; zm(LYAx}@`IFxN7rGR-OU)Hr&>dE`hKjr6ghR8{QI4t{}tESG#K};)^P2vGc;?j-YD$K zV4GNoUswn2-3W?CbqxLcptVr9(>@aE*MHUj52MzjJsz;;iH=vLd!lnI_E(kqk8v%B z>^*+F9{mc|#@{OfFbA8ysc=GkyT2*3t7wS5uWN^y|q?~8PYUxY(K$DdHY{| zq*1L1`BlYcYzN8DC+-P)-xsm6YN{Jg9;_kd=D_%0^HajMsV@GVW9c#(#&*^o(5ViRZIILA}~X3dNk><3a|o ze%X}z@~t`j`RSG@;pbdwOT({dlx0u&A6S-T6ORnTQY}2x!kALPIlBK|h45n0`g#;2 z#^*H=X!FvMIqs)^j^8fO&+{zoeNfd3dqV4;3yt0``4)FyTxjzD?1{dXT5KAcnUVqTUa>*tCbMur8tWvV z9|oQsKA!hn_~snNh!Ofj;9P~lSt2zA&U)AGlmC5|N*FLAVUcT$KMvTcJCqQjjKY*09B0%1~jfkL*=qT2?+k-`gp9y7n>3SD=#m zvXWb(5~)iuE(4ckn4V=kuje(94r7PbMS_7He;KT#aZ}t0V>%w^=(}FKb(&=F|M3NS zr?i=@Ixo0uY&aUx}d>C>mprGx$(TgYTU$()WC8% zNyrT527do5BPNZA(DoF1D@wkn76EizMH|U%d?)p;eb<|MEn9P*)-qJ1snMAXo_&+4 z&8*&2C_gIYqcsXj2t#2^MJp~lFTWrmpYWrS^bqWtqBOh(>x*_v!0C?&8ol_#s<;zp zduPPR_FzQDOcZf50*GG~nRB0VzgXQzQzwMN>=Q4jWy!6X!^CM>{*|w`*;#Or__F4H zapUeMASB;Lo#!?A4c1ru$H&-dH^s5I7AUPRrxRGhU>eFblU=u-`~*-CI1yD&ixu(rJ`m4(M@& z5lBGiMy1}$$|t^21>L=t42rsdj}^a2W{9#>1>e0^zzhg&C5c~RWr&hF!<*?lgI%-VDZy@NuNdVH z-{y#Axn+kG3D;wqa3P4QT=#lXL|;n{#|<5F!L$ZXmg|vw6SV(_YP2UlbDOR#szk46 z>{E4rjW_4@@VH6kCCp8@nhE{K99avjt`5*(8mXsx}_>J zhi57{=NnQAxc2KG9!o*IPB`BQ9o~Pby(*O`92f9@Z=P{Gqb}x(QpfczeT!-SigVm_ zA#~34nrtM1tT5r=b~w`|KOauzxCZi6TvxD{8QEX>4Tx04R}tkv&MmKpe$iQ?*4Z4i*t{$WWauh!xRIt5AdrrB-Ow!Q|2pp-DrM z;^HW{799LotU9+0Yt2!bCVt}afBE>hzEl0u6Z503ls?%w0>9U#=pOf@^k09CV$ zbRsThb1P!t6+gyEO~3aW^Rx2RdJD`(qdg>;jFNZGRuzcH;!_KLb}<%U`JjQ=g>Q zT3X}?=-mb`u3MVC2VCv|15dhSNRH&EDHIC8`x$*x4(PiDx>w!an)^6?05a57@&-6K z1V)OKz2@=mV0&->o@w^?1KCP)&@3*f&j0`b24YJ`L;(K){{a7>y{D4^000SaNLh0L z01ejw01ejxLMWSf00007bV*G`2j>PB2@VO>Dbm~k000?uMObu0Z*6U5Zgc=ca%Ew3 zWn>_CX>@2HM@dakSAh-}000X1Nkl)w5Mn(N-~^@tj{ysTnScv0 zVFW-7=mt&z9{`^K4M3l?7IF0;X#lDWOaWd1s)6Z%#c&)lB1zPJKpoI5twp;An?!vO z_#;pOI1Dpg;RF5&`~^5JtwocP&3`KJXP^qO8BQrh2si}%35g~-*{A+CnW+Y9>S0S7 zK99gDCkLwKM)Mz$a3sg4X(nK9a-d3^5I{5r{(gwWM&~mn32YX~w16THdFXWDF%$4) zx{dz+Ff?9*W-kQ#L5REmnTiZ~S@82Bn4AwL<+g`ffQ6=Hoti%NO+116WorU;G{ftI zD}FG^FxfTap)*a%;y=ww&1X=oV{sxl*E(c`%Ksu(~{NHYY=|#{Jg05cB#OQstS%E2T zxUb*`D}(fdRb-fypXlGtUrF@2qfr%@l2yTE7v$N8aeO*f;bsL&a-qNpvH0lKv1TO! zJe)x@ZI=RNDbdemjM4u<#s~w}fHlH^HDC=`BMjKPIidJ5KfGUAM1AfmPBXw|OtKCx1St zQ$Q_AqCV2SiOk3Wqbo?D&gE3zI^N1(z)5p9n$GjxT9jvczv9vEjY(9$0UK53(vb5? z%BV$JKhO3YXRi8J?9si(;B_6fhPPbhDWR6c!#vgdHFLci$2{t&^|3K|HjOzo>~$^T zD@(3!)B-KSioTP~>3)N($UdXoN}xVOL+(0uyUJ5S&C_D6>^;fj-px4sca7OTbyQ(v z@@$&3UuI7-Q)B46Q03O5tn53*Jas*e$lkO;y{oV>`613_uVRmT3CApXx={~$~U zixg0^MVxA1J@eJA9hT7_TAgY5uDH zHyrjn!x8&L0y;1L*@Z?~=mJ&hP6~qC#x?4&GgjcH%f5>DJkRr#r`dWP&KI(P4cAPt&`DGm;`2MVea#N zOhF*cV6WI#a@74C?`7UYZwjdM!WUVt?q!1iAGbt3o%brc^B2%;%F?|Gma9cs=KB_F z%$t5)!THRG`5?1YH>wH26X8o#t8X*W_d2p@y5aSxGM6*CHSEq`z&9yeSafMo76qD^ z+r0y4|Jb|+He~yoaGu z=>?l1Gd3^0n9s4;04^;tFS z$}3Ol!eXNNw@{|mk)I})Yld0l_;H8cq(ZG_S)hf?0hucUkM(u`tOOqtYD{-OG6Yc_G|QO!$++Ov{Kde2JYa-w3@N$T7;2BD+R&L zRH$a+o@ePcWm4UJgekonFlomIp`Nv^VT+@ZI#Vtx5(sFG2qZKLtuh%ye60=a1d`*>wZz4Kp(dO3f05 zH{n`^MtSH0%e(3*3~U+n{^K@d2UZJ`@D9qd_4G5d98}qM&=t*$&Gb0QOia%PoPb<68NFa6#_?JFPu6>OY3)B_StYtxs+t~ zlc8J!-4ow&2n(RlL0(LySh$Fqi>a4wM214`?Lj(y3SV0%#5LM9nTvsJisW31?dgp> zqOezST``pjA{SvU=D)J-mc<&qSI9VZ0$*zfXxB6Qye4xw;KU>6P-Ksgp>!Cq*WOfI zAU}4Q5|NE$E}>Dj4#?aDDqnv|q`4h1!%f%G&c$VXK__lGhvLjI7NygGy^h;Xe(VYp zMGj$02~DzD(tYdFoDSX8J zL0BzWAnOTs1~sIwKcnwVBbXgv${6yIK!+n{V(n8=B#k)*3Yq5P2JArGnE{#AkpNPA zHanUxg3WW=OuaddMoie-rvfmifV9EAYhA&O-9j7g*aeEiF+xEP&2bwM9Z!7hj4Swp zP6|y<3hlwP=oUt;63>v1^FUsZ8ch&wy`TL-E52c#>jMslGKjbT6q6ihwkJ%6(r9Gt zwQo`G#$)TD(40#km_uvSbo)B@<|#8!A5*yO%cs=h#BB>;mQ^ETul2b~6Aycm_bIeb zV|&o5>->ZLW*lwPcomrC2Ak=$0eh`mP#T!!Hn9eYXxlV)hBEZwhOAi5--jd#X1O)2 z${7RpYS>H-JmglW5i*XBDfGnj-E9-pWR6@aB|l>p({jfitR&VG#n?w?q$4Ji*pSAE zk&SMd#4bNZjBK2cf%lWuj1eOf5#W6p_!Ou&JVq?)flp-;`%&#rPH>F4v+yM?8)Tpl zs3ox{{y)bZzu%^hYJ7z002ovPDHLkV1lSxM8E(5 literal 0 HcmV?d00001 diff --git a/example/aurora/main.cpp b/example/aurora/main.cpp new file mode 100644 index 0000000..331e26e --- /dev/null +++ b/example/aurora/main.cpp @@ -0,0 +1,9 @@ +#include +#include "generated_plugin_registrant.h" + +int main(int argc, char *argv[]) { + Application::Initialize(argc, argv); + RegisterPlugins(); + Application::Launch(); + return 0; +} diff --git a/example/aurora/rpm/ru.auroraos.flutter_example_packages.spec b/example/aurora/rpm/ru.auroraos.flutter_example_packages.spec new file mode 100644 index 0000000..f1ce250 --- /dev/null +++ b/example/aurora/rpm/ru.auroraos.flutter_example_packages.spec @@ -0,0 +1,31 @@ +%global __provides_exclude_from ^%{_datadir}/%{name}/lib/.*$ +%global __requires_exclude ^lib(dconf|flutter-embedder|maliit-glib|appmanifest-.+|.+_platform_plugin)\\.so.*$ + +Name: ru.auroraos.flutter_example_packages +Summary: A new Flutter project. +Version: 0.1.0 +Release: 1 +License: Proprietary +Source0: %{name}-%{version}.tar.zst + +BuildRequires: cmake +BuildRequires: pkgconfig(flutter-embedder) + +%description +%{summary}. + +%prep +%autosetup + +%build +%cmake -DCMAKE_BUILD_TYPE=%{_flutter_build_type} +%make_build + +%install +%make_install + +%files +%{_bindir}/%{name} +%{_datadir}/%{name}/* +%{_datadir}/applications/%{name}.desktop +%{_datadir}/icons/hicolor/*/apps/%{name}.png diff --git a/example/data/raw/flutter.svg b/example/data/raw/flutter.svg new file mode 100644 index 0000000..30c3a1e --- /dev/null +++ b/example/data/raw/flutter.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/example/data/raw/icon.png b/example/data/raw/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..8ab60ab9b1f53a34a24f6f017830d928070a25f1 GIT binary patch literal 11470 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 V_AT`4d>jORU}}1I%kS7d{a \ No newline at end of file diff --git a/example/data/raw/package.svg b/example/data/raw/package.svg new file mode 100644 index 0000000..3626988 --- /dev/null +++ b/example/data/raw/package.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/example/l10n.yaml b/example/l10n.yaml new file mode 100644 index 0000000..4e6692e --- /dev/null +++ b/example/l10n.yaml @@ -0,0 +1,3 @@ +arb-dir: lib/l10n +template-arb-file: app_en.arb +output-localization-file: app_localizations.dart \ No newline at end of file diff --git a/example/lib/app.dart b/example/lib/app.dart new file mode 100644 index 0000000..7beb5e0 --- /dev/null +++ b/example/lib/app.dart @@ -0,0 +1,33 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_example_packages/base/di/app_di.dart'; +import 'package:flutter_example_packages/model.dart'; +import 'package:flutter_example_packages/pages/home/page.dart'; +import 'package:flutter_example_packages/pages/xdga_directories/page.dart'; +import 'package:flutter_example_packages/theme/theme.dart'; +import 'package:scoped_model/scoped_model.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; + +/// Main app class +class MyApp extends StatelessWidget { + const MyApp({super.key}); + + @override + Widget build(BuildContext context) { + return ScopedModel( + model: getIt(), + child: ScopedModelDescendant( + builder: (context, child, model) => MaterialApp( + localizationsDelegates: AppLocalizations.localizationsDelegates, + supportedLocales: AppLocalizations.supportedLocales, + title: 'Flutter Aurora OS', + theme: appTheme, + initialRoute: '/', + routes: { + '/': (context) => const HomePage(), + '/xdga_directories': (context) => const XdgaDirectoriesPage(), + }, + ), + ), + ); + } +} diff --git a/example/lib/base/build/build.config.dart b/example/lib/base/build/build.config.dart new file mode 100644 index 0000000..2ae6133 --- /dev/null +++ b/example/lib/base/build/build.config.dart @@ -0,0 +1,3 @@ +abstract class BuildConfig { + bool get isDebug; +} \ No newline at end of file diff --git a/example/lib/base/build/build.debug.dart b/example/lib/base/build/build.debug.dart new file mode 100644 index 0000000..13add5a --- /dev/null +++ b/example/lib/base/build/build.debug.dart @@ -0,0 +1,6 @@ +import 'build.config.dart'; + +class BuildDebugConfig implements BuildConfig { + @override + bool get isDebug => true; +} \ No newline at end of file diff --git a/example/lib/base/build/build.release.dart b/example/lib/base/build/build.release.dart new file mode 100644 index 0000000..37c3b34 --- /dev/null +++ b/example/lib/base/build/build.release.dart @@ -0,0 +1,6 @@ +import 'build.config.dart'; + +class BuildReleaseConfig implements BuildConfig { + @override + bool get isDebug => false; +} \ No newline at end of file diff --git a/example/lib/base/di/app_di.dart b/example/lib/base/di/app_di.dart index 8412b12..4abd06f 100644 --- a/example/lib/base/di/app_di.dart +++ b/example/lib/base/di/app_di.dart @@ -1,25 +1,35 @@ +import 'package:flutter_example_packages/base/build/build.config.dart'; +import 'package:flutter_example_packages/model.dart'; +import 'package:flutter_example_packages/pages/battery_plus/model.dart'; +import 'package:flutter_example_packages/pages/device_info_plus/model.dart'; +import 'package:flutter_example_packages/pages/flutter_local_notifications/model.dart'; +import 'package:flutter_example_packages/pages/flutter_secure_storage/model.dart'; +import 'package:flutter_example_packages/pages/home/model.dart'; +import 'package:flutter_example_packages/pages/package_info_plus/model.dart'; +import 'package:flutter_example_packages/pages/path_provider/model.dart'; +import 'package:flutter_example_packages/pages/shared_preferences/model.dart'; +import 'package:flutter_example_packages/pages/wakelock/model.dart'; +import 'package:flutter_example_packages/pages/xdga_directories/model.dart'; import 'package:get_it/get_it.dart'; final getIt = GetIt.instance; /// Initialization application DI void setupDI(BuildConfig config) { - final dio = configureDio(url: config.baseUrl); getIt - // build info + // build info ..registerSingleton(config) - // services - ..registerSingleton(AuthService(dio)) - ..registerSingleton(UsersService(dio)) - ..registerSingleton(CardsService(dio)) - // pages models + // pages models ..registerFactory(() => HomeModel()) - ..registerFactory(() => SignInModel()) - ..registerFactory(() => SignUpModel()) - ..registerFactory(() => CardModel()) - ..registerFactory(() => CardsModel()) - ..registerFactory(() => StatsModel()) - ..registerFactory(() => FriendsModel()) - // other + ..registerFactory(() => BatteryPlusModel()) + ..registerFactory(() => DeviceInfoPlusModel()) + ..registerFactory(() => FlutterLocalNotificationsModel()) + ..registerFactory(() => FlutterSecureStorageModel()) + ..registerFactory(() => PackageInfoPlusModel()) + ..registerFactory(() => PathProviderModel()) + ..registerFactory(() => SharedPreferencesModel()) + ..registerFactory(() => WakelockModel()) + ..registerFactory(() => XdgaDirectoriesModel()) + // other ..registerSingleton(AppModel()); } \ No newline at end of file diff --git a/example/lib/extensions/keys_ext.dart b/example/lib/extensions/keys_ext.dart new file mode 100644 index 0000000..15a6bf2 --- /dev/null +++ b/example/lib/extensions/keys_ext.dart @@ -0,0 +1,18 @@ +import 'package:flutter/material.dart'; + +/// Extensions for [GlobalKey] +extension ExtGlobalKey on GlobalKey { + /// Get height by key + double? getHeight() { + if (currentContext == null) { + return null; + } + try { + final renderBoxRed = currentContext!.findRenderObject() as RenderBox; + final sizeRed = renderBoxRed.size; + return sizeRed.height; + } catch (e) { + return 0; + } + } +} \ No newline at end of file diff --git a/example/lib/l10n/app_en.arb b/example/lib/l10n/app_en.arb new file mode 100644 index 0000000..801c5ce --- /dev/null +++ b/example/lib/l10n/app_en.arb @@ -0,0 +1,3 @@ +{ + "helloPageTitle": "Flutter Aurora OS" +} \ No newline at end of file diff --git a/example/lib/l10n/app_ru.arb b/example/lib/l10n/app_ru.arb new file mode 100644 index 0000000..ddfd0cd --- /dev/null +++ b/example/lib/l10n/app_ru.arb @@ -0,0 +1,3 @@ +{ + "helloPageTitle": "Flutter ОС Аврора" +} \ No newline at end of file diff --git a/example/lib/main.dart b/example/lib/main.dart new file mode 100644 index 0000000..2712e00 --- /dev/null +++ b/example/lib/main.dart @@ -0,0 +1,9 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_example_packages/app.dart'; +import 'package:flutter_example_packages/base/build/build.release.dart'; +import 'package:flutter_example_packages/base/di/app_di.dart'; + +void main() { + setupDI(BuildReleaseConfig()); + runApp(const MyApp()); +} diff --git a/example/lib/main.release.dart b/example/lib/main.release.dart new file mode 100644 index 0000000..dfe04bc --- /dev/null +++ b/example/lib/main.release.dart @@ -0,0 +1,9 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_example_packages/app.dart'; +import 'package:flutter_example_packages/base/build/build.debug.dart'; +import 'package:flutter_example_packages/base/di/app_di.dart'; + +void main() { + setupDI(BuildDebugConfig()); + runApp(const MyApp()); +} diff --git a/example/lib/model.dart b/example/lib/model.dart new file mode 100644 index 0000000..34324e8 --- /dev/null +++ b/example/lib/model.dart @@ -0,0 +1,8 @@ +import 'package:flutter/widgets.dart'; +import 'package:scoped_model/scoped_model.dart'; + +/// Global model for app +class AppModel extends Model { + /// Get [ScopedModel] + static AppModel of(BuildContext context) => ScopedModel.of(context); +} \ No newline at end of file diff --git a/example/lib/pages/battery_plus/model.dart b/example/lib/pages/battery_plus/model.dart new file mode 100644 index 0000000..591da11 --- /dev/null +++ b/example/lib/pages/battery_plus/model.dart @@ -0,0 +1,8 @@ +import 'package:flutter/widgets.dart'; +import 'package:scoped_model/scoped_model.dart'; + +/// Model for [BatteryPlusPage] +class BatteryPlusModel extends Model { + /// Get [ScopedModel] + static BatteryPlusModel of(BuildContext context) => ScopedModel.of(context); +} \ No newline at end of file diff --git a/example/lib/pages/battery_plus/page.dart b/example/lib/pages/battery_plus/page.dart new file mode 100644 index 0000000..508e192 --- /dev/null +++ b/example/lib/pages/battery_plus/page.dart @@ -0,0 +1,31 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_example_packages/base/di/app_di.dart'; +import 'package:flutter_example_packages/pages/battery_plus/model.dart'; +import 'package:scoped_model/scoped_model.dart'; + +class BatteryPlusPage extends StatefulWidget { + const BatteryPlusPage({ + super.key, + }); + + @override + State createState() => _BatteryPlusPageState(); +} + +class _BatteryPlusPageState extends State { + @override + Widget build(BuildContext context) { + return ScopedModel( + model: getIt(), + child: ScopedModelDescendant(builder: (context, child, model) { + return Wrap( + spacing: 20, + runSpacing: 20, + children: const [ + Text("data"), + ], + ); + }), + ); + } +} \ No newline at end of file diff --git a/example/lib/pages/device_info_plus/model.dart b/example/lib/pages/device_info_plus/model.dart new file mode 100644 index 0000000..4e3b570 --- /dev/null +++ b/example/lib/pages/device_info_plus/model.dart @@ -0,0 +1,8 @@ +import 'package:flutter/widgets.dart'; +import 'package:scoped_model/scoped_model.dart'; + +/// Model for [DeviceInfoPlusPage] +class DeviceInfoPlusModel extends Model { + /// Get [ScopedModel] + static DeviceInfoPlusModel of(BuildContext context) => ScopedModel.of(context); +} \ No newline at end of file diff --git a/example/lib/pages/device_info_plus/page.dart b/example/lib/pages/device_info_plus/page.dart new file mode 100644 index 0000000..1d93280 --- /dev/null +++ b/example/lib/pages/device_info_plus/page.dart @@ -0,0 +1,31 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_example_packages/base/di/app_di.dart'; +import 'package:flutter_example_packages/pages/device_info_plus/model.dart'; +import 'package:scoped_model/scoped_model.dart'; + +class DeviceInfoPlusPage extends StatefulWidget { + const DeviceInfoPlusPage({ + super.key, + }); + + @override + State createState() => _DeviceInfoPlusPageState(); +} + +class _DeviceInfoPlusPageState extends State { + @override + Widget build(BuildContext context) { + return ScopedModel( + model: getIt(), + child: ScopedModelDescendant(builder: (context, child, model) { + return Wrap( + spacing: 20, + runSpacing: 20, + children: const [ + Text("data"), + ], + ); + }), + ); + } +} \ No newline at end of file diff --git a/example/lib/pages/flutter_local_notifications/model.dart b/example/lib/pages/flutter_local_notifications/model.dart new file mode 100644 index 0000000..e8bb71d --- /dev/null +++ b/example/lib/pages/flutter_local_notifications/model.dart @@ -0,0 +1,8 @@ +import 'package:flutter/widgets.dart'; +import 'package:scoped_model/scoped_model.dart'; + +/// Model for [FlutterLocalNotificationsPage] +class FlutterLocalNotificationsModel extends Model { + /// Get [ScopedModel] + static FlutterLocalNotificationsModel of(BuildContext context) => ScopedModel.of(context); +} \ No newline at end of file diff --git a/example/lib/pages/flutter_local_notifications/page.dart b/example/lib/pages/flutter_local_notifications/page.dart new file mode 100644 index 0000000..627dbd1 --- /dev/null +++ b/example/lib/pages/flutter_local_notifications/page.dart @@ -0,0 +1,31 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_example_packages/base/di/app_di.dart'; +import 'package:flutter_example_packages/pages/flutter_local_notifications/model.dart'; +import 'package:scoped_model/scoped_model.dart'; + +class FlutterLocalNotificationsPage extends StatefulWidget { + const FlutterLocalNotificationsPage({ + super.key, + }); + + @override + State createState() => _FlutterLocalNotificationsPageState(); +} + +class _FlutterLocalNotificationsPageState extends State { + @override + Widget build(BuildContext context) { + return ScopedModel( + model: getIt(), + child: ScopedModelDescendant(builder: (context, child, model) { + return Wrap( + spacing: 20, + runSpacing: 20, + children: const [ + Text("data"), + ], + ); + }), + ); + } +} \ No newline at end of file diff --git a/example/lib/pages/flutter_secure_storage/model.dart b/example/lib/pages/flutter_secure_storage/model.dart new file mode 100644 index 0000000..5f1e190 --- /dev/null +++ b/example/lib/pages/flutter_secure_storage/model.dart @@ -0,0 +1,8 @@ +import 'package:flutter/widgets.dart'; +import 'package:scoped_model/scoped_model.dart'; + +/// Model for [FlutterSecureStoragePage] +class FlutterSecureStorageModel extends Model { + /// Get [ScopedModel] + static FlutterSecureStorageModel of(BuildContext context) => ScopedModel.of(context); +} \ No newline at end of file diff --git a/example/lib/pages/flutter_secure_storage/page.dart b/example/lib/pages/flutter_secure_storage/page.dart new file mode 100644 index 0000000..7074e2a --- /dev/null +++ b/example/lib/pages/flutter_secure_storage/page.dart @@ -0,0 +1,31 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_example_packages/base/di/app_di.dart'; +import 'package:flutter_example_packages/pages/flutter_secure_storage/model.dart'; +import 'package:scoped_model/scoped_model.dart'; + +class FlutterSecureStoragePage extends StatefulWidget { + const FlutterSecureStoragePage({ + super.key, + }); + + @override + State createState() => _FlutterSecureStoragePageState(); +} + +class _FlutterSecureStoragePageState extends State { + @override + Widget build(BuildContext context) { + return ScopedModel( + model: getIt(), + child: ScopedModelDescendant(builder: (context, child, model) { + return Wrap( + spacing: 20, + runSpacing: 20, + children: const [ + Text("data"), + ], + ); + }), + ); + } +} \ No newline at end of file diff --git a/example/lib/pages/home/model.dart b/example/lib/pages/home/model.dart new file mode 100644 index 0000000..0e8460a --- /dev/null +++ b/example/lib/pages/home/model.dart @@ -0,0 +1,8 @@ +import 'package:flutter/widgets.dart'; +import 'package:scoped_model/scoped_model.dart'; + +/// Model for [HomePage] +class HomeModel extends Model { + /// Get [ScopedModel] + static HomeModel of(BuildContext context) => ScopedModel.of(context); +} \ No newline at end of file diff --git a/example/lib/pages/home/page.dart b/example/lib/pages/home/page.dart new file mode 100644 index 0000000..1aca288 --- /dev/null +++ b/example/lib/pages/home/page.dart @@ -0,0 +1,237 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_example_packages/base/di/app_di.dart'; +import 'package:flutter_example_packages/extensions/keys_ext.dart'; +import 'package:flutter_example_packages/pages/home/model.dart'; +import 'package:flutter_example_packages/theme/colors.dart'; +import 'package:flutter_example_packages/theme/radius.dart'; +import 'package:flutter_example_packages/widgets/layouts/page_layout.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:scoped_model/scoped_model.dart'; + +class HomePage extends StatefulWidget { + const HomePage({ + super.key, + }); + + @override + State createState() => _HomePageState(); +} + +class _HomePageState extends State { + double _hH = 0; + final _header = GlobalKey(); + + @override + void initState() { + super.initState(); + WidgetsBinding.instance.addPostFrameCallback((_) => setState(() { + _hH = _header.getHeight() ?? 0; + Future.delayed(const Duration(milliseconds: 100), () { + setState(() { + _hH = _header.getHeight() ?? 0; + }); + }); + Future.delayed(const Duration(milliseconds: 200), () { + setState(() { + _hH = _header.getHeight() ?? 0; + }); + }); + })); + } + + @override + Widget build(BuildContext context) { + final theme = Theme.of(context); + final localizations = AppLocalizations.of(context)!; + + return PageLayout( + child: ScopedModel( + model: getIt(), + child: ScopedModelDescendant( + builder: (context, child, model) { + return Stack( + children: [ + Container( + height: _hH > 0 ? _hH : 0, + color: AppColors.primary, + width: double.infinity, + child: Center( + child: Align( + alignment: FractionalOffset.bottomRight, + child: Padding( + padding: const EdgeInsets.only( + left: 20, right: 20, top: 0, bottom: 40), + child: Opacity( + opacity: 0.3, + child: Image.asset( + 'images/logo-head.png', + width: 250, + ), + ), + ), + ), + ), + ), + Container( + key: _header, + width: double.infinity, + padding: const EdgeInsets.only( + left: 20, right: 20, top: 30, bottom: 120), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "Welcome!", + textAlign: TextAlign.left, + style: theme.textTheme.titleLarge?.copyWith( + color: const Color(0xFF3c67b5), + ), + ), + const SizedBox(height: 50), + Text( + "In this application you can find 100500 plugins supporting Aurors OS. If it happens that something is missing for you, you can write to us or add it yourself.", + textAlign: TextAlign.left, + style: theme.textTheme.bodyLarge?.copyWith( + color: const Color(0xFF3c67b5), + height: 1.5, + ), + ), + ], + ), + ), + ListView.builder( + padding: EdgeInsets.only(top: _hH > 0 ? _hH - 16 : 0), + itemCount: 20, + itemBuilder: (context, index) { + final i = index; + return Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: i == 0 + ? const BorderRadius.only( + topLeft: Radius.circular(20), + topRight: Radius.circular(20), + ) + : null, + ), + child: Padding( + padding: i == 0 + ? const EdgeInsets.only( + left: 20, right: 20, top: 20, bottom: 0) + : const EdgeInsets.symmetric(horizontal: 20), + child: Column( + children: [ + Stack( + children: [ + Padding( + padding: const EdgeInsets.only(top: 10), + child: Stack( + children: [ + SizedBox( + width: double.infinity, + child: Card( + child: Padding( + padding: const EdgeInsets.all(20), + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Text( + 'battery_plus', + textAlign: TextAlign.left, + style: theme + .textTheme.titleSmall, + ), + const SizedBox(height: 10), + Text( + 'A Flutter plugin to access various information about the battery of the device the app is running on.', + textAlign: TextAlign.left, + style: theme + .textTheme.bodyMedium + ?.copyWith( + color: Colors.black + .withOpacity( + 0.6)), + ), + const SizedBox(height: 12), + Divider( + height: 1, + color: + const Color(0xFF3c67b5) + .withOpacity(0.2)), + const SizedBox(height: 12), + Text( + 'Version: 4.0.1', + textAlign: TextAlign.left, + style: theme.textTheme.caption + ?.copyWith( + color: const Color( + 0xFF3c67b5) + .withOpacity( + 0.7)), + ), + ], + ), + ), + ), + ), + Positioned.fill( + child: Material( + color: Colors.transparent, + child: InkWell( + customBorder: + RoundedRectangleBorder( + borderRadius: AppRadius.small, + ), + hoverColor: Colors.transparent, + onTap: () => debugPrint("click"), + ), + ), + ), + ], + ), + ), + Align( + alignment: FractionalOffset.topRight, + child: Container( + margin: const EdgeInsets.only(right: 16), + decoration: BoxDecoration( + color: i % 2 == 0 + ? Colors.orange + : Colors.blueAccent, + borderRadius: AppRadius.small, + ), + child: Padding( + padding: const EdgeInsets.all(6), + child: Text( + i % 2 == 0 + ? 'platform dependent' + : 'platform independent', + textAlign: TextAlign.left, + style: + theme.textTheme.caption?.copyWith( + color: Colors.white, + fontWeight: FontWeight.w100, + ), + ), + ), + ), + ), + ], + ), + const SizedBox(height: 20), + ], + ), + ), + ); + }, + ), + ], + ); + }, + ), + ), + ); + } +} diff --git a/example/lib/pages/package_info_plus/model.dart b/example/lib/pages/package_info_plus/model.dart new file mode 100644 index 0000000..45bb2c6 --- /dev/null +++ b/example/lib/pages/package_info_plus/model.dart @@ -0,0 +1,8 @@ +import 'package:flutter/widgets.dart'; +import 'package:scoped_model/scoped_model.dart'; + +/// Model for [PackageInfoPlusPage] +class PackageInfoPlusModel extends Model { + /// Get [ScopedModel] + static PackageInfoPlusModel of(BuildContext context) => ScopedModel.of(context); +} \ No newline at end of file diff --git a/example/lib/pages/package_info_plus/page.dart b/example/lib/pages/package_info_plus/page.dart new file mode 100644 index 0000000..92f1f74 --- /dev/null +++ b/example/lib/pages/package_info_plus/page.dart @@ -0,0 +1,31 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_example_packages/base/di/app_di.dart'; +import 'package:flutter_example_packages/pages/package_info_plus/model.dart'; +import 'package:scoped_model/scoped_model.dart'; + +class PackageInfoPlusPage extends StatefulWidget { + const PackageInfoPlusPage({ + super.key, + }); + + @override + State createState() => _PackageInfoPlusPageState(); +} + +class _PackageInfoPlusPageState extends State { + @override + Widget build(BuildContext context) { + return ScopedModel( + model: getIt(), + child: ScopedModelDescendant(builder: (context, child, model) { + return Wrap( + spacing: 20, + runSpacing: 20, + children: const [ + Text("data"), + ], + ); + }), + ); + } +} \ No newline at end of file diff --git a/example/lib/pages/path_provider/model.dart b/example/lib/pages/path_provider/model.dart new file mode 100644 index 0000000..2657ee9 --- /dev/null +++ b/example/lib/pages/path_provider/model.dart @@ -0,0 +1,8 @@ +import 'package:flutter/widgets.dart'; +import 'package:scoped_model/scoped_model.dart'; + +/// Model for [PathProviderPage] +class PathProviderModel extends Model { + /// Get [ScopedModel] + static PathProviderModel of(BuildContext context) => ScopedModel.of(context); +} \ No newline at end of file diff --git a/example/lib/pages/path_provider/page.dart b/example/lib/pages/path_provider/page.dart new file mode 100644 index 0000000..b46b211 --- /dev/null +++ b/example/lib/pages/path_provider/page.dart @@ -0,0 +1,31 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_example_packages/base/di/app_di.dart'; +import 'package:flutter_example_packages/pages/path_provider/model.dart'; +import 'package:scoped_model/scoped_model.dart'; + +class PathProviderPage extends StatefulWidget { + const PathProviderPage({ + super.key, + }); + + @override + State createState() => _PathProviderPageState(); +} + +class _PathProviderPageState extends State { + @override + Widget build(BuildContext context) { + return ScopedModel( + model: getIt(), + child: ScopedModelDescendant(builder: (context, child, model) { + return Wrap( + spacing: 20, + runSpacing: 20, + children: const [ + Text("data"), + ], + ); + }), + ); + } +} \ No newline at end of file diff --git a/example/lib/pages/shared_preferences/model.dart b/example/lib/pages/shared_preferences/model.dart new file mode 100644 index 0000000..6717380 --- /dev/null +++ b/example/lib/pages/shared_preferences/model.dart @@ -0,0 +1,8 @@ +import 'package:flutter/widgets.dart'; +import 'package:scoped_model/scoped_model.dart'; + +/// Model for [SharedPreferencesPage] +class SharedPreferencesModel extends Model { + /// Get [ScopedModel] + static SharedPreferencesModel of(BuildContext context) => ScopedModel.of(context); +} \ No newline at end of file diff --git a/example/lib/pages/shared_preferences/page.dart b/example/lib/pages/shared_preferences/page.dart new file mode 100644 index 0000000..edcfb68 --- /dev/null +++ b/example/lib/pages/shared_preferences/page.dart @@ -0,0 +1,31 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_example_packages/base/di/app_di.dart'; +import 'package:flutter_example_packages/pages/shared_preferences/model.dart'; +import 'package:scoped_model/scoped_model.dart'; + +class SharedPreferencesPage extends StatefulWidget { + const SharedPreferencesPage({ + super.key, + }); + + @override + State createState() => _SharedPreferencesPageState(); +} + +class _SharedPreferencesPageState extends State { + @override + Widget build(BuildContext context) { + return ScopedModel( + model: getIt(), + child: ScopedModelDescendant(builder: (context, child, model) { + return Wrap( + spacing: 20, + runSpacing: 20, + children: const [ + Text("data"), + ], + ); + }), + ); + } +} \ No newline at end of file diff --git a/example/lib/pages/wakelock/model.dart b/example/lib/pages/wakelock/model.dart new file mode 100644 index 0000000..610b1d8 --- /dev/null +++ b/example/lib/pages/wakelock/model.dart @@ -0,0 +1,8 @@ +import 'package:flutter/widgets.dart'; +import 'package:scoped_model/scoped_model.dart'; + +/// Model for [WakelockPage] +class WakelockModel extends Model { + /// Get [ScopedModel] + static WakelockModel of(BuildContext context) => ScopedModel.of(context); +} \ No newline at end of file diff --git a/example/lib/pages/wakelock/page.dart b/example/lib/pages/wakelock/page.dart new file mode 100644 index 0000000..14e4d22 --- /dev/null +++ b/example/lib/pages/wakelock/page.dart @@ -0,0 +1,31 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_example_packages/base/di/app_di.dart'; +import 'package:flutter_example_packages/pages/wakelock/model.dart'; +import 'package:scoped_model/scoped_model.dart'; + +class WakelockPage extends StatefulWidget { + const WakelockPage({ + super.key, + }); + + @override + State createState() => _WakelockPageState(); +} + +class _WakelockPageState extends State { + @override + Widget build(BuildContext context) { + return ScopedModel( + model: getIt(), + child: ScopedModelDescendant(builder: (context, child, model) { + return Wrap( + spacing: 20, + runSpacing: 20, + children: const [ + Text("data"), + ], + ); + }), + ); + } +} \ No newline at end of file diff --git a/example/lib/pages/xdga_directories/model.dart b/example/lib/pages/xdga_directories/model.dart new file mode 100644 index 0000000..ea659fc --- /dev/null +++ b/example/lib/pages/xdga_directories/model.dart @@ -0,0 +1,8 @@ +import 'package:flutter/widgets.dart'; +import 'package:scoped_model/scoped_model.dart'; + +/// Model for [XdgaDirectoriesPage] +class XdgaDirectoriesModel extends Model { + /// Get [ScopedModel] + static XdgaDirectoriesModel of(BuildContext context) => ScopedModel.of(context); +} \ No newline at end of file diff --git a/example/lib/pages/xdga_directories/page.dart b/example/lib/pages/xdga_directories/page.dart new file mode 100644 index 0000000..7994581 --- /dev/null +++ b/example/lib/pages/xdga_directories/page.dart @@ -0,0 +1,31 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_example_packages/base/di/app_di.dart'; +import 'package:flutter_example_packages/pages/xdga_directories/model.dart'; +import 'package:scoped_model/scoped_model.dart'; + +class XdgaDirectoriesPage extends StatefulWidget { + const XdgaDirectoriesPage({ + super.key, + }); + + @override + State createState() => _XdgaDirectoriesPageState(); +} + +class _XdgaDirectoriesPageState extends State { + @override + Widget build(BuildContext context) { + return ScopedModel( + model: getIt(), + child: ScopedModelDescendant(builder: (context, child, model) { + return Wrap( + spacing: 20, + runSpacing: 20, + children: const [ + Text("data"), + ], + ); + }), + ); + } +} \ No newline at end of file diff --git a/example/lib/theme/colors.dart b/example/lib/theme/colors.dart new file mode 100644 index 0000000..aa7e37f --- /dev/null +++ b/example/lib/theme/colors.dart @@ -0,0 +1,7 @@ +import 'dart:ui'; + +class AppColors { + static const Color primary = Color(0xFFCBDCF8); + static const Color secondary = Color(0xFF00b3ad); + static const Color warning = Color(0xFFfb7d4a); +} diff --git a/example/lib/theme/radius.dart b/example/lib/theme/radius.dart new file mode 100644 index 0000000..85c9d0e --- /dev/null +++ b/example/lib/theme/radius.dart @@ -0,0 +1,7 @@ +import 'package:flutter/material.dart'; + +class AppRadius { + static final large = BorderRadius.circular(24.0); + static final medium = BorderRadius.circular(16.0); + static final small = BorderRadius.circular(8.0); +} diff --git a/example/lib/theme/theme.dart b/example/lib/theme/theme.dart new file mode 100644 index 0000000..e4a313f --- /dev/null +++ b/example/lib/theme/theme.dart @@ -0,0 +1,54 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_example_packages/theme/colors.dart'; +import 'package:flutter_example_packages/theme/radius.dart'; +import 'package:google_fonts/google_fonts.dart'; + +final appTheme = ThemeData( + colorScheme: ThemeData().colorScheme.copyWith( + primary: AppColors.primary, + secondary: AppColors.secondary, + ), + cardTheme: CardTheme( + clipBehavior: Clip.antiAlias, + margin: const EdgeInsets.all(0), + color: AppColors.primary.withOpacity(0.4), + elevation: 0, + shape: RoundedRectangleBorder( + borderRadius: AppRadius.small, + ), + ), + + /// [Text] + textTheme: TextTheme( + headlineLarge: GoogleFonts.ubuntu( + fontSize: 60, + fontWeight: FontWeight.bold, + ), + headlineMedium: GoogleFonts.ubuntu( + fontSize: 40, + fontWeight: FontWeight.bold, + ), + headlineSmall: GoogleFonts.ubuntu( + fontSize: 24, + fontWeight: FontWeight.bold, + ), + titleLarge: GoogleFonts.ubuntu( + fontSize: 60, + ), + titleMedium: GoogleFonts.ubuntu( + fontSize: 40, + ), + titleSmall: GoogleFonts.ubuntu( + fontSize: 24, + ), + bodyLarge: GoogleFonts.ubuntu( + fontSize: 18, + ), + bodyMedium: GoogleFonts.ubuntu( + fontSize: 16, + ), + bodySmall: GoogleFonts.ubuntu( + fontSize: 12, + ), + ), +); diff --git a/example/lib/widgets/layouts/page_layout.dart b/example/lib/widgets/layouts/page_layout.dart new file mode 100644 index 0000000..8c4daa1 --- /dev/null +++ b/example/lib/widgets/layouts/page_layout.dart @@ -0,0 +1,38 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_example_packages/model.dart'; +import 'package:scoped_model/scoped_model.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; + +class PageLayout extends StatefulWidget { + const PageLayout({ + super.key, + required this.child, + }); + + final Widget child; + + @override + State createState() => _PageLayoutState(); +} + +class _PageLayoutState extends State { + @override + Widget build(BuildContext context) { + final localizations = AppLocalizations.of(context)!; + return ScopedModelDescendant(builder: (context, child, model) { + return Localizations.override( + context: context, + child: Builder( + builder: (context) { + return Scaffold( + appBar: AppBar( + elevation: 0, + ), + body: widget.child, + ); + }, + ), + ); + }); + } +} diff --git a/example/pubspec.lock b/example/pubspec.lock new file mode 100644 index 0000000..920d1cf --- /dev/null +++ b/example/pubspec.lock @@ -0,0 +1,614 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + _fe_analyzer_shared: + dependency: transitive + description: + name: _fe_analyzer_shared + url: "https://pub.dartlang.org" + source: hosted + version: "50.0.0" + analyzer: + dependency: transitive + description: + name: analyzer + url: "https://pub.dartlang.org" + source: hosted + version: "5.2.0" + args: + dependency: transitive + description: + name: args + url: "https://pub.dartlang.org" + source: hosted + version: "2.4.1" + async: + dependency: transitive + description: + name: async + url: "https://pub.dartlang.org" + source: hosted + version: "2.9.0" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + build: + dependency: transitive + description: + name: build + url: "https://pub.dartlang.org" + source: hosted + version: "2.3.1" + build_config: + dependency: transitive + description: + name: build_config + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.1" + build_daemon: + dependency: transitive + description: + name: build_daemon + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.1" + build_resolvers: + dependency: transitive + description: + name: build_resolvers + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + build_runner: + dependency: "direct dev" + description: + name: build_runner + url: "https://pub.dartlang.org" + source: hosted + version: "2.3.3" + build_runner_core: + dependency: transitive + description: + name: build_runner_core + url: "https://pub.dartlang.org" + source: hosted + version: "7.2.7" + built_collection: + dependency: transitive + description: + name: built_collection + url: "https://pub.dartlang.org" + source: hosted + version: "5.1.1" + built_value: + dependency: transitive + description: + name: built_value + url: "https://pub.dartlang.org" + source: hosted + version: "8.6.1" + characters: + dependency: transitive + description: + name: characters + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.1" + checked_yaml: + dependency: transitive + description: + name: checked_yaml + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.2" + cli_util: + dependency: transitive + description: + name: cli_util + url: "https://pub.dartlang.org" + source: hosted + version: "0.3.5" + clock: + dependency: transitive + description: + name: clock + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.1" + code_builder: + dependency: transitive + description: + name: code_builder + url: "https://pub.dartlang.org" + source: hosted + version: "4.4.0" + collection: + dependency: transitive + description: + name: collection + url: "https://pub.dartlang.org" + source: hosted + version: "1.16.0" + convert: + dependency: transitive + description: + name: convert + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.1" + crypto: + dependency: transitive + description: + name: crypto + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.2" + cupertino_icons: + dependency: "direct main" + description: + name: cupertino_icons + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.5" + dart_style: + dependency: transitive + description: + name: dart_style + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.5" + fake_async: + dependency: transitive + description: + name: fake_async + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.1" + ffi: + dependency: "direct main" + description: + name: ffi + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.2" + ffigen: + dependency: "direct dev" + description: + name: ffigen + url: "https://pub.dartlang.org" + source: hosted + version: "7.2.7" + file: + dependency: transitive + description: + name: file + url: "https://pub.dartlang.org" + source: hosted + version: "6.1.4" + fixnum: + dependency: transitive + description: + name: fixnum + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_lints: + dependency: "direct dev" + description: + name: flutter_lints + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" + flutter_localizations: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + frontend_server_client: + dependency: transitive + description: + name: frontend_server_client + url: "https://pub.dartlang.org" + source: hosted + version: "3.2.0" + get_it: + dependency: "direct main" + description: + name: get_it + url: "https://pub.dartlang.org" + source: hosted + version: "7.6.0" + glob: + dependency: transitive + description: + name: glob + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.1" + google_fonts: + dependency: "direct main" + description: + name: google_fonts + url: "https://pub.dartlang.org" + source: hosted + version: "4.0.4" + graphs: + dependency: transitive + description: + name: graphs + url: "https://pub.dartlang.org" + source: hosted + version: "2.3.1" + http: + dependency: transitive + description: + name: http + url: "https://pub.dartlang.org" + source: hosted + version: "0.13.5" + http_multi_server: + dependency: transitive + description: + name: http_multi_server + url: "https://pub.dartlang.org" + source: hosted + version: "3.2.1" + http_parser: + dependency: transitive + description: + name: http_parser + url: "https://pub.dartlang.org" + source: hosted + version: "4.0.2" + intl: + dependency: "direct main" + description: + name: intl + url: "https://pub.dartlang.org" + source: hosted + version: "0.17.0" + io: + dependency: transitive + description: + name: io + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.4" + js: + dependency: transitive + description: + name: js + url: "https://pub.dartlang.org" + source: hosted + version: "0.6.5" + json_annotation: + dependency: "direct main" + description: + name: json_annotation + url: "https://pub.dartlang.org" + source: hosted + version: "4.8.0" + json_serializable: + dependency: "direct dev" + description: + name: json_serializable + url: "https://pub.dartlang.org" + source: hosted + version: "6.6.1" + lints: + dependency: transitive + description: + name: lints + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" + logging: + dependency: transitive + description: + name: logging + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.1" + matcher: + dependency: transitive + description: + name: matcher + url: "https://pub.dartlang.org" + source: hosted + version: "0.12.12" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.5" + meta: + dependency: transitive + description: + name: meta + url: "https://pub.dartlang.org" + source: hosted + version: "1.8.0" + mime: + dependency: transitive + description: + name: mime + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.4" + package_config: + dependency: transitive + description: + name: package_config + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + path: + dependency: transitive + description: + name: path + url: "https://pub.dartlang.org" + source: hosted + version: "1.8.2" + path_provider: + dependency: transitive + description: + name: path_provider + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.15" + path_provider_android: + dependency: transitive + description: + name: path_provider_android + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.27" + path_provider_foundation: + dependency: transitive + description: + name: path_provider_foundation + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.3" + path_provider_linux: + dependency: transitive + description: + name: path_provider_linux + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.11" + path_provider_platform_interface: + dependency: transitive + description: + name: path_provider_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.6" + path_provider_windows: + dependency: transitive + description: + name: path_provider_windows + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.7" + platform: + dependency: transitive + description: + name: platform + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.0" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.4" + pool: + dependency: transitive + description: + name: pool + url: "https://pub.dartlang.org" + source: hosted + version: "1.5.1" + process: + dependency: transitive + description: + name: process + url: "https://pub.dartlang.org" + source: hosted + version: "4.2.4" + pub_semver: + dependency: transitive + description: + name: pub_semver + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.4" + pubspec_parse: + dependency: transitive + description: + name: pubspec_parse + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.3" + quiver: + dependency: transitive + description: + name: quiver + url: "https://pub.dartlang.org" + source: hosted + version: "3.2.1" + scoped_model: + dependency: "direct main" + description: + name: scoped_model + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + shelf: + dependency: transitive + description: + name: shelf + url: "https://pub.dartlang.org" + source: hosted + version: "1.4.1" + shelf_web_socket: + dependency: transitive + description: + name: shelf_web_socket + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.4" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.99" + source_gen: + dependency: transitive + description: + name: source_gen + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.2" + source_helper: + dependency: transitive + description: + name: source_helper + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.3" + source_span: + dependency: transitive + description: + name: source_span + url: "https://pub.dartlang.org" + source: hosted + version: "1.9.0" + stack_trace: + dependency: transitive + description: + name: stack_trace + url: "https://pub.dartlang.org" + source: hosted + version: "1.10.0" + stream_channel: + dependency: transitive + description: + name: stream_channel + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + stream_transform: + dependency: transitive + description: + name: stream_transform + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + string_scanner: + dependency: transitive + description: + name: string_scanner + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.1" + term_glyph: + dependency: transitive + description: + name: term_glyph + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.1" + test_api: + dependency: transitive + description: + name: test_api + url: "https://pub.dartlang.org" + source: hosted + version: "0.4.12" + timing: + dependency: transitive + description: + name: timing + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" + typed_data: + dependency: transitive + description: + name: typed_data + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.2" + vector_math: + dependency: transitive + description: + name: vector_math + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.2" + watcher: + dependency: transitive + description: + name: watcher + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.2" + web_socket_channel: + dependency: transitive + description: + name: web_socket_channel + url: "https://pub.dartlang.org" + source: hosted + version: "2.4.0" + win32: + dependency: transitive + description: + name: win32 + url: "https://pub.dartlang.org" + source: hosted + version: "4.1.4" + xdg_directories: + dependency: transitive + description: + name: xdg_directories + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" + yaml: + dependency: transitive + description: + name: yaml + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.1" + yaml_edit: + dependency: transitive + description: + name: yaml_edit + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" +sdks: + dart: ">=2.18.6 <3.0.0" + flutter: ">=3.3.0" diff --git a/example/pubspec.yaml b/example/pubspec.yaml new file mode 100644 index 0000000..dfa734e --- /dev/null +++ b/example/pubspec.yaml @@ -0,0 +1,45 @@ +name: flutter_example_packages +description: An application demonstrating the operation of Flutter plugins on the Aurora OS. + +publish_to: "none" + +version: 1.0.0+1 + +environment: + sdk: ">=2.18.6 <3.0.0" + +dependencies: + flutter: + sdk: flutter + flutter_localizations: + sdk: flutter + #################################### + ## Platform dependent plugins Aurora OS + + #################################### + ## Package verified + cupertino_icons: ^1.0.2 + google_fonts: ^4.0.3 + scoped_model: ^2.0.0 + get_it: ^7.2.0 + json_annotation: ^4.8.0 + ffi: ^2.0.2 + intl: ^0.17.0 + +dev_dependencies: + flutter_test: + sdk: + flutter + #################################### + ## Package verified + flutter_lints: ^2.0.0 + build_runner: ^2.3.3 + json_serializable: ^6.6.1 + ffigen: ^7.2.7 + +flutter: + generate: true + uses-material-design: true + assets: + - assets/ + - assets/images/ diff --git a/example/run.sh b/example/run.sh new file mode 100755 index 0000000..0ff40b8 --- /dev/null +++ b/example/run.sh @@ -0,0 +1,94 @@ +#!/bin/bash + +# Copyright (c) 2023. Open Mobile Platform LLC. +# License: Proprietary. + +## Build example, sign rpm, upload/install/run rpm to device + +## Usage +## +## chmod +x ./run.sh +## +## ./run.sh \ +## -d : \ +## -s /home/user/sign/folder + +## Flutter path +FLUTTER="$HOME/.local/opt/flutter-sdk/bin/flutter" + +## https://developer.auroraos.ru/doc/software_development/psdk/setup +## Install Platform SDK path +## You may not have set the PSDK_DIR environment variable. +## export PSDK_DIR=$HOME/AuroraPlatformSDK/sdks/aurora_psdk + +while getopts d:s: flag; do + case "${flag}" in + d) device=${OPTARG} ;; + s) sign=${OPTARG} ;; + *) + echo "usage: $0 [-d] [-s]" >&2 + exit 1 + ;; + esac +done + +## Update dependency +$FLUTTER pub get + +## Generate internationalizing +$FLUTTER gen-l10n + +## Run ffigen +# $FLUTTER pub run ffigen + +## Build aurora example app +{ + $FLUTTER build aurora --release +} || { + exit 1; +} + +if [ -n "$sign" ]; then + + key=$(ls "$sign"/*key.pem) + + if [ -z "$key" ]; then + echo "Key *key.pem not found." + exit + fi + + cert=$(ls "$sign"/*cert.pem) + + if [ -z "$cert" ]; then + echo "Key *cert.pem not found." + exit + fi + + ## Sign rpm system key + "$PSDK_DIR"/sdk-chroot rpmsign-external sign \ + --key "$key" \ + --cert "$cert" \ + build/aurora/arm/release/RPMS/*.rpm +fi + +if [ -n "$device" ]; then + + PACKAGE="ru.auroraos.flutter_example_packages" + + IFS=':' read -ra ADDR <<< "$device" + + D_IP="${ADDR[0]}" + D_PASS="${ADDR[1]}" + + # shellcheck disable=SC2012 + rpm=$(ls "$PWD"/build/aurora/arm/release/RPMS/*.rpm | sort -r | head -n 1) + + # upload rpm + scp "$rpm" defaultuser@"$D_IP:/home/defaultuser/Downloads" + + # install rpm + ssh -t defaultuser@"$D_IP" "echo $D_PASS | devel-su pkcon -y install-local /home/defaultuser/Downloads/$PACKAGE*.rpm" + + # run application + ssh -t defaultuser@"$D_IP" "/usr/bin/$PACKAGE" +fi diff --git a/example/web/favicon.png b/example/web/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..8aaa46ac1ae21512746f852a42ba87e4165dfdd1 GIT binary patch literal 917 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|I14-?iy0X7 zltGxWVyS%@P(fs7NJL45ua8x7ey(0(N`6wRUPW#JP&EUCO@$SZnVVXYs8ErclUHn2 zVXFjIVFhG^g!Ppaz)DK8ZIvQ?0~DO|i&7O#^-S~(l1AfjnEK zjFOT9D}DX)@^Za$W4-*MbbUihOG|wNBYh(yU7!lx;>x^|#0uTKVr7USFmqf|i<65o z3raHc^AtelCMM;Vme?vOfh>Xph&xL%(-1c06+^uR^q@XSM&D4+Kp$>4P^%3{)XKjo zGZknv$b36P8?Z_gF{nK@`XI}Z90TzwSQO}0J1!f2c(B=V`5aP@1P1a|PZ!4!3&Gl8 zTYqUsf!gYFyJnXpu0!n&N*SYAX-%d(5gVjrHJWqXQshj@!Zm{!01WsQrH~9=kTxW#6SvuapgMqt>$=j#%eyGrQzr zP{L-3gsMA^$I1&gsBAEL+vxi1*Igl=8#8`5?A-T5=z-sk46WA1IUT)AIZHx1rdUrf zVJrJn<74DDw`j)Ki#gt}mIT-Q`XRa2-jQXQoI%w`nb|XblvzK${ZzlV)m-XcwC(od z71_OEC5Bt9GEXosOXaPTYOia#R4ID2TiU~`zVMl08TV_C%DnU4^+HE>9(CE4D6?Fz oujB08i7adh9xk7*FX66dWH6F5TM;?E2b5PlUHx3vIVCg!0Dx9vYXATM literal 0 HcmV?d00001 diff --git a/example/web/icons/Icon-192.png b/example/web/icons/Icon-192.png new file mode 100644 index 0000000000000000000000000000000000000000..b749bfef07473333cf1dd31e9eed89862a5d52aa GIT binary patch literal 5292 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 literal 0 HcmV?d00001 diff --git a/example/web/icons/Icon-512.png b/example/web/icons/Icon-512.png new file mode 100644 index 0000000000000000000000000000000000000000..88cfd48dff1169879ba46840804b412fe02fefd6 GIT binary patch literal 8252 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 literal 0 HcmV?d00001 diff --git a/example/web/icons/Icon-maskable-192.png b/example/web/icons/Icon-maskable-192.png new file mode 100644 index 0000000000000000000000000000000000000000..eb9b4d76e525556d5d89141648c724331630325d GIT binary patch literal 5594 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 X>c!)3PgKfL&lX^$Z>Cpu&6)6jvi^Z! literal 0 HcmV?d00001 diff --git a/example/web/icons/Icon-maskable-512.png b/example/web/icons/Icon-maskable-512.png new file mode 100644 index 0000000000000000000000000000000000000000..d69c56691fbdb0b7efa65097c7cc1edac12a6d3e GIT binary patch literal 20998 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 MPgg&ebxsLQ025IeI{*Lx literal 0 HcmV?d00001 diff --git a/example/web/index.html b/example/web/index.html new file mode 100644 index 0000000..be172b7 --- /dev/null +++ b/example/web/index.html @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + flutter_example_packages + + + + + + + + + + diff --git a/example/web/manifest.json b/example/web/manifest.json new file mode 100644 index 0000000..090d9c0 --- /dev/null +++ b/example/web/manifest.json @@ -0,0 +1,35 @@ +{ + "name": "flutter_example_packages", + "short_name": "flutter_example_packages", + "start_url": ".", + "display": "standalone", + "background_color": "#0175C2", + "theme_color": "#0175C2", + "description": "A new Flutter project.", + "orientation": "portrait-primary", + "prefer_related_applications": false, + "icons": [ + { + "src": "icons/Icon-192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "icons/Icon-512.png", + "sizes": "512x512", + "type": "image/png" + }, + { + "src": "icons/Icon-maskable-192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "maskable" + }, + { + "src": "icons/Icon-maskable-512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "maskable" + } + ] +}