From 2158f65a05d27539d7a66318d54f24b3cf6022d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Uek=C3=B6tter?= Date: Tue, 27 Aug 2024 19:50:12 +0200 Subject: [PATCH] App updates (#77) --- .github/ISSUE_TEMPLATE/app_bug_report.yaml | 47 ++ .github/workflows/build_app.yaml | 36 +- app/analysis_options.yaml | 2 + app/android/app/build.gradle | 11 +- .../res/mipmap-anydpi-v26/ic_launcher.xml | 6 + .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 544 -> 4283 bytes .../mipmap-hdpi/ic_launcher_background.png | Bin 0 -> 857 bytes .../mipmap-hdpi/ic_launcher_foreground.png | Bin 0 -> 1889 bytes .../mipmap-hdpi/ic_launcher_monochrome.png | Bin 0 -> 1842 bytes .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 442 -> 2600 bytes .../mipmap-mdpi/ic_launcher_background.png | Bin 0 -> 463 bytes .../mipmap-mdpi/ic_launcher_foreground.png | Bin 0 -> 880 bytes .../mipmap-mdpi/ic_launcher_monochrome.png | Bin 0 -> 854 bytes .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 721 -> 5825 bytes .../mipmap-xhdpi/ic_launcher_background.png | Bin 0 -> 1321 bytes .../mipmap-xhdpi/ic_launcher_foreground.png | Bin 0 -> 2560 bytes .../mipmap-xhdpi/ic_launcher_monochrome.png | Bin 0 -> 2559 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 1031 -> 10108 bytes .../mipmap-xxhdpi/ic_launcher_background.png | Bin 0 -> 2953 bytes .../mipmap-xxhdpi/ic_launcher_foreground.png | Bin 0 -> 5279 bytes .../mipmap-xxhdpi/ic_launcher_monochrome.png | Bin 0 -> 5123 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 1443 -> 13881 bytes .../mipmap-xxxhdpi/ic_launcher_background.png | Bin 0 -> 4236 bytes .../mipmap-xxxhdpi/ic_launcher_foreground.png | Bin 0 -> 7434 bytes .../mipmap-xxxhdpi/ic_launcher_monochrome.png | Bin 0 -> 7378 bytes app/lib/db/database.dart | 16 +- app/lib/db/database.g.dart | 170 +++++++ app/lib/db/db.dart | 36 +- app/lib/db/db.g.dart | 197 -------- app/lib/db/pass_entry.dart | 19 + app/lib/db/pass_entry_dao.dart | 17 + app/lib/{ => home}/home_page.dart | 147 +++--- app/lib/home/pass_list_notifier.dart | 21 + app/lib/import_pass/import_page.dart | 41 +- app/lib/import_pass/pick_pass.dart | 4 +- app/lib/import_pass/receive_pass.dart | 7 +- app/lib/l10n/app_en.arb | 9 +- app/lib/main.dart | 4 +- app/lib/main_app.dart | 1 + app/lib/pass_backside/pass_backside_page.dart | 38 +- app/lib/router.dart | 2 +- app/lib/settings/settings_page.dart | 21 + .../Flutter/GeneratedPluginRegistrant.swift | 2 + app/pubspec.lock | 407 +++++++++------ app/pubspec.yaml | 15 +- apple_passkit/example/pubspec.lock | 28 +- passkit_server/pubspec.lock | 474 ++++++++++++++++++ passkit_ui/example/pubspec.lock | 42 +- 48 files changed, 1285 insertions(+), 535 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/app_bug_report.yaml create mode 100644 app/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml create mode 100644 app/android/app/src/main/res/mipmap-hdpi/ic_launcher_background.png create mode 100644 app/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png create mode 100644 app/android/app/src/main/res/mipmap-hdpi/ic_launcher_monochrome.png create mode 100644 app/android/app/src/main/res/mipmap-mdpi/ic_launcher_background.png create mode 100644 app/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png create mode 100644 app/android/app/src/main/res/mipmap-mdpi/ic_launcher_monochrome.png create mode 100644 app/android/app/src/main/res/mipmap-xhdpi/ic_launcher_background.png create mode 100644 app/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png create mode 100644 app/android/app/src/main/res/mipmap-xhdpi/ic_launcher_monochrome.png create mode 100644 app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_background.png create mode 100644 app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png create mode 100644 app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_monochrome.png create mode 100644 app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_background.png create mode 100644 app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png create mode 100644 app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_monochrome.png create mode 100644 app/lib/db/database.g.dart delete mode 100644 app/lib/db/db.g.dart create mode 100644 app/lib/db/pass_entry.dart create mode 100644 app/lib/db/pass_entry_dao.dart rename app/lib/{ => home}/home_page.dart (52%) create mode 100644 app/lib/home/pass_list_notifier.dart create mode 100644 passkit_server/pubspec.lock diff --git a/.github/ISSUE_TEMPLATE/app_bug_report.yaml b/.github/ISSUE_TEMPLATE/app_bug_report.yaml new file mode 100644 index 0000000..6db38b1 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/app_bug_report.yaml @@ -0,0 +1,47 @@ +name: 🐞 Bug Report +description: Describe the problem +labels: ["bug", "package: app"] +body: + - type: input + id: version + attributes: + label: Version + description: Which version of the App do you use? + placeholder: 1.2.3 ← should look like this + validations: + required: true + + - type: textarea + id: repro + attributes: + label: Steps to Reproduce + description: How can we see what you're seeing? Specific is terrific. + placeholder: |- + 1. foo + 2. bar + 3. baz + validations: + required: true + + - type: textarea + id: expected + attributes: + label: Expected Result + validations: + required: true + + - type: textarea + id: actual + attributes: + label: Actual Result + description: Logs? Screenshots? Yes, please. + validations: + required: true + + - type: textarea + id: passkit_file + attributes: + label: Upload ".pkpass" or ".pkpasses" file + description: If possible & relevant, please attach the non-working file. Change the file extension to zip and drop it into this field. + validations: + required: false \ No newline at end of file diff --git a/.github/workflows/build_app.yaml b/.github/workflows/build_app.yaml index 13cba75..3a7dd44 100644 --- a/.github/workflows/build_app.yaml +++ b/.github/workflows/build_app.yaml @@ -31,28 +31,22 @@ jobs: - uses: subosito/flutter-action@v2 with: channel: 'stable' - flutter-version-file: app/pubspec.yaml # path to pubspec.yaml - # write key.properties - #- run: echo "$KEY_PROPERTIES" > android/key.properties - # env: - # KEY_PROPERTIES: ${{ secrets.key_properties }} - # write key.keystore - #- run: mkdir android/key - #- run: echo "$KEY_KEYSTORE" | base64 --decode > android/key/key.keystore - # env: - # KEY_KEYSTORE: ${{ secrets.key_keystore }} + flutter-version-file: app/pubspec.yaml - run: flutter pub get - run: flutter analyze . - #- run: flutter build apk --build-number $GITHUB_RUN_NUMBER - - run: flutter build apk --build-number ${{ inputs.buildNumber }} --build-name ${{ inputs.versionName }} - - name: Create Release - id: create_release - uses: softprops/action-gh-release@v2 + - name: Decode Keystore env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + ENCODED_KEYSTORE: ${{ secrets.KEYSTORE_BASE64 }} + DECODED_KEYSTORE_PATH: android/app/keystore.jks + run: | + echo $ENCODED_KEYSTORE > keystore_base64.txt + base64 -d keystore_base64.txt > $DECODED_KEYSTORE_PATH + #- run: flutter build apk --build-number $GITHUB_RUN_NUMBER + - run: flutter build aab --build-number ${{ inputs.buildNumber }} --build-name ${{ inputs.versionName }} + - name: Upload to Google Play + uses: r0adkll/upload-google-play@v1 with: - name: App Release ${{ inputs.versionName }}-${{ inputs.buildNumber }} - tag_name: app-${{ inputs.buildNumber }} - draft: false - prerelease: true - files: ./app/build/app/outputs/apk/release/app-release.apk \ No newline at end of file + serviceAccountJsonPlainText: ${{ secrets.SERVICE_ACCOUNT_JSON }} + packageName: dev.uekoetter.passkit + releaseFiles: ./app/build/app/outputs/aab/release/app-release.aab + track: production \ No newline at end of file diff --git a/app/analysis_options.yaml b/app/analysis_options.yaml index a84b89b..7c63806 100644 --- a/app/analysis_options.yaml +++ b/app/analysis_options.yaml @@ -23,3 +23,5 @@ analyzer: missing_required_param: error missing_return: error todo: ignore + exclude: + - '**/*.g.dart' diff --git a/app/android/app/build.gradle b/app/android/app/build.gradle index 38c61b3..ead7316 100644 --- a/app/android/app/build.gradle +++ b/app/android/app/build.gradle @@ -46,11 +46,20 @@ android { defaultConfig { applicationId "dev.uekoetter.passkit" minSdkVersion flutter.minSdkVersion - targetSdkVersion flutter.targetSdkVersion + targetSdkVersion 35 //flutter.targetSdkVersion versionCode flutterVersionCode.toInteger() versionName flutterVersionName } + signingConfigs { + release { + storeFile file("keystore.jks") + storePassword System.getenv("KEYSTORE_PASSWORD") + keyAlias "cards_keystore" + keyPassword System.getenv("KEY_PASSWORD") + } + } + buildTypes { release { signingConfig signingConfigs.debug diff --git a/app/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml new file mode 100644 index 0000000..345888d --- /dev/null +++ b/app/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/android/app/src/main/res/mipmap-hdpi/ic_launcher.png index db77bb4b7b0906d62b1847e87f15cdcacf6a4f29..4e329d0d518b441e322b57231a881a2a4f05f7eb 100644 GIT binary patch literal 4283 zcmV;s5Jc~ZP)Px_bxA})RCr$PTzPmDMHYWOS7vfSAPJzZ$fB$w1mqAQTq?$(!U`w?u8ozc~^|9-3$Of$9dvX5d*K62d_sYfX~ARdP#NH zYUjXe4Uoj)+EpUXMF$NRrdz2Hv;j%OtP>}!#>p*bq&yOma69sLaYmk7EiOy31 zQR8cfK|CWe8sD)>hl_(KCkOSsicy!PQI`vlz?#VqZ66dHbwf7a5ZA|DuWU~!1}Mat z0S_A|KQCJ*o^a9)4rJ)1`v{cN#X-IAV$Lg{q|BB~4@Et!BV2%p*4U?yDw=DDHqQy> zL`+G65w9{E1jP`0G)&Iuv#3)(`}qa0ZoCaaYNWiLDWJjuh?rE=%ty~`^Ebq%Ha1{~ z>5&bzA@U58>egWtfgay0h`F=os|6q5cn<)$sqnxsNM-@T^0rAMw%wB$-EDJSwJ5-{ zw^8{IZT2XN1@mAA^+%J9k~_57If#zqpvryh{>7Wp@+FfqtV?D962STE@GWUAqPlOY zt46a{Yk;O}4kFCvy;*P#QiTc93taIQsPTRMz>>}B2ogqMhCnh3kP@64c4*b^Sui@b z34stu#L-OrBb7I&UCI|wAZ;_sBqIP3&552py0n@wN9>&#*@~$Y{Z|7p9dOJuD7XfR z?V%3lz0q+NSnzprJOI>7fn`u88371gxifpr4_~@}jqlB>n~Ks>w5NJ&B-s-xmSP*l z5Z>9mX5Ye%Hw^-S21&SeMLQHg2#({qkw;$O+`oIq=Ox}s--5Ng7U36dRx;n%0atzJ zfs?h4jep2@<6aZnXSZ|Ucm2F@(dRv8N+E!5oD>Woyyy7)Bgf`hyw^V4*r05=CUc}9 zMT$L`8GJQPfc?6s-}GmVv|+tOy@eXdC&eW{fZw=qm*r8dX z74X`XIQ%|<%3>cB?RCR}E%k8mtTzCXPVR=of-#cM_4C3vgP58YK!iQ9(?^t6HrDHy zr$h-dLJ7%Mxa;9)=$YmeUVJqUkDG_WPwSyzeJxa#itT1iOUu+MJ^H4m)f0g|&pdqS zMW|~#HE1|RW$8C{alpvQagfmJ3eiSq1j>H#!PL_9$N=YLF}uR3kg}j)Jk%n_V%p(qkx^+q-kC;CP{1j?P%`$$m%1 zFWTO!B>>d0g3SUHU{7t^sp>|EL!uQ~b?y@dV(dZL90xT(KCt4TrkjDGYK;LK5J~n z{x`nps1R!!AT+Po>BCAY-AvT10E`@f zhz@%~m>FHC&sK48>CTSnl31gS@&q9KYX^YlPp20b)5*CI*s5}M3NqQm9FQ@yxhauG zbIQpogR)=z@{Hv8IgF0cj8!Cc+OHzTeLf!Y-mQfTXVGTW?bXsGG_z8F-mnh~GG#L( z0HJwBJvFT0#i)i`rqKGMqlpx!#Z%NEvnJ;C@Q^d10?IG=WZijfYqBYj^$O#{{ z!cX6btCL!QXfd+H`{~H_`~JL%Owkg6FuHS1OyBlmEOeO^k}(=188$#!O-abE;@AOpAA=Ifje1IyT z3>nl!0G%oF7-o;aG-v6-CHbAv-Csg?PXI!Jj+-*%)E2HW;r3tvF-}b8Zc3^HGG>|6 zAT+U;BnFY}{q-*+$e^hdgQQNWyd2Y6ueJQpvVvPtsHn0jyVMJ=bHni160AO~cI!=Uk^29dai1qie94R2P%zxKHS^DK<+ z+x*@JgCC29lzvgVV<`X>27|D|w+dUg27n40AY>2%bit_CV#|fgpqH{Lp!^p~gBTOL z@RJu7K2ZtSVbMHzusb*yFgzNDPK-4Vkiw;DKmJx>>oyWV9>O32peYEDF$M08 zn_bpxy6dt=XD$fKqXuQpHt)rdK|&lPb$|uP2!plC&?2oBG3(V^>pyp7<=!6mvm%YO zY5ru|*Le>9+8)6hMYtrE5@r~IgOtAEY0y71(TfE{I(K`ka4}IlhX5@?FLqptqz%?u zTCz3f-w#qd!CD1PjnpS{q+*6T@wbp?tM4GNb*loyL6g9Lyu)i7vY*r6Kh z(ZwGW3`T&2=~qRnF{IbaL)*t^tO_PV>g--*6l&1;Ip)0>VGvmc%gv7vgS>!mw}ew5D9~0YQfVAaTNgLmOi3*LRa^F+itq z0U{us*zblCjb)!u9!N`riuO>;J_gZ}%&Q#$l+r7#G=pR_8`JNjIf;&bj}r|F3=}(L zf!!8pVp(&|c`<`+H(l(V>?%068#lEYKT6!Ymaaee$Q%Huq_z#KeugA09R4rkPo8x5 z`R`b7rb#4OgT(2ME48CTuj@D^vV4}f^lbEy*mE-g6chJOrm<-TVSU2nJ$kdu0sA+` z+1hm%k{H!~9rdhrhprA7{cJq6xZ0Z+&ii2Xf@=8wDDE9Mb`&=hEZcBs)I2G@Ap5C> zhgpEgnrfzz$?9=;*){F#(EC0YbnNAT=1Es}169RE9~|G~ zhW&ZW2C5JU1!IpEgUB_UK#N0vygA`0%4S08qwyF8X;b4Whx5O>JzyT^}~H{oyu6PNcEvRMj|!5t@wA=uxB@ zL%*Whd-~|=eFMfwITx;fk)KPcS`rK(VrrP9VTzsf#K7;rv2iF(>W$<!BMz%7NJl8VR^JGCjcbeb!+zE4vFKI$sp;Oj#iGumeoO& z*&ZFrT1?$Xa88%4oVe@M{4b=4nfw$%cYKWigk^+H<+wC7u;cUh-kg-RL>DBzjvEC? zgPo>O&?$`Id|SHWiNe!4TP4%N%?XN_N9$1|0O5034)q8@O6b?|`LvFS<0O!5q4y63 zaeht77!hkPAULN=S0Xt0Gbqfpa37+f-;5ari0Bc?)i5hf_)}`Zia1-_u57d&Y#v9~ zp&6JlFv}!#<(Ir?kFD7^FiQdk*V_>soMtriLtirh(IBBF;cu=IhWGqnN^*4HOc^Ad zIEEHpd7a8YSY;Lz!Wti652X$J-}~h7W3Nfzpdh2>7-A0X%FVWcXc8v1=+c^xxP8qt zEuG!6ESwXpeCXV*DZCTu1Yym8Dz+>wJe`C8x&m2)6Y%J*LTXMpUQAEBgiYtT@e@Hp zMm^Yb)l*5%o*7oo2^MgfTG2E+N@~sb0>zqKX4^+flB;J1&IWLt4UA5m1Op5~!2{V+>pge8&U^0bPYyr!w!{?2A z&z5gqzURAt?v=nmKv013gK5KMv4-wkBpAfjM+1dIj;f7_;0Mng!+Lx$k>_zmh38`I z*LRJ!weF(DnmX^r;{qt2pO2Q-6dkc}R$t-im-kD8i$7f=zz|SSXTs7NJ=R7VAo3op zmjH!PIL1#X==2A#;XTwaJV*A??ZJ+siJ-tDBM<~U#}A&9@9cl13RluJpKB_BXrS<% zfF=C57zq&kOTObd+ZK!l2uKJ53GVQmXbTDUnjp*+yU^4C>1h>tFJYQqJFw%V^DG!m d1`6Hi{{mOTTFSU{p8Ws-002ovPDHLkV1mm;0@eTk literal 544 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY3?!3`olAj~WQl7;NpOBzNqJ&XDuZK6ep0G} zXKrG8YEWuoN@d~6R2!h8bpbvhu0Wd6uZuB!w&u2PAxD2eNXD>P5D~Wn-+_Wa#27Xc zC?Zj|6r#X(-D3u$NCt}(Ms06KgJ4FxJVv{GM)!I~&n8Bnc94O7-Hd)cjDZswgC;Qs zO=b+9!WcT8F?0rF7!Uys2bs@gozCP?z~o%U|N3vA*22NaGQG zlg@K`O_XuxvZ&Ks^m&R!`&1=spLvfx7oGDKDwpwW`#iqdw@AL`7MR}m`rwr|mZgU`8P7SBkL78fFf!WnuYWm$5Z0 zNXhDbCv&49sM544K|?c)WrFfiZvCi9h0O)B3Pgg&ebxsLQ05GG~ AQ2+n{ diff --git a/app/android/app/src/main/res/mipmap-hdpi/ic_launcher_background.png b/app/android/app/src/main/res/mipmap-hdpi/ic_launcher_background.png new file mode 100644 index 0000000000000000000000000000000000000000..08751a9e64270db1492c6395d2d70e014f45dc12 GIT binary patch literal 857 zcmeAS@N?(olHy`uVBq!ia0vp^i$Iuz4M-mPBqj}{7>k44ofy`glX=O&z%1A!Pw%F6~KA%y*(L;p6(6CwA zAw?mO;m8r5K8A^nE{p=g#uiL2Y(lIKK4%_q2uO}98V!P>nhHAP&%U46cYgcgUBJA; N;OXk;vd$@?2>{?F<6Qs% literal 0 HcmV?d00001 diff --git a/app/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png b/app/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..623f869168393f7a8132b36c7d2026ef62d6852d GIT binary patch literal 1889 zcmeHIX;4!K5Pk>>3Kkw`087GypcoCK6%3aGh9pnqQj{PSkRpmA%8gMHPJJAT1T<2E zp)npU5;-IUA>u(1HQ`8^s5lX+N1za{Ksp5^O=s-SPXBlMWB1#c{dRwRJG)yH5=36T z%4QV+0IOjNakmz^f0@Awt$#dYX{!aD)ZJu1fZwxb6ae&XVWMwXR+O^Z`}VhoOwJC$ z-17#$MzQsjyLmA)zK zTt2Ny?T9m*IPcUmE_csVtK0)I?T0heRSNp)-c|+MwZXRr(82ZTZuId%5Iw8`Cbno( zpC0t9&&p*8HP&cLE0mI$!)bIcOeS4Qrhp1l zyUKgf(o3~*Z~bXX+`(vTV~U3txAaL7K|^?p8|}lG^3zq7yle-4sY7vAH80#z?)GqJ z)^Owq?)?JOZgbNliN?@oN_bnb2Rx-UvUb)9NBN0(PU-9t$$UBpp1kuex9DXp9Z0=f z_4V9D{i;^bznv^?s|6Uk-Wgz7VvHuG4T^0o7uxs{t!@SyHOr{r)^ZKkMN%w8wGLrL zn>;bJP^ltbt%^PLYHW=Tv9xuH#p`wSJ{pgHnt{!BUWTAl@AtsQS0gm6<3)NV{l+RX z94y9jv!02UW+zF~9RTQE*%SYuGL2J}tsE-ku>gn$!)W-vTuh&v^pgevpoqsa7LQ+G zl(fjArdSb28_`~(!|`Z*^KVY(JBZt7uQ%maE-9Wc66=~J^VJO<6Tif(*_z`6yC5zD z&oWJJ;3(898hb1aZ;U ze^UgZAY)9i=qPe+Q+$YoUy75=M3K^bCSKLjfPWUM%6lix3~0AYc7T>Jqt39))rgLQ z@kQDGF@@8D_ls~BKp(WqaeIbe?mwS>ejr2@$Oh+BhQ}AooFQ9?bR@89L^;Wwd!@aX1agzKF{{Ek_|UPD{=!ZU4)Q2p!pgnn%x&XeCG{; z>Rys>(XVl694USkJ$xE2gJ}}+{Q3;~u{yacW1sP@6N^o^IU9t~wR~ByeD>Bi?V?Ww z86ElyIzdO8AQHXNtq~$ctz~}9>@=uzZYm7#G%`Z2_@-OCg2~qAx9&cARLpTlOa4*Y zmWnU>cdb@`Ax(FK+iOpnf}gvy3@X0NVmnM@Kb8KG>(4|`KVYY8dQdKzHlX}=kKU=Y zmh=kC1$&t4xvTZ! z#HMR+svoBkK+hYpK{r?*t3(sK@bUy$e_pqmR8ilXNC97V3(3+X`13HybKg{?azPTh zHoiC1%Z-sHKZzS|{g_S#6`R#%qt(m|cyL=}sNm)q{s#*sq`ovIl?#7~f`o|ClfHD??TxzdA}trD-!ui4n?=AH$8f~WmlfVc&gM%;i>55dtPv+n$8*1VYirtJ(TJJ z&;%@0u2wwbcwTU#GW^E0F}C>5=HzmuD({w>8utS+ce)(6dc@D~##=c-A@` z;;{zUHN;i@B?AkF^bLypL3Js3AVqsDro*&=zfX>wOqPC}g4g7$TW_;k_Q6-QPSUX8 z#;I>?xwlHHq9C(kp3AtN!SplpSU_eyJTFS>)0OCpWFqmKLM4Br+GX*N?JO}Xo1M30 z zyoVqB4>86Z*+<4VR3$_J6KTSH4lm;@(Ttp!|5;#E%S-cb@Ecg+Z&)BbS#8^)nl*-MJ_`t)XrUv`qjx|G{6 z`qT2ebP2RU#-^`V7%R|pvg2C9Yb4l{=>?4FWlp4bKo%A(y8Ly(2)KqI-U%>{y7^K< zpyTfc%`AlJ0(qchZeN?Qpb&c;K}pyT6p@hfr~=H(qn7kTabbBP=Ib?ysKm!0XS z?v$M_xWOqCUAC$Nv0!j>d0A}fqwSr(i!bi$Nx7Dv96jf`gXJ$6Qb1Zbc$7pk~ja9+UKChjYE`-!uy>2hgpD>fl6 z3^KT`fBhOqA0h1VEEhnDOHVQXByZ0M>5IOThN>?Dr#-mnQ!{r3+jUW>8(A8CLhahU z9}u<~lvbbm@+(-?qb+xF)z%p*5B=ZFJhG;%Nl8R{GSWDvjS8`T%C!cXrb7+a3 zkr;INb%ldX)>Of>+2GmEpu7Un%23GHyylb>dSZY;s{l2!SsG{W4PNon#FQSJ+H@)F zSX>o1GqCG!pOHR;1qvm-X3Nn_$J6?iiFSWfHP+4!%lW^Pd|Em3x6Linv7+R-?xspw z@b?GryA0!LE-yT!5Z`3Q4&M_A{i(n1s|CuN036x1h=rY8Xg-y$gH(h zp9(Il>pNX1s{6qjZ8aEQYS@q97C#u6!6CSo$oT)q{#6nMN(ozavnZ*dM*Rd~Btj_u IMnK$|&*y0^%K!iX literal 0 HcmV?d00001 diff --git a/app/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/android/app/src/main/res/mipmap-mdpi/ic_launcher.png index 17987b79bb8a35cc66c3c1fd44f5a5526c1b78be..27e8539a5b10645006b2292ab3b2c135f27d81a3 100644 GIT binary patch literal 2600 zcmV+@3fJ|CP)Px;;z>k7RA@uhT6=I6U}kTRBm-3tDu8u=t3MEUjRgb{O?R9KNs`d*{M+kJhsUQ9@vB5^ zk+4gEj&rWaJC>CgKYXn#l*9p-d89x38<1C5;*a`&FfJ1M6O zC#snwu?UcRT}88NH+sZjzwPN#?yf~#{+lZ>%tAa!qlI{@SsWLi0Cb7hU)_H6;dLqr zN_5jtGy(+PT{!#V#&~I1k+0VfX}&P>qzr(06%_J{auEu$P^;&=+yZ)>UvAk^o=GH_ zr6NdJ5uo4Wie_Kj=*D-8{5@*qHIFEN@WIy-*d(e(3t1(4_&7yM$_UIlg@}JFr=j;;| zW;tP|fCE6ny2l&aG|%fIulR+JVzlIq7X66xIKT0gEj~d&Q%}vzvNLl|sQp5_y^#R< zK5kXPxnh^^d#l4<4O@>coO+J~qo>5fJAjmlUal?obINtKg>a#w2d#}t=i@KQ&UeJ$ zsohpNVhVsRzEAK3`#il(r_hdjo>5+DMK76+@6BC_*ezZRv*$1>bx7mD~s<$ zl2Bn#H@_pDDcD~%ubfwbM?u!{F8TSH;za3(D;4ySp3k12fb4k*eM4vS=!&uq9Dlo$ zlUv`}1<#$@QiBSNfEImEXn2vIl}y#Zyb$?I6Y=Owk4;E@JFNPHE*#m`9yyMv$wD)f zQ3XbTyzgC-b7u1Z{9vW&ZB-U|O9x;=o;N14ufFi3;+;-(w5WqpjA}&}Y;Tnm3q@&m zqF1j1BS7{U_`CduJ6gjsLR10dFN>|f_0Rp-@oXyse#OAiDpt6;MGk{zRf<%2qw1bC z0If8RGXn1UQ})gn?8-f?;pQ7AM<(Bf0!K>QaqgpTHIQbVm*rM?mNIRMT>0krx1fB^ zftsg}QD0yqvS)ej+0CBdh*eBJhFMpLB!Co{kQY4%-g~_rwI{me(7$#fBc|Q>1N=S- zML7*&7$%*)*Zq0P-qVwR51^X}kpBn#I=B9$Gmt(m;%26gTNVT0d5a5P_fONACla0~afl94Jv0Akdo^ z5CK}d1B22X*kDB?@USX=p?e8>>>m3L6%Z2`EX-D`1zv zGo(Ni0zSvh%X_LG%I2$3;**n(7NA& zNm-6H;8_+E_^`9)zIy>Q(n6mNb8;zN{Mh9RuXt~`5}Ei=Rv-oex;c&0J{&M$XI>Y_ncoQ zVA_-an(0=lSLr^_v%{i+U3cDEfCDSGK=fl}GlW=*unL_*6nwq3)dOcpNYsiEE0s_JODYm=;wxY&)I)!(@v05u4DF2vqQ=oDatsH7%mJ-9CS`>Bg} z3!tyu$GA8**~f_$S%LaUfUNWPmVHm3s(*p%ejBq6yRDg#<)?F$&`)H(zdqGHez6F* zb!X=Y$r-~p?kHoqohn7(n|-xpoflQ>^cvq6SY@L8n1x8p%{=&gn){JOR!T&ab(2+G zw7Di)!)ormu;)-TJ=inhDVcy|s8qIzgn@t6^6?+4uDwJr zzX>?a6PB-)`a^)vi+Ji4w9OrVxF{I%xzfGk7s#DE+6X8O zV&rcIntrzx@%|)nEF%09ZX(5|K(<(7MU?>3MsE#i>o;f~(0>5}`N@t~v8?6*0000< KMNUMnLSTXs0p|k% literal 442 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA3?vioaBc-sk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5Xx&nMcT!A!W`0S9QKQy;}1Cl^CgaH=;G9cpY;r$Q>i*pfB zP2drbID<_#qf;rPZx^FqH)F_D#*k@@q03KywUtLX8Ua?`H+NMzkczFPK3lFz@i_kW%1NOn0|D2I9n9wzH8m|-tHjsw|9>@K=iMBhxvkv6m8Y-l zytQ?X=U+MF$@3 zt`~i=@j|6y)RWMK--}M|=T`o&^Ni>IoWKHEbBXz7?A@mgWoL>!*SXo`SZH-*HSdS+ yn*9;$7;m`l>wYBC5bq;=U}IMqLzqbYCidGC!)_gkIk_C@Uj?jGCvSjw8cV1T7YilnjPW)2%eb4Pl^KShMoqTy! z%iEJx>MxyCC*1Sc6*PIvt(LnJzibeS+$?cD$9|=1aPA>HPpfe5IeTT~bLOuH@&EOF zIFnTzm?NJpy=C41>uPH%AB2D37|XjntI1@Vm!>mEwcg9AOWr%r-2S&{#m-;nj8zlu zRda9F-4^#cd)(jihU)G0*=@Ei+cY_EZ`fZ%cn(;H^2Go$deavd^wn zSI&pD)Nb9o)BlD5_l%#K^*8J+SFOFZ@AH=kRi&IBZO+8ES9YpyGoID^VA_uPqP*Gr ztNM}-=XqACy_~(oc#@pQu3LRxCOIu_w$n-ufBP?*qWN^klJDMs*xEM;w#?o3xAI`+ z`?vqz)_I>6Fl*WnyluZiPAB^TBj;-yUR0>O{MHnm^f~H~tJJohr8^C?1+L9`yK9NK zj+ND^NRt}hLt(zBjB{GjZ>-uh>#;!FhIiM`2mX0jpA#pXk z#RHGHt9A@NnyqIAbf-t>p03&^-O8El96w`2TD@^}8vn$wtGXLco?Q0juy)wo4F{)J q2+tNsOmq^YY5KvDEXCB`=)cf)s9Dr-!x)%_7(8A5T-G@yGywo%%7zyJ literal 0 HcmV?d00001 diff --git a/app/android/app/src/main/res/mipmap-mdpi/ic_launcher_monochrome.png b/app/android/app/src/main/res/mipmap-mdpi/ic_launcher_monochrome.png new file mode 100644 index 0000000000000000000000000000000000000000..763f06455a057ddc838395d165b7d0ef4e534066 GIT binary patch literal 854 zcmeAS@N?(olHy`uVBq!ia0vp^IUvlz1|<8_!p{OJ#^NA%Cx&(BWL`2bFbjCPIEGZj zy`8`m6)#Hv@VodowRHTr;rUL@ zylCg=()WMnot&96`)>KY%A#|>-&mKIr?K~IFj)s?@^&9OB-VIHM9fV=XB}^Fghb

i7ba6-7;ux73Ap7K1>tI=#7c(4cP~DAE@N~U3&Qbf!%vwzhmleke@myO!(S~ zD&9GoOfOXnHcr}-btsSNd)J9u{e_Yh5vswaiSHYOLm%iA?P2u`KN;eCV?F1$HKls9 zY~LQ(<#_v7rD-DXoGy1sztkojonFN^oF8O<7%lplu6)ikW0fW6Z@xLVe^;4yczm4v zT;+|;hea0e4}N^6@`mF>slmiY!e?9~lvfFEtBH}A`PYBJPX*hThT@6y8y443lzGgS zR(UG_z(dbm(Z6Rdw|5@;6(Id^&c3w)H#k20_F1^W^va#XxAe8YZxCIx?c#>l2a+Ec z7clMMj>&rHn<>%@D&nP5hYS1K;ld2Q_n;5|20XYp<)WeqUXFZHo_3fi+uANJKa9 zf~OOF-zR==l-90OHS1TMvo%pySC{wpmJQE>!W)*~D=C@2`BhIY$LrZwY;&4y*Q{Uj z%%)Xy&F^0y^=04AylEhPt#0d^{yE-<|FEZ(e_uT3;&;7`J9qSR^ekF%TgAEMr+}aN zwZ%PhN@tGWaSObVJ4x}-xAjk&m)xDfFJ;@d!IAM_VbRRln~faB7Su>4oh@3ecIJBT zp_ZRc@iPqKXYvYPJMwkum;WBCx3%X!;>!;!*3$7=J^)E4`|zQbzl_@VdvZVVTZ#iS O3WKMspUXO@geCx~;(s9k literal 0 HcmV?d00001 diff --git a/app/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png index 09d4391482be68e9e4a07fab769b5de337d16eb1..8a5adc6318164c8da157c45cb6ec32ed9b4c08c7 100644 GIT binary patch literal 5825 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 diff --git a/app/android/app/src/main/res/mipmap-xhdpi/ic_launcher_background.png b/app/android/app/src/main/res/mipmap-xhdpi/ic_launcher_background.png new file mode 100644 index 0000000000000000000000000000000000000000..afd4662cb424dd65efe5e3d3da322f8dce7e2e1d GIT binary patch literal 1321 zcmeAS@N?(olHy`uVBq!ia0vp^H$a$!4M=t>=)MI~jKx9jP7LeL$-HD>V0rB6;uum9 z_x7?QFN1;ri=jZ9;*`fsLN;gCt0%~xJ$vW%orfF(9xTfa2!$_Z+1GHuhN&^YAwh9n zCKJ&L#?~FnI62Pn3vjTqh&`I6reI+2pdca;(UCo?;lLk;QN^R7F`70;bIJe~ c1s@ph6=)py)VR(JEc+NdUHx3vIVCg!0Cm)&761SM literal 0 HcmV?d00001 diff --git a/app/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png b/app/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..f1639fbba98243c4d02488e878c72a319f1c7a86 GIT binary patch literal 2560 zcmeH}`B#%?7RQqqLWrdVkVSz*kWCtqr5zR#35&rH7PXZ{2)u_DK?#i-3lti{%Zy`C zL=B44K%fNfDEp5g9%!!{xY2?hu`N%r0NhyS_lGP8ajNhie}^9L|$5WlZg4I%`D7Qi|4JA5n_5GpUsiUB!4( zRk$R@ndy$gawL{0G)@oOfWKF5OmIJo0E3Vy;^VnAG`46jsp>?&1b5MQ9}@K?27h1= zK@gNsOwO0wNB-6Fzaw_gXIEn@(Shcy(&vgDRc9$N7@=n40hK#by4Fxr=fFx6sW&PP z7b~Iw;x|)+Xq#pwMLSV zbxpZi;e0s#WFKCB0oWRAF}=R=_4srdwXOLVzr3s{C%9G@_=fXa+t5Lq=XyBsMt@qi z3%K&h%bx*N30BxE&YAt;Ck4UpQv6hdYg);SKabEAj->qhI`pt@nvB%;zQ+H}D zK{FiOY*uU$Ws~+?zP#PNEnkAAuYmsNHvfz@g0}r`2`O*bPtIR+gQxW9 zo9AR_$NkVMOZvBNbI&&`(LX~6-X=Z<3(rV+ECc$FkZbX!k3d&%L6Uqs@3K!e$MWtz zVX>stO0L*it<8Xlo+gd0+jTg8QG;Q_3t!6-sX1ibppmEW5+)m&w$RQ9nuA^_9v4MISW$sWf~gWI~0mgZ8Mvo_vaf~!J`_d&P%kT zl~*}OLK1p{A4B4j&WWs7W2x8X5~QVUJzjETFJB5Hm%nKOzO?rp$l1Z{7Zzxx{V)9C zN3eEl0$`}<=mR9!_#`GsvGmkkv%7RSDE0nE+RPIVLPu><`-dB9M$}fse5cv~FYiRn z2LB-(4|>ua4y@u9f1lAXXi0A?=KpBK?j#q4^L}lWGXtM3-;6v&0#v-ck%8*@mR4Cn%)-D)o=l|Us_SLB>sK|tM#fid_lw5@B*i}%7?eL`<)+OIm>a{& z4!FBkeRn8WyL9yICOvbNyS@|jUhHyP_NQ3dB$A-trd$*j_pHOTVvi$_K$@NE8%om9 z%cifCySYokX$W&PsnV1n2qq^(C7~NUMwF+oKCWEIGWF{0zs(0_ljkUIrW24c|K8=v zOo-zk#=!d1BUiU(w$_Y0O!qQ9-@Q(7ljjjg!VO2Xxiu&|!;Z|XsId(@Y_B3yoC_3L ztT?C)fR0b5I{G`Rg89rIaV^@MnQVq~L87QFEe7Cy1lUs^dxaF1FF8f02N9e|fQNIm z-7OP>V2>3K&oRKq4i=uq)}XNmdwQMF$*8~D|3A=uhiRNESU*vI0tJ8R5R_w)Ax%L* G!G8dKUN(~e literal 0 HcmV?d00001 diff --git a/app/android/app/src/main/res/mipmap-xhdpi/ic_launcher_monochrome.png b/app/android/app/src/main/res/mipmap-xhdpi/ic_launcher_monochrome.png new file mode 100644 index 0000000000000000000000000000000000000000..9435f51e921833d24ab727fa14a46e7f9d2cb448 GIT binary patch literal 2559 zcmeHJ>pPp-77t!dVvb7c)}aU@K}S#BN-=S%DJh~;Eygu%QMXia1a*q0Q>CS?WJ=n! zL-mpt6LGJ;72a{_$*D5!kVG`DDJ6}x(V9mE6a8}jf%EOmhrQSH{GPqm+H3vRUTc>g zBKqrS8*9U0FdagG-(i&$ZY{W$YA;3G%Tz)w>#)Bsj6Jk-0R}^K68wCQa8i^iW3M;PPfCwe2a1up0FrTFsyKO9)DAVk zcaMcP$x@9P{9|e|0LN;;gD~El($n_kFen~&t`vapMX~Rr(2T#M_f)_j?5}Ok>Hu90 zz-~ti{T^2yC?Yu)_4ug+Ot|0`92umAWCRqE^rjYV+Wp$fWIzTCoCPz4DDKfxNGxg$p_3;Or8y|g|Lw~;_=zb)DudniK~>HBup^k z<%6+7it`xxqdVg{qZ7S{_pRmN@|=0(>ocaKN(;h?-ls4GWnXg?U0E7^`P$9+ z95zvW#TefHujX+VLE})h;gZev`i{?H%pV{YWSBse%m4JJ;bO9~FQf|M8;Odbj?9ai zKoou3bhW@>Mp93z?EnEVCjFnY;<}hgs4u^vGh;b5_fG&bv9f z`}p$S-(zuL!i3@(=m=E~-!?idcoSKe15c_yDTW6-4{xp&NyDeX@jO3IV%*m<)tad<&NOVNi;!#h7`snj9{TbQE zy6*J=RuQgF;i!0OcF6M#gWOARZD-2*Zj!JOuHo1SqnF3kAUHo*7kW|x=kJ%;*0M^v z%F2|l0Vn85=e{6gKL{aAsHT44Gr| z5~>ECs8dl5Ohzb!MAnrP6?X$E<4b4x6aAZ&yDQFo@$=jk&gVvL28wTE8xJbhG>DEW z4HNK$QG*zi>JUVN$Z#|BK*jZg$LuP)B*o#u?vFSS{HULyS^Me!1g~lEolrAh zsoZ$AX){oJ_NWhd%A>D$E6{!J6iB4y^}TYK1U^&9l}s+PbW{^7Tp)7VTUOd1c3@Zg zt$FW#ms7}#I)Dcm5-o`^r_3d3jagkEGva7+^V69zQIny5At`kEh-s{g)I66;(kTGfTZeK$;LQna45^{1-36a14|8*&$+zb`Xag%#mYO zdnhy00qm-+LSry%;?iqf`5_!KVr67(z9SZFDs#IfMSH6N{*^f^0+(Vse?(fWD)W45 zn=K`rHox~Ly^D^j);q4(VEQtI{?wlL)%p3O;|EknnAEnrXTITqG|#4r2DdUbbzq!L z5?pzgMd03$EMSIlc^OllshyT8oJ$JVFCXm=tK99ar45BKTYp1uy}tYPx%DG;8m}W9 zAb7hS4T!q1OI1~MeXVOL;?}wo-TmdG_G{t|#nAfb4~fgnWfLJUxY|3PFg;N)wqd90 z07Ko^BrR)~`+mD(9-x>yG+*k9N?QdcGgi1gI6Z-(>EA@sOxYZ2_}1fH`^T+>j_oFN zr6Z47{O={!LjFnDs$BVM&XoM5p#S#vcbSJ|LsqgE9UTUFOTRRTlh%j2$Y)*@Ao#58 z9GX92#jECKba^oN9qpOA8g;ZbBb8Q->wM-i);;;v*w2RC#^O_xM}hk4O-e8&pB94a z^x{crucOnw7XP#29u8W|tO#ZY6%DCu(JCgQoNfnfWf{)I0x1AIZ1$e^ISX~bh{Q&R04yFImx~?s!`}dtV8aw^yXNk-9$b_q5o3jWk M_>Snu_9apO1eOI)E&u=k literal 0 HcmV?d00001 diff --git a/app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png index d5f1c8d34e7a88e3f88bea192c3a370d44689c3c..1670d8f2c36b57122af91d732de44c1f2d76ee93 100644 GIT binary patch literal 10108 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 literal 1031 zcmeAS@N?(olHy`uVBq!ia0vp^6F``Q8Ax83A=Cw=BuiW)N`mv#O3D+9QW+dm@{>{( zJaZG%Q-e|yQz{EjrrIztFa`(sgt!6~Yi|1%a`XoT0ojZ}lNrNjb9xjc(B0U1_% zz5^97Xt*%oq$rQy4?0GKNfJ44uvxI)gC`h-NZ|&0-7(qS@?b!5r36oQ}zyZrNO3 zMO=Or+<~>+A&uN&E!^Sl+>xE!QC-|oJv`ApDhqC^EWD|@=#J`=d#Xzxs4ah}w&Jnc z$|q_opQ^2TrnVZ0o~wh<3t%W&flvYGe#$xqda2bR_R zvPYgMcHgjZ5nSA^lJr%;<&0do;O^tDDh~=pIxA#coaCY>&N%M2^tq^U%3DB@ynvKo}b?yu-bFc-u0JHzced$sg7S3zqI(2 z#Km{dPr7I=pQ5>FuK#)QwK?Y`E`B?nP+}U)I#c1+FM*1kNvWG|a(TpksZQ3B@sD~b zpQ2)*V*TdwjFOtHvV|;OsiDqHi=6%)o4b!)x$)%9pGTsE z-JL={-Ffv+T87W(Xpooq<`r*VzWQcgBN$$`u}f>-ZQI1BB8ykN*=e4rIsJx9>z}*o zo~|9I;xof diff --git a/app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_background.png b/app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_background.png new file mode 100644 index 0000000000000000000000000000000000000000..6be412a2aae5adbb76056dc62708cb9323744c9a GIT binary patch literal 2953 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 literal 1443 zcmb`G{WsKk6vsdJTdFg%tJav9_E4vzrOaqkWF|A724Nly!y+?N9`YV6wZ}5(X(D_N(?!*n3`|_r0Hc?=PQw&*vnU?QTFY zB_MsH|!j$PP;I}?dppoE_gA(4uc!jV&0!l7_;&p2^pxNo>PEcNJv za5_RT$o2Mf!<+r?&EbHH6nMoTsDOa;mN(wv8RNsHpG)`^ymG-S5By8=l9iVXzN_eG%Xg2@Xeq76tTZ*dGh~Lo9vl;Zfs+W#BydUw zCkZ$o1LqWQO$FC9aKlLl*7x9^0q%0}$OMlp@Kk_jHXOjofdePND+j!A{q!8~Jn+s3 z?~~w@4?egS02}8NuulUA=L~QQfm;MzCGd)XhiftT;+zFO&JVyp2mBww?;QByS_1w! zrQlx%{^cMj0|Bo1FjwY@Q8?Hx0cIPF*@-ZRFpPc#bBw{5@tD(5%sClzIfl8WU~V#u zm5Q;_F!wa$BSpqhN>W@2De?TKWR*!ujY;Yylk_X5#~V!L*Gw~;$%4Q8~Mad z@`-kG?yb$a9cHIApZDVZ^U6Xkp<*4rU82O7%}0jjHlK{id@?-wpN*fCHXyXh(bLt* zPc}H-x0e4E&nQ>y%B-(EL=9}RyC%MyX=upHuFhAk&MLbsF0LP-q`XnH78@fT+pKPW zu72MW`|?8ht^tz$iC}ZwLp4tB;Q49K!QCF3@!iB1qOI=?w z7In!}F~ij(18UYUjnbmC!qKhPo%24?8U1x{7o(+?^Zu0Hx81|FuS?bJ0jgBhEMzf< zCgUq7r2OCB(`XkKcN-TL>u5y#dD6D!)5W?`O5)V^>jb)P)GBdy%t$uUMpf$SNV31$ zb||OojAbvMP?T@$h_ZiFLFVHDmbyMhJF|-_)HX3%m=CDI+ID$0^C>kzxprBW)hw(v zr!Gmda);ICoQyhV_oP5+C%?jcG8v+D@9f?Dk*!BxY}dazmrT@64UrP3hlslANK)bq z$67n83eh}OeW&SV@HG95P|bjfqJ7gw$e+`Hxo!4cx`jdK1bJ>YDSpGKLPZ^1cv$ek zIB?0S<#tX?SJCLWdMd{-ME?$hc7A$zBOdIJ)4!KcAwb=VMov)nK;9z>x~rfT1>dS+ zZ6#`2v@`jgbqq)P22H)Tx2CpmM^o1$B+xT6`(v%5xJ(?j#>Q$+rx_R|7TzDZe{J6q zG1*EcU%tE?!kO%^M;3aM6JN*LAKUVb^xz8-Pxo#jR5(-KBeLJvA@-gxNHx0M-ZJLl z;#JwQoh~9V?`UVo#}{6ka@II>++D@%KqGpMdlQ}?9E*wFcf5(#XQnP$Dk5~%iX^>f z%$y;?M0BLp{O3a(-4A?ewryHrrD%cx#Q^%KY1H zNre$ve+vceSLZcNY4U(RBX&)oZn*Py()h)XkE?PL$!bNb{N5FVI2Y%LKEm%yvpyTP z(1P?z~7YxD~Rf<(a@_y` diff --git a/app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_background.png b/app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_background.png new file mode 100644 index 0000000000000000000000000000000000000000..eddfa1ecd07a14ffda54db37b2f6eaf7c20e155b GIT binary patch literal 4236 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 literal 0 HcmV?d00001 diff --git a/app/lib/db/database.dart b/app/lib/db/database.dart index 6253c02..0871a08 100644 --- a/app/lib/db/database.dart +++ b/app/lib/db/database.dart @@ -1,6 +1,14 @@ -import 'package:app/db/db.dart'; +import 'dart:async'; +import 'dart:typed_data'; +import 'package:floor/floor.dart'; +import 'package:sqflite/sqflite.dart' as sqflite; -late final AppDatabase database; -void initDb() { - database = AppDatabase(); +import 'pass_entry_dao.dart'; +import 'pass_entry.dart'; + +part 'database.g.dart'; + +@Database(version: 1, entities: [PassEntry]) +abstract class AppDatabase extends FloorDatabase { + PassEntryDao get passEntryDao; } diff --git a/app/lib/db/database.g.dart b/app/lib/db/database.g.dart new file mode 100644 index 0000000..e059dd8 --- /dev/null +++ b/app/lib/db/database.g.dart @@ -0,0 +1,170 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'database.dart'; + +// ************************************************************************** +// FloorGenerator +// ************************************************************************** + +abstract class $AppDatabaseBuilderContract { + /// Adds migrations to the builder. + $AppDatabaseBuilderContract addMigrations(List migrations); + + /// Adds a database [Callback] to the builder. + $AppDatabaseBuilderContract addCallback(Callback callback); + + /// Creates the database and initializes it. + Future build(); +} + +// ignore: avoid_classes_with_only_static_members +class $FloorAppDatabase { + /// Creates a database builder for a persistent database. + /// Once a database is built, you should keep a reference to it and re-use it. + static $AppDatabaseBuilderContract databaseBuilder(String name) => + _$AppDatabaseBuilder(name); + + /// Creates a database builder for an in memory database. + /// Information stored in an in memory database disappears when the process is killed. + /// Once a database is built, you should keep a reference to it and re-use it. + static $AppDatabaseBuilderContract inMemoryDatabaseBuilder() => + _$AppDatabaseBuilder(null); +} + +class _$AppDatabaseBuilder implements $AppDatabaseBuilderContract { + _$AppDatabaseBuilder(this.name); + + final String? name; + + final List _migrations = []; + + Callback? _callback; + + @override + $AppDatabaseBuilderContract addMigrations(List migrations) { + _migrations.addAll(migrations); + return this; + } + + @override + $AppDatabaseBuilderContract addCallback(Callback callback) { + _callback = callback; + return this; + } + + @override + Future build() async { + final path = name != null + ? await sqfliteDatabaseFactory.getDatabasePath(name!) + : ':memory:'; + final database = _$AppDatabase(); + database.database = await database.open( + path, + _migrations, + _callback, + ); + return database; + } +} + +class _$AppDatabase extends AppDatabase { + _$AppDatabase([StreamController? listener]) { + changeListener = listener ?? StreamController.broadcast(); + } + + PassEntryDao? _passEntryDaoInstance; + + Future open( + String path, + List migrations, [ + Callback? callback, + ]) async { + final databaseOptions = sqflite.OpenDatabaseOptions( + version: 1, + onConfigure: (database) async { + await database.execute('PRAGMA foreign_keys = ON'); + await callback?.onConfigure?.call(database); + }, + onOpen: (database) async { + await callback?.onOpen?.call(database); + }, + onUpgrade: (database, startVersion, endVersion) async { + await MigrationAdapter.runMigrations( + database, startVersion, endVersion, migrations); + + await callback?.onUpgrade?.call(database, startVersion, endVersion); + }, + onCreate: (database, version) async { + await database.execute( + 'CREATE TABLE IF NOT EXISTS `PassEntry` (`id` TEXT NOT NULL, `description` TEXT NOT NULL, `pass` BLOB NOT NULL, PRIMARY KEY (`id`))'); + + await callback?.onCreate?.call(database, version); + }, + ); + return sqfliteDatabaseFactory.openDatabase(path, options: databaseOptions); + } + + @override + PassEntryDao get passEntryDao { + return _passEntryDaoInstance ??= _$PassEntryDao(database, changeListener); + } +} + +class _$PassEntryDao extends PassEntryDao { + _$PassEntryDao( + this.database, + this.changeListener, + ) : _queryAdapter = QueryAdapter(database), + _passEntryInsertionAdapter = InsertionAdapter( + database, + 'PassEntry', + (PassEntry item) => { + 'id': item.id, + 'description': item.description, + 'pass': item.pass + }), + _passEntryUpdateAdapter = UpdateAdapter( + database, + 'PassEntry', + ['id'], + (PassEntry item) => { + 'id': item.id, + 'description': item.description, + 'pass': item.pass + }); + + final sqflite.DatabaseExecutor database; + + final StreamController changeListener; + + final QueryAdapter _queryAdapter; + + final InsertionAdapter _passEntryInsertionAdapter; + + final UpdateAdapter _passEntryUpdateAdapter; + + @override + Future> findAll() async { + return _queryAdapter.queryList('SELECT * FROM PassEntry', + mapper: (Map row) => PassEntry( + id: row['id'] as String, + description: row['description'] as String, + pass: row['pass'] as Uint8List)); + } + + @override + Future deletePassEntry(String serial) async { + await _queryAdapter.queryNoReturn('DELETE FROM PassEntry WHERE id = ?1', + arguments: [serial]); + } + + @override + Future insertPassEntry(PassEntry entry) async { + await _passEntryInsertionAdapter.insert(entry, OnConflictStrategy.abort); + } + + @override + Future updatePassEntry(PassEntry entry) async { + await _passEntryUpdateAdapter.update(entry, OnConflictStrategy.replace); + } +} diff --git a/app/lib/db/db.dart b/app/lib/db/db.dart index 5c4b466..793581f 100644 --- a/app/lib/db/db.dart +++ b/app/lib/db/db.dart @@ -1,35 +1,7 @@ -import 'dart:io'; +import 'package:app/db/database.dart'; -import 'package:drift/drift.dart'; -import 'package:drift/native.dart'; -import 'package:path_provider/path_provider.dart'; -import 'package:path/path.dart' as p; +late final AppDatabase db; -part 'db.g.dart'; - -class Pass extends Table { - TextColumn get id => text()(); - BlobColumn get binaryPass => blob()(); - - @override - Set get primaryKey => {id}; -} - -@DriftDatabase(tables: [Pass]) -class AppDatabase extends _$AppDatabase { - AppDatabase() : super(_openConnection()); - - @override - int get schemaVersion => 1; -} - -LazyDatabase _openConnection() { - // the LazyDatabase util lets us find the right location for the file async. - return LazyDatabase(() async { - // put the database file, called db.sqlite here, into the documents folder - // for your app. - final dbFolder = await getApplicationDocumentsDirectory(); - final file = File(p.join(dbFolder.path, 'db.sqlite')); - return NativeDatabase.createInBackground(file); - }); +Future initDb() async { + db = await $FloorAppDatabase.databaseBuilder('app_database.db').build(); } diff --git a/app/lib/db/db.g.dart b/app/lib/db/db.g.dart deleted file mode 100644 index eaf781b..0000000 --- a/app/lib/db/db.g.dart +++ /dev/null @@ -1,197 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'db.dart'; - -// ignore_for_file: type=lint -class $PassTable extends Pass with TableInfo<$PassTable, Pas> { - @override - final GeneratedDatabase attachedDatabase; - final String? _alias; - $PassTable(this.attachedDatabase, [this._alias]); - static const VerificationMeta _idMeta = const VerificationMeta('id'); - @override - late final GeneratedColumn id = GeneratedColumn( - 'id', aliasedName, false, - type: DriftSqlType.string, requiredDuringInsert: true); - static const VerificationMeta _binaryPassMeta = - const VerificationMeta('binaryPass'); - @override - late final GeneratedColumn binaryPass = GeneratedColumn( - 'binary_pass', aliasedName, false, - type: DriftSqlType.blob, requiredDuringInsert: true); - @override - List get $columns => [id, binaryPass]; - @override - String get aliasedName => _alias ?? 'pass'; - @override - String get actualTableName => 'pass'; - @override - VerificationContext validateIntegrity(Insertable instance, - {bool isInserting = false}) { - final context = VerificationContext(); - final data = instance.toColumns(true); - if (data.containsKey('id')) { - context.handle(_idMeta, id.isAcceptableOrUnknown(data['id']!, _idMeta)); - } else if (isInserting) { - context.missing(_idMeta); - } - if (data.containsKey('binary_pass')) { - context.handle( - _binaryPassMeta, - binaryPass.isAcceptableOrUnknown( - data['binary_pass']!, _binaryPassMeta)); - } else if (isInserting) { - context.missing(_binaryPassMeta); - } - return context; - } - - @override - Set get $primaryKey => {id}; - @override - Pas map(Map data, {String? tablePrefix}) { - final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; - return Pas( - id: attachedDatabase.typeMapping - .read(DriftSqlType.string, data['${effectivePrefix}id'])!, - binaryPass: attachedDatabase.typeMapping - .read(DriftSqlType.blob, data['${effectivePrefix}binary_pass'])!, - ); - } - - @override - $PassTable createAlias(String alias) { - return $PassTable(attachedDatabase, alias); - } -} - -class Pas extends DataClass implements Insertable { - final String id; - final Uint8List binaryPass; - const Pas({required this.id, required this.binaryPass}); - @override - Map toColumns(bool nullToAbsent) { - final map = {}; - map['id'] = Variable(id); - map['binary_pass'] = Variable(binaryPass); - return map; - } - - PassCompanion toCompanion(bool nullToAbsent) { - return PassCompanion( - id: Value(id), - binaryPass: Value(binaryPass), - ); - } - - factory Pas.fromJson(Map json, - {ValueSerializer? serializer}) { - serializer ??= driftRuntimeOptions.defaultSerializer; - return Pas( - id: serializer.fromJson(json['id']), - binaryPass: serializer.fromJson(json['binaryPass']), - ); - } - @override - Map toJson({ValueSerializer? serializer}) { - serializer ??= driftRuntimeOptions.defaultSerializer; - return { - 'id': serializer.toJson(id), - 'binaryPass': serializer.toJson(binaryPass), - }; - } - - Pas copyWith({String? id, Uint8List? binaryPass}) => Pas( - id: id ?? this.id, - binaryPass: binaryPass ?? this.binaryPass, - ); - @override - String toString() { - return (StringBuffer('Pas(') - ..write('id: $id, ') - ..write('binaryPass: $binaryPass') - ..write(')')) - .toString(); - } - - @override - int get hashCode => Object.hash(id, $driftBlobEquality.hash(binaryPass)); - @override - bool operator ==(Object other) => - identical(this, other) || - (other is Pas && - other.id == this.id && - $driftBlobEquality.equals(other.binaryPass, this.binaryPass)); -} - -class PassCompanion extends UpdateCompanion { - final Value id; - final Value binaryPass; - final Value rowid; - const PassCompanion({ - this.id = const Value.absent(), - this.binaryPass = const Value.absent(), - this.rowid = const Value.absent(), - }); - PassCompanion.insert({ - required String id, - required Uint8List binaryPass, - this.rowid = const Value.absent(), - }) : id = Value(id), - binaryPass = Value(binaryPass); - static Insertable custom({ - Expression? id, - Expression? binaryPass, - Expression? rowid, - }) { - return RawValuesInsertable({ - if (id != null) 'id': id, - if (binaryPass != null) 'binary_pass': binaryPass, - if (rowid != null) 'rowid': rowid, - }); - } - - PassCompanion copyWith( - {Value? id, Value? binaryPass, Value? rowid}) { - return PassCompanion( - id: id ?? this.id, - binaryPass: binaryPass ?? this.binaryPass, - rowid: rowid ?? this.rowid, - ); - } - - @override - Map toColumns(bool nullToAbsent) { - final map = {}; - if (id.present) { - map['id'] = Variable(id.value); - } - if (binaryPass.present) { - map['binary_pass'] = Variable(binaryPass.value); - } - if (rowid.present) { - map['rowid'] = Variable(rowid.value); - } - return map; - } - - @override - String toString() { - return (StringBuffer('PassCompanion(') - ..write('id: $id, ') - ..write('binaryPass: $binaryPass, ') - ..write('rowid: $rowid') - ..write(')')) - .toString(); - } -} - -abstract class _$AppDatabase extends GeneratedDatabase { - _$AppDatabase(QueryExecutor e) : super(e); - late final $PassTable pass = $PassTable(this); - @override - Iterable> get allTables => - allSchemaEntities.whereType>(); - @override - List get allSchemaEntities => [pass]; -} diff --git a/app/lib/db/pass_entry.dart b/app/lib/db/pass_entry.dart new file mode 100644 index 0000000..aa9682e --- /dev/null +++ b/app/lib/db/pass_entry.dart @@ -0,0 +1,19 @@ +import 'dart:typed_data'; + +import 'package:floor/floor.dart'; + +@entity +class PassEntry { + PassEntry({ + required this.id, + required this.description, + required this.pass, + }); + + @primaryKey + final String id; + + final String description; + + final Uint8List pass; +} diff --git a/app/lib/db/pass_entry_dao.dart b/app/lib/db/pass_entry_dao.dart new file mode 100644 index 0000000..e456bbc --- /dev/null +++ b/app/lib/db/pass_entry_dao.dart @@ -0,0 +1,17 @@ +import 'package:app/db/pass_entry.dart'; +import 'package:floor/floor.dart'; + +@dao +abstract class PassEntryDao { + @Query('SELECT * FROM PassEntry') + Future> findAll(); + + @insert + Future insertPassEntry(PassEntry entry); + + @Query('DELETE FROM PassEntry WHERE id = :serial') + Future deletePassEntry(String serial); + + @Update(onConflict: OnConflictStrategy.replace) + Future updatePassEntry(PassEntry entry); +} diff --git a/app/lib/home_page.dart b/app/lib/home/home_page.dart similarity index 52% rename from app/lib/home_page.dart rename to app/lib/home/home_page.dart index 22c9e1f..31b7972 100644 --- a/app/lib/home_page.dart +++ b/app/lib/home/home_page.dart @@ -1,4 +1,4 @@ -import 'package:app/db/database.dart'; +import 'package:app/home/pass_list_notifier.dart'; import 'package:app/import_pass/import_page.dart'; import 'package:app/import_pass/pick_pass.dart'; import 'package:app/pass_backside/pass_backside_page.dart'; @@ -6,11 +6,9 @@ import 'package:app/router.dart'; import 'package:app/widgets/app_icon.dart'; import 'package:app/widgets/pass_list_tile.dart'; import 'package:desktop_drop/desktop_drop.dart'; -import 'package:drift/drift.dart' as drift; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; -import 'package:passkit/passkit.dart'; import 'package:passkit_ui/passkit_ui.dart'; class HomePage extends StatefulWidget { @@ -21,28 +19,12 @@ class HomePage extends StatefulWidget { } class _HomePageState extends State { - List passes = []; - PassView passView = PassView.preview; @override void initState() { super.initState(); - loadPasses(); - } - - Future loadPasses() async { - final dbPasses = await database.pass.select(distinct: true).get(); - final mappedPasses = dbPasses.map((p) { - return PkPass.fromBytes( - p.binaryPass, - skipChecksumVerification: true, - skipSignatureVerification: true, - ); - }).toList(); - setState(() { - passes = mappedPasses; - }); + passListNotifier.loadPasses(); } @override @@ -85,54 +67,87 @@ class _HomePageState extends State { ), ], ), - body: Column( - children: [ - ViewChooser( - selected: passView, - onViewChanged: (newViewSelection) { - setState(() { - passView = newViewSelection; - }); - }, - ), - passes.isEmpty - ? const Center(child: Text('No passes')) - : Expanded( - child: RefreshIndicator( - onRefresh: () => loadPasses(), - child: ListView.builder( - padding: const EdgeInsets.fromLTRB(0, 50, 0, 0), - itemCount: passes.length, - itemBuilder: (context, index) { - final pass = passes[index]; - if (passView == PassView.compact) { - return PassListTile( - pass: pass, - onTap: () { - router.push( - '/backside', - extra: PassBackSidePageArgs(pass, true), + body: ListenableBuilder( + listenable: passListNotifier, + builder: (context, child) { + return Column( + children: [ + /* + ViewChooser( + selected: passView, + onViewChanged: (newViewSelection) { + setState(() { + passView = newViewSelection; + }); + }, + ), + */ + passListNotifier.passes?.isEmpty ?? true + ? const HomePageEmptyState() + : Expanded( + child: RefreshIndicator( + onRefresh: () => passListNotifier.loadPasses(), + child: ListView.builder( + padding: const EdgeInsets.fromLTRB(0, 25, 0, 25), + itemCount: passListNotifier.passes!.length, + itemBuilder: (context, index) { + final pass = passListNotifier.passes![index]; + if (passView == PassView.compact) { + return PassListTile( + pass: pass, + onTap: () { + router.push( + '/backside', + extra: PassBackSidePageArgs(pass, true), + ); + }, ); - }, - ); - } else { - return Padding( - padding: const EdgeInsets.all(16.0), - child: InkWell( - child: PkPassWidget(pass: pass), - onTap: () { - router.push( - '/backside', - extra: PassBackSidePageArgs(pass, true), - ); - }, - ), - ); - } - }, + } else { + return Padding( + padding: const EdgeInsets.all(16.0), + child: InkWell( + child: PkPassWidget(pass: pass), + onTap: () { + router.push( + '/backside', + extra: PassBackSidePageArgs(pass, true), + ); + }, + ), + ); + } + }, + ), + ), ), - ), - ), + ], + ); + }, + ), + ), + ); + } +} + +class HomePageEmptyState extends StatelessWidget { + const HomePageEmptyState({ + super.key, + }); + + @override + Widget build(BuildContext context) { + final translations = AppLocalizations.of(context); + return Expanded( + child: Center( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text(translations.noPassesToShow), + const SizedBox(height: 16), + ElevatedButton( + onPressed: () => pickPass(context), + child: Text(translations.import), + ), ], ), ), diff --git a/app/lib/home/pass_list_notifier.dart b/app/lib/home/pass_list_notifier.dart new file mode 100644 index 0000000..4c401b2 --- /dev/null +++ b/app/lib/home/pass_list_notifier.dart @@ -0,0 +1,21 @@ +import 'package:app/db/db.dart'; +import 'package:flutter/foundation.dart'; +import 'package:passkit/passkit.dart'; + +final passListNotifier = PassListNotifier(); + +class PassListNotifier extends ChangeNotifier { + List? passes; + + Future loadPasses() async { + final dbPasses = await db.passEntryDao.findAll(); + passes = dbPasses.map((p) { + return PkPass.fromBytes( + p.pass, + skipChecksumVerification: true, + skipSignatureVerification: true, + ); + }).toList(); + notifyListeners(); + } +} diff --git a/app/lib/import_pass/import_page.dart b/app/lib/import_pass/import_page.dart index 1e25139..4e385d1 100644 --- a/app/lib/import_pass/import_page.dart +++ b/app/lib/import_pass/import_page.dart @@ -1,7 +1,10 @@ +import 'dart:async'; +import 'dart:io'; import 'dart:typed_data'; -import 'package:app/db/database.dart'; import 'package:app/db/db.dart'; +import 'package:app/db/pass_entry.dart'; +import 'package:app/home/pass_list_notifier.dart'; import 'package:app/pass_backside/pass_backside_page.dart'; import 'package:app/router.dart'; import 'package:content_resolver/content_resolver.dart'; @@ -12,15 +15,19 @@ import 'package:passkit/passkit.dart'; import 'package:passkit_ui/passkit_ui.dart'; class PkPassImportSource { - PkPassImportSource({this.path, this.bytes}) - : assert(path != null || bytes != null); + PkPassImportSource({this.contentResolverPath, this.bytes, this.filePath}) + : assert( + contentResolverPath != null || bytes != null || filePath != null, + ); - final String? path; + final String? contentResolverPath; + final String? filePath; final List? bytes; Future getPass() async { - if (path != null) { - final Content content = await ContentResolver.resolveContent(path!); + if (contentResolverPath != null) { + final Content content = + await ContentResolver.resolveContent(contentResolverPath!); return PkPass.fromBytes( content.data, skipChecksumVerification: true, @@ -32,6 +39,12 @@ class PkPassImportSource { skipChecksumVerification: true, skipSignatureVerification: true, ); + } else if (filePath != null) { + return PkPass.fromBytes( + await File(filePath!).readAsBytes(), + skipChecksumVerification: true, + skipSignatureVerification: true, + ); } throw Exception('No data'); } @@ -73,7 +86,7 @@ class _ImportPassPageState extends State { Padding( padding: const EdgeInsets.all(16.0), child: InkWell( - child: PkPassWidget(pass: pass!), + child: Center(child: PkPassWidget(pass: pass!)), onTap: () { router.push( '/backside', @@ -85,12 +98,13 @@ class _ImportPassPageState extends State { // TODO(ueman): only offer this button if the pass isn't yet added ElevatedButton( onPressed: () async { - await database.into(database.pass).insert( - PassCompanion.insert( - id: pass!.pass.serialNumber, - binaryPass: Uint8List.fromList(pass!.sourceData), - ), - ); + await db.passEntryDao.insertPassEntry( + PassEntry( + id: pass!.pass.serialNumber, + pass: Uint8List.fromList(pass!.sourceData), + description: pass!.pass.description, + ), + ); if (context.mounted) { // If this page is opened via a file open intent, it can't be // popped via the navigator. Instead the button should be hidden. @@ -100,6 +114,7 @@ class _ImportPassPageState extends State { // TODO(ueman): hide the import button } } + unawaited(passListNotifier.loadPasses()); }, child: Text(AppLocalizations.of(context).importPass), ), diff --git a/app/lib/import_pass/pick_pass.dart b/app/lib/import_pass/pick_pass.dart index 8bcb35b..e685132 100644 --- a/app/lib/import_pass/pick_pass.dart +++ b/app/lib/import_pass/pick_pass.dart @@ -24,11 +24,11 @@ Future pickPass(BuildContext context) async { return; } - if ({'.pkpass', '.pass'}.contains(extension(firstPath))) { + if (!{'.pkpass', '.pass'}.contains(extension(firstPath))) { // This is probably not a valid PkPass // TOOD show a hint to the user, that the user picked an ivalid file return; } - await router.push('/import', extra: PkPassImportSource(path: firstPath)); + await router.push('/import', extra: PkPassImportSource(filePath: firstPath)); } diff --git a/app/lib/import_pass/receive_pass.dart b/app/lib/import_pass/receive_pass.dart index c5ad1e1..66dd07b 100644 --- a/app/lib/import_pass/receive_pass.dart +++ b/app/lib/import_pass/receive_pass.dart @@ -47,5 +47,10 @@ Future _onIntent(Intent? receivedIntent) async { // TODO(ueman): show error popup? return; } - unawaited(router.push('/import', extra: PkPassImportSource(path: path))); + unawaited( + router.push( + '/import', + extra: PkPassImportSource(contentResolverPath: path), + ), + ); } diff --git a/app/lib/l10n/app_en.arb b/app/lib/l10n/app_en.arb index a9bafa4..139b0c1 100644 --- a/app/lib/l10n/app_en.arb +++ b/app/lib/l10n/app_en.arb @@ -1,7 +1,7 @@ { "appName": "Cards", - "import": "Import new card", - "importPass": "Import this card", + "import": "Import new pass", + "importPass": "Import this pass", "pickPasses": "Pick passes", "associatediOSApps": "Associated iOS Apps", "associatediOSAppsDisclaimer": "Due to limitations of the Pass files, it's only possible to show iOS apps.", @@ -16,5 +16,8 @@ } }, "settings": "Settings", - "overrideShareProhibitedFlag": "Share passes even if they disallow it" + "overrideShareProhibitedFlag": "Share passes even if they disallow it", + "reportIssue": "Report a bug", + "noPassesToShow": "You haven't added any passes yet.", + "updateButton": "Update" } \ No newline at end of file diff --git a/app/lib/main.dart b/app/lib/main.dart index 459fe1a..72c138a 100644 --- a/app/lib/main.dart +++ b/app/lib/main.dart @@ -1,6 +1,6 @@ import 'dart:io'; -import 'package:app/db/database.dart'; +import 'package:app/db/db.dart'; import 'package:app/db/preferences.dart'; import 'package:app/import_pass/receive_pass.dart'; import 'package:app/main_app.dart'; @@ -12,7 +12,7 @@ Future main() async { if (Platform.isAndroid) { await FlutterDisplayMode.setHighRefreshRate(); } - initDb(); + await initDb(); await AppPreferences().init(); runApp(const MainApp()); if (Platform.isAndroid) { diff --git a/app/lib/main_app.dart b/app/lib/main_app.dart index 7c16e81..c0af653 100644 --- a/app/lib/main_app.dart +++ b/app/lib/main_app.dart @@ -10,6 +10,7 @@ class MainApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp.router( + debugShowCheckedModeBanner: false, routerConfig: router, scaffoldMessengerKey: scaffoldMessenger, theme: _lightTheme(), diff --git a/app/lib/pass_backside/pass_backside_page.dart b/app/lib/pass_backside/pass_backside_page.dart index 043f90c..880ddc0 100644 --- a/app/lib/pass_backside/pass_backside_page.dart +++ b/app/lib/pass_backside/pass_backside_page.dart @@ -1,7 +1,11 @@ +import 'dart:async'; import 'dart:developer'; import 'dart:io'; import 'dart:typed_data'; +import 'package:app/db/db.dart'; +import 'package:app/db/pass_entry.dart'; +import 'package:app/home/pass_list_notifier.dart'; import 'package:app/pass_backside/app_metadata_tile.dart'; import 'package:app/pass_backside/placemark_tile.dart'; import 'package:app/web_service/app_meta_data_client.dart'; @@ -185,14 +189,46 @@ class _PassBacksidePageState extends State { MaterialLocalizations.of(context).deleteButtonTooltip, style: const TextStyle(color: Colors.red), ), - onTap: () {}, + onTap: delete, ), ], + if (widget.pass.isWebServiceAvailable) + ListTile( + title: Text( + AppLocalizations.of(context).updateButton, + style: const TextStyle(color: Colors.green), + ), + onTap: update, + ), ], ), ); } + Future delete() async { + await db.passEntryDao.deletePassEntry(widget.pass.pass.serialNumber); + if (mounted) { + await Navigator.maybePop(context); + } + unawaited(passListNotifier.loadPasses()); + } + + Future update() async { + final updatedPass = await PassKitWebClient().getLatestVersion(widget.pass); + if (updatedPass == null) { + return; + } + await db.passEntryDao.updatePassEntry( + PassEntry( + id: updatedPass.pass.serialNumber, + description: updatedPass.pass.description, + pass: Uint8List.fromList(updatedPass.sourceData), + ), + ); + + unawaited(passListNotifier.loadPasses()); + } + void _sharePass() { final data = Uint8List.fromList(widget.pass.sourceData); Share.shareXFiles([XFile.fromData(data)]); diff --git a/app/lib/router.dart b/app/lib/router.dart index 4f55f25..8053c24 100644 --- a/app/lib/router.dart +++ b/app/lib/router.dart @@ -1,5 +1,5 @@ import 'package:app/example/example_passes.dart'; -import 'package:app/home_page.dart'; +import 'package:app/home/home_page.dart'; import 'package:app/import_pass/import_page.dart'; import 'package:app/pass_backside/pass_backside_page.dart'; import 'package:app/settings/settings_page.dart'; diff --git a/app/lib/settings/settings_page.dart b/app/lib/settings/settings_page.dart index 8f800c9..140e211 100644 --- a/app/lib/settings/settings_page.dart +++ b/app/lib/settings/settings_page.dart @@ -1,7 +1,9 @@ import 'package:app/db/preferences.dart'; +import 'package:app/widgets/app_version.dart'; import 'package:app/widgets/show_about_dialog.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:url_launcher/url_launcher.dart'; class SettingsPage extends StatefulWidget { const SettingsPage({super.key}); @@ -37,6 +39,25 @@ class _SettingsPageState extends State { setState(() {}); }, ), + ListTile( + title: Text(AppLocalizations.of(context).reportIssue), + leading: const Icon(Icons.bug_report), + onTap: () { + final bugReportUrl = Uri.parse( + 'https://github.com/ueman/passkit/issues/new?template=app_bug_report.yaml', + ); + launchUrl(bugReportUrl); + }, + ), + ListTile( + title: Text( + MaterialLocalizations.of(context) + .aboutListTileTitle(AppLocalizations.of(context).appName), + ), + subtitle: const AppVersion(), + leading: const Icon(Icons.info), + onTap: () => showAboutWalletApp(context), + ), ], ), ); diff --git a/app/macos/Flutter/GeneratedPluginRegistrant.swift b/app/macos/Flutter/GeneratedPluginRegistrant.swift index f211274..78136a1 100644 --- a/app/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/app/macos/Flutter/GeneratedPluginRegistrant.swift @@ -13,6 +13,7 @@ import path_provider_foundation import screen_brightness_macos import share_plus import shared_preferences_foundation +import sqflite import sqlite3_flutter_libs import url_launcher_macos import wakelock_plus @@ -26,6 +27,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { ScreenBrightnessMacosPlugin.register(with: registry.registrar(forPlugin: "ScreenBrightnessMacosPlugin")) SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) + SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin")) Sqlite3FlutterLibsPlugin.register(with: registry.registrar(forPlugin: "Sqlite3FlutterLibsPlugin")) UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) WakelockPlusMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockPlusMacosPlugin")) diff --git a/app/pubspec.lock b/app/pubspec.lock index 8d1fff6..1829083 100644 --- a/app/pubspec.lock +++ b/app/pubspec.lock @@ -5,34 +5,31 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: "0b2f2bd91ba804e53a61d757b986f89f1f9eaed5b11e4b2f5a2468d86d6c9fc7" + sha256: f256b0c0ba6c7577c15e2e4e114755640a875e885099367bf6e012b19314c834 url: "https://pub.dev" source: hosted - version: "67.0.0" + version: "72.0.0" + _macros: + dependency: transitive + description: dart + source: sdk + version: "0.3.2" analyzer: dependency: transitive description: name: analyzer - sha256: "37577842a27e4338429a1cbc32679d508836510b056f1eedf0c8d20e39c1383d" + sha256: b652861553cd3990d8ed361f7979dc6d7053a9ac8843fa73820ab68ce5410139 url: "https://pub.dev" source: hosted - version: "6.4.1" - analyzer_plugin: - dependency: transitive - description: - name: analyzer_plugin - sha256: "9661b30b13a685efaee9f02e5d01ed9f2b423bd889d28a304d02d704aee69161" - url: "https://pub.dev" - source: hosted - version: "0.11.3" + version: "6.7.0" android_intent_plus: dependency: "direct main" description: name: android_intent_plus - sha256: "2bfdbee8d65e7c26f88b66f0a91f2863da4d3596d8a658b4162c8de5cf04b074" + sha256: "007703c1b2cac7ca98add3336b98cffa4baa11d5133cc463293dba9daa39cdf6" url: "https://pub.dev" source: hosted - version: "5.0.2" + version: "5.1.0" archive: dependency: transitive description: @@ -117,18 +114,18 @@ packages: dependency: "direct dev" description: name: build_runner - sha256: "644dc98a0f179b872f612d3eb627924b578897c629788e858157fa5e704ca0c7" + sha256: dd09dd4e2b078992f42aac7f1a622f01882a8492fef08486b27ddde929c19f04 url: "https://pub.dev" source: hosted - version: "2.4.11" + version: "2.4.12" build_runner_core: dependency: transitive description: name: build_runner_core - sha256: e3c79f69a64bdfcd8a776a3c28db4eb6e3fb5356d013ae5eb2e52007706d5dbe + sha256: f8126682b87a7282a339b871298cc12009cb67109cfa1614d6436fb0289193e0 url: "https://pub.dev" source: hosted - version: "7.3.1" + version: "7.3.2" built_collection: dependency: transitive description: @@ -169,14 +166,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.3" - cli_util: - dependency: transitive - description: - name: cli_util - sha256: c05b7406fdabc7a49a3929d4af76bcaccbbffcbcdcf185b082e1ae07da323d19 - url: "https://pub.dev" - source: hosted - version: "0.4.1" clock: dependency: transitive description: @@ -221,18 +210,18 @@ packages: dependency: transitive description: name: cross_file - sha256: "55d7b444feb71301ef6b8838dbc1ae02e63dd48c8773f3810ff53bb1e2945b32" + sha256: "7caf6a750a0c04effbb52a676dce9a4a592e10ad35c34d6d2d0e4811160d5670" url: "https://pub.dev" source: hosted - version: "0.3.4+1" + version: "0.3.4+2" crypto: dependency: transitive description: name: crypto - sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab + sha256: ec30d999af904f33454ba22ed9a86162b35e52b44ac4807d1d93c288041d7d27 url: "https://pub.dev" source: hosted - version: "3.0.3" + version: "3.0.5" csslib: dependency: transitive description: @@ -265,22 +254,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.4.4" - drift: - dependency: "direct main" - description: - name: drift - sha256: "6acedc562ffeed308049f78fb1906abad3d65714580b6745441ee6d50ec564cd" - url: "https://pub.dev" - source: hosted - version: "2.18.0" - drift_dev: - dependency: "direct dev" + dev_build: + dependency: transitive description: - name: drift_dev - sha256: d9b020736ea85fff1568699ce18b89fabb3f0f042e8a7a05e84a3ec20d39acde + name: dev_build + sha256: f526d1fbe68875f6119ffc333f114dfe6aa93ad04439276d53968f7977cc410e url: "https://pub.dev" source: hosted - version: "2.18.0" + version: "1.0.0+11" fake_async: dependency: transitive description: @@ -293,10 +274,10 @@ packages: dependency: transitive description: name: ffi - sha256: "493f37e7df1804778ff3a53bd691d8692ddf69702cf4c1c1096a2e41b4779e21" + sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6" url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.1.3" file: dependency: transitive description: @@ -309,10 +290,10 @@ packages: dependency: "direct main" description: name: file_picker - sha256: "2ca051989f69d1b2ca012b2cf3ccf78c70d40144f0861ff2c063493f7c8c3d45" + sha256: "167bb619cdddaa10ef2907609feb8a79c16dfa479d3afaf960f8e223f754bf12" url: "https://pub.dev" source: hosted - version: "8.0.5" + version: "8.1.2" fixnum: dependency: transitive description: @@ -321,6 +302,38 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.0" + floor: + dependency: "direct main" + description: + name: floor + sha256: c1b06023912b5b8e49deb6a9d867863c535ae1a232d991c3582bba3ee8687867 + url: "https://pub.dev" + source: hosted + version: "1.5.0" + floor_annotation: + dependency: transitive + description: + name: floor_annotation + sha256: a40949580a7ab0eee572686e2d3b1638fd6bd6a753e661d792ab4236b365b23b + url: "https://pub.dev" + source: hosted + version: "1.5.0" + floor_common: + dependency: transitive + description: + name: floor_common + sha256: "41c9914862f83a821815e1b1ffd47a1e1ae2130c35ff882ba2d000a67713ba64" + url: "https://pub.dev" + source: hosted + version: "1.5.0" + floor_generator: + dependency: "direct dev" + description: + name: floor_generator + sha256: "1499b3ab878a807e6fbe6f140dc014124845cd1df3090a113aae5fa7577a1e77" + url: "https://pub.dev" + source: hosted + version: "1.5.0" flutter: dependency: "direct main" description: flutter @@ -354,26 +367,26 @@ packages: dependency: "direct main" description: name: flutter_local_notifications - sha256: "40e6fbd2da7dcc7ed78432c5cdab1559674b4af035fddbfb2f9a8f9c2112fcef" + sha256: c500d5d9e7e553f06b61877ca6b9c8b92c570a4c8db371038702e8ce57f8a50f url: "https://pub.dev" source: hosted - version: "17.1.2" + version: "17.2.2" flutter_local_notifications_linux: dependency: transitive description: name: flutter_local_notifications_linux - sha256: "33f741ef47b5f63cc7f78fe75eeeac7e19f171ff3c3df054d84c1e38bedb6a03" + sha256: c49bd06165cad9beeb79090b18cd1eb0296f4bf4b23b84426e37dd7c027fc3af url: "https://pub.dev" source: hosted - version: "4.0.0+1" + version: "4.0.1" flutter_local_notifications_platform_interface: dependency: transitive description: name: flutter_local_notifications_platform_interface - sha256: "340abf67df238f7f0ef58f4a26d2a83e1ab74c77ab03cd2b2d5018ac64db30b7" + sha256: "85f8d07fe708c1bdcf45037f2c0109753b26ae077e9d9e899d55971711a4ea66" url: "https://pub.dev" source: hosted - version: "7.1.0" + version: "7.2.0" flutter_localizations: dependency: "direct main" description: flutter @@ -383,10 +396,10 @@ packages: dependency: transitive description: name: flutter_plugin_android_lifecycle - sha256: c6b0b4c05c458e1c01ad9bcc14041dd7b1f6783d487be4386f793f47a8a4d03e + sha256: "9d98bd47ef9d34e803d438f17fd32b116d31009f534a6fa5ce3a1167f189a6de" url: "https://pub.dev" source: hosted - version: "2.0.20" + version: "2.0.21" flutter_test: dependency: "direct dev" description: flutter @@ -441,18 +454,18 @@ packages: dependency: "direct main" description: name: geolocator - sha256: "149876cc5207a0f5daf4fdd3bfcf0a0f27258b3fe95108fa084f527ad0568f1b" + sha256: "0ec58b731776bc43097fcf751f79681b6a8f6d3bc737c94779fe9f1ad73c1a81" url: "https://pub.dev" source: hosted - version: "12.0.0" + version: "13.0.1" geolocator_android: dependency: transitive description: name: geolocator_android - sha256: "00c7177a95823dd3ee35ef42fd8666cd27d219ae14cea472ac76a21dff43000b" + sha256: "7aefc530db47d90d0580b552df3242440a10fe60814496a979aa67aa98b1fd47" url: "https://pub.dev" source: hosted - version: "4.6.0" + version: "4.6.1" geolocator_apple: dependency: transitive description: @@ -473,10 +486,10 @@ packages: dependency: transitive description: name: geolocator_web - sha256: "7a22f400d831f924a89d931ba126a10e6b8b437f31e6b9311320435f3e1571bd" + sha256: "2ed69328e05cd94e7eb48bb0535f5fc0c0c44d1c4fa1e9737267484d05c29b5e" url: "https://pub.dev" source: hosted - version: "4.0.0" + version: "4.1.1" geolocator_windows: dependency: transitive description: @@ -497,10 +510,10 @@ packages: dependency: "direct main" description: name: go_router - sha256: cdae1b9c8bd7efadcef6112e81c903662ef2ce105cbd220a04bbb7c3425b5554 + sha256: "48d03a1e4887b00fe622695139246e3c778ac814eeb32421467b56d23fa64034" url: "https://pub.dev" source: hosted - version: "14.2.0" + version: "14.2.6" google_fonts: dependency: "direct main" description: @@ -513,18 +526,18 @@ packages: dependency: transitive description: name: graphs - sha256: aedc5a15e78fc65a6e23bcd927f24c64dd995062bcd1ca6eda65a3cff92a4d19 + sha256: "741bbf84165310a68ff28fe9e727332eef1407342fca52759cb21ad8177bb8d0" url: "https://pub.dev" source: hosted - version: "2.3.1" + version: "2.3.2" http: dependency: "direct main" description: name: http - sha256: "761a297c042deedc1ffbb156d6e2af13886bb305c2a343a4d972504cd67dd938" + sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010 url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.2.2" http_multi_server: dependency: transitive description: @@ -577,18 +590,18 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a" + sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" url: "https://pub.dev" source: hosted - version: "10.0.4" + version: "10.0.5" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8" + sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" url: "https://pub.dev" source: hosted - version: "3.0.3" + version: "3.0.5" leak_tracker_testing: dependency: transitive description: @@ -613,6 +626,14 @@ packages: url: "https://pub.dev" source: hosted version: "4.0.0" + lists: + dependency: transitive + description: + name: lists + sha256: "4ca5c19ae4350de036a7e996cdd1ee39c93ac0a2b840f4915459b7d0a7d4ab27" + url: "https://pub.dev" + source: hosted + version: "1.0.1" logging: dependency: transitive description: @@ -621,6 +642,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.2.0" + macros: + dependency: transitive + description: + name: macros + sha256: "0acaed5d6b7eab89f63350bccd82119e6c602df0f391260d0e32b5e23db79536" + url: "https://pub.dev" + source: hosted + version: "0.1.2-main.4" matcher: dependency: transitive description: @@ -633,18 +662,18 @@ packages: dependency: transitive description: name: material_color_utilities - sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" + sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec url: "https://pub.dev" source: hosted - version: "0.8.0" + version: "0.11.1" meta: dependency: transitive description: name: meta - sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136" + sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 url: "https://pub.dev" source: hosted - version: "1.12.0" + version: "1.15.0" mime: dependency: transitive description: @@ -665,32 +694,32 @@ packages: dependency: "direct main" description: name: package_info_plus - sha256: b93d8b4d624b4ea19b0a5a208b2d6eff06004bc3ce74c06040b120eeadd00ce0 + sha256: a75164ade98cb7d24cfd0a13c6408927c6b217fa60dee5a7ff5c116a58f28918 url: "https://pub.dev" source: hosted - version: "8.0.0" + version: "8.0.2" package_info_plus_platform_interface: dependency: transitive description: name: package_info_plus_platform_interface - sha256: f49918f3433a3146047372f9d4f1f847511f2acd5cd030e1f44fe5a50036b70e + sha256: ac1f4a4847f1ade8e6a87d1f39f5d7c67490738642e2542f559ec38c37489a66 url: "https://pub.dev" source: hosted - version: "3.0.0" + version: "3.0.1" passkit: dependency: "direct main" description: path: "../passkit" relative: true source: path - version: "0.0.4" + version: "0.0.5" passkit_ui: dependency: "direct main" description: path: "../passkit_ui" relative: true source: path - version: "0.0.3" + version: "0.0.4" path: dependency: "direct main" description: @@ -703,18 +732,18 @@ packages: dependency: "direct main" description: name: path_provider - sha256: c9e7d3a4cd1410877472158bee69963a4579f78b68c65a2b7d40d1a7a88bb161 + sha256: fec0d61223fba3154d87759e3cc27fe2c8dc498f6386c6d6fc80d1afdd1bf378 url: "https://pub.dev" source: hosted - version: "2.1.3" + version: "2.1.4" path_provider_android: dependency: transitive description: name: path_provider_android - sha256: bca87b0165ffd7cdb9cad8edd22d18d2201e886d9a9f19b4fb3452ea7df3a72a + sha256: "6f01f8e37ec30b07bc424b4deabac37cacb1bc7e2e515ad74486039918a37eb7" url: "https://pub.dev" source: hosted - version: "2.2.6" + version: "2.2.10" path_provider_foundation: dependency: transitive description: @@ -743,10 +772,18 @@ packages: dependency: transitive description: name: path_provider_windows - sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170" + sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7 url: "https://pub.dev" source: hosted - version: "2.2.1" + version: "2.3.0" + pem: + dependency: transitive + description: + name: pem + sha256: "3dfb24524f805ad694ba3cdbb6387ab31ab661fdb8ea873052ed88487fcfef86" + url: "https://pub.dev" + source: hosted + version: "2.0.5" petitparser: dependency: transitive description: @@ -755,6 +792,14 @@ packages: url: "https://pub.dev" source: hosted version: "6.0.2" + pkcs7: + dependency: transitive + description: + name: pkcs7 + sha256: "13c916f7577a4dbfc638af2266891a8f6bef06117ff78cff8982802419efbd37" + url: "https://pub.dev" + source: hosted + version: "1.0.3" platform: dependency: transitive description: @@ -771,6 +816,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.8" + pointycastle: + dependency: transitive + description: + name: pointycastle + sha256: "4be0097fcf3fd3e8449e53730c631200ebc7b88016acecab2b0da2f0149222fe" + url: "https://pub.dev" + source: hosted + version: "3.9.1" pool: dependency: transitive description: @@ -779,6 +832,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.5.1" + process_run: + dependency: transitive + description: + name: process_run + sha256: "112a77da35be50617ed9e2230df68d0817972f225e7f97ce8336f76b4e601606" + url: "https://pub.dev" + source: hosted + version: "1.2.0" pub_semver: dependency: transitive description: @@ -799,18 +860,10 @@ packages: dependency: transitive description: name: qr - sha256: "64957a3930367bf97cc211a5af99551d630f2f4625e38af10edd6b19131b64b3" + sha256: "5a1d2586170e172b8a8c8470bbbffd5eb0cd38a66c0d77155ea138d3af3a4445" url: "https://pub.dev" source: hosted - version: "3.0.1" - recase: - dependency: transitive - description: - name: recase - sha256: e4eb4ec2dcdee52dcf99cb4ceabaffc631d7424ee55e56f280bc039737f89213 - url: "https://pub.dev" - source: hosted - version: "4.1.0" + version: "3.0.2" receive_intent: dependency: "direct main" description: @@ -871,74 +924,74 @@ packages: dependency: "direct main" description: name: share_plus - sha256: ef3489a969683c4f3d0239010cc8b7a2a46543a8d139e111c06c558875083544 + sha256: "468c43f285207c84bcabf5737f33b914ceb8eb38398b91e5e3ad1698d1b72a52" url: "https://pub.dev" source: hosted - version: "9.0.0" + version: "10.0.2" share_plus_platform_interface: dependency: transitive description: name: share_plus_platform_interface - sha256: "0f9e4418835d1b2c3ae78fdb918251959106cefdbc4dd43526e182f80e82f6d4" + sha256: "6ababf341050edff57da8b6990f11f4e99eaba837865e2e6defe16d039619db5" url: "https://pub.dev" source: hosted - version: "4.0.0" + version: "5.0.0" shared_preferences: dependency: "direct main" description: name: shared_preferences - sha256: d3bbe5553a986e83980916ded2f0b435ef2e1893dfaa29d5a7a790d0eca12180 + sha256: "746e5369a43170c25816cc472ee016d3a66bc13fcf430c0bc41ad7b4b2922051" url: "https://pub.dev" source: hosted - version: "2.2.3" + version: "2.3.2" shared_preferences_android: dependency: transitive description: name: shared_preferences_android - sha256: "93d0ec9dd902d85f326068e6a899487d1f65ffcd5798721a95330b26c8131577" + sha256: a7e8467e9181cef109f601e3f65765685786c1a738a83d7fbbde377589c0d974 url: "https://pub.dev" source: hosted - version: "2.2.3" + version: "2.3.1" shared_preferences_foundation: dependency: transitive description: name: shared_preferences_foundation - sha256: "0a8a893bf4fd1152f93fec03a415d11c27c74454d96e2318a7ac38dd18683ab7" + sha256: c4b35f6cb8f63c147312c054ce7c2254c8066745125264f0c88739c417fc9d9f url: "https://pub.dev" source: hosted - version: "2.4.0" + version: "2.5.2" shared_preferences_linux: dependency: transitive description: name: shared_preferences_linux - sha256: "9f2cbcf46d4270ea8be39fa156d86379077c8a5228d9dfdb1164ae0bb93f1faa" + sha256: "580abfd40f415611503cae30adf626e6656dfb2f0cee8f465ece7b6defb40f2f" url: "https://pub.dev" source: hosted - version: "2.3.2" + version: "2.4.1" shared_preferences_platform_interface: dependency: transitive description: name: shared_preferences_platform_interface - sha256: "22e2ecac9419b4246d7c22bfbbda589e3acf5c0351137d87dd2939d984d37c3b" + sha256: "57cbf196c486bc2cf1f02b85784932c6094376284b3ad5779d1b1c6c6a816b80" url: "https://pub.dev" source: hosted - version: "2.3.2" + version: "2.4.1" shared_preferences_web: dependency: transitive description: name: shared_preferences_web - sha256: "9aee1089b36bd2aafe06582b7d7817fd317ef05fc30e6ba14bff247d0933042a" + sha256: d2ca4132d3946fec2184261726b355836a82c33d7d5b67af32692aff18a4684e url: "https://pub.dev" source: hosted - version: "2.3.0" + version: "2.4.2" shared_preferences_windows: dependency: transitive description: name: shared_preferences_windows - sha256: "841ad54f3c8381c480d0c9b508b89a34036f512482c407e6df7a9c4aa2ef8f59" + sha256: "94ef0f72b2d71bc3e700e025db3710911bd51a71cefb65cc609dd0d9a982e3c1" url: "https://pub.dev" source: hosted - version: "2.3.2" + version: "2.4.1" shelf: dependency: transitive description: @@ -984,14 +1037,46 @@ packages: url: "https://pub.dev" source: hosted version: "7.0.0" + sqflite: + dependency: "direct main" + description: + name: sqflite + sha256: a43e5a27235518c03ca238e7b4732cf35eabe863a369ceba6cbefa537a66f16d + url: "https://pub.dev" + source: hosted + version: "2.3.3+1" + sqflite_common: + dependency: transitive + description: + name: sqflite_common + sha256: "7b41b6c3507854a159e24ae90a8e3e9cc01eb26a477c118d6dca065b5f55453e" + url: "https://pub.dev" + source: hosted + version: "2.5.4+2" + sqflite_common_ffi: + dependency: transitive + description: + name: sqflite_common_ffi + sha256: "4d6137c29e930d6e4a8ff373989dd9de7bac12e3bc87bce950f6e844e8ad3bb5" + url: "https://pub.dev" + source: hosted + version: "2.3.3" + sqflite_common_ffi_web: + dependency: transitive + description: + name: sqflite_common_ffi_web + sha256: "5aa15408f29eca8cc8dcca653c38d66cf9a5fb5a2c1e9826a75ce4ae4938dec1" + url: "https://pub.dev" + source: hosted + version: "0.4.5+2" sqlite3: dependency: transitive description: name: sqlite3 - sha256: b384f598b813b347c5a7e5ffad82cbaff1bec3d1561af267041e66f6f0899295 + sha256: "45f168ae2213201b54e09429ed0c593dc2c88c924a1488d6f9c523a255d567cb" url: "https://pub.dev" source: hosted - version: "2.4.3" + version: "2.4.6" sqlite3_flutter_libs: dependency: "direct main" description: @@ -1004,10 +1089,10 @@ packages: dependency: transitive description: name: sqlparser - sha256: ade9a67fd70d0369329ed3373208de7ebd8662470e8c396fc8d0d60f9acdfc9f + sha256: "7b20045d1ccfb7bc1df7e8f9fee5ae58673fce6ff62cefbb0e0fd7214e90e5a0" url: "https://pub.dev" source: hosted - version: "0.36.0" + version: "0.34.1" stack_trace: dependency: transitive description: @@ -1040,6 +1125,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.2.0" + strings: + dependency: transitive + description: + name: strings + sha256: "052836499f03897d3860a603b330c1ea3c8a14177b21f34b15a1295f36024aae" + url: "https://pub.dev" + source: hosted + version: "3.1.2" + synchronized: + dependency: transitive + description: + name: synchronized + sha256: a824e842b8a054f91a728b783c177c1e4731f6b124f9192468457a8913371255 + url: "https://pub.dev" + source: hosted + version: "3.2.0" term_glyph: dependency: transitive description: @@ -1052,18 +1153,18 @@ packages: dependency: transitive description: name: test_api - sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f" + sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" url: "https://pub.dev" source: hosted - version: "0.7.0" + version: "0.7.2" timezone: dependency: transitive description: name: timezone - sha256: a6ccda4a69a442098b602c44e61a1e2b4bf6f5516e875bbf0f427d5df14745d5 + sha256: "2236ec079a174ce07434e89fcd3fcda430025eb7692244139a9cf54fdcf1fc7d" url: "https://pub.dev" source: hosted - version: "0.9.3" + version: "0.9.4" timing: dependency: transitive description: @@ -1080,6 +1181,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.2" + unicode: + dependency: transitive + description: + name: unicode + sha256: "0f69e46593d65245774d4f17125c6084d2c20b4e473a983f6e21b7d7762218f1" + url: "https://pub.dev" + source: hosted + version: "0.3.1" url_launcher: dependency: "direct main" description: @@ -1092,26 +1201,26 @@ packages: dependency: transitive description: name: url_launcher_android - sha256: ceb2625f0c24ade6ef6778d1de0b2e44f2db71fded235eb52295247feba8c5cf + sha256: e35a698ac302dd68e41f73250bd9517fe3ab5fa4f18fe4647a0872db61bacbab url: "https://pub.dev" source: hosted - version: "6.3.3" + version: "6.3.10" url_launcher_ios: dependency: transitive description: name: url_launcher_ios - sha256: "7068716403343f6ba4969b4173cbf3b84fc768042124bc2c011e5d782b24fe89" + sha256: e43b677296fadce447e987a2f519dcf5f6d1e527dc35d01ffab4fff5b8a7063e url: "https://pub.dev" source: hosted - version: "6.3.0" + version: "6.3.1" url_launcher_linux: dependency: transitive description: name: url_launcher_linux - sha256: ab360eb661f8879369acac07b6bb3ff09d9471155357da8443fd5d3cf7363811 + sha256: e2b9622b4007f97f504cd64c0128309dfb978ae66adbe944125ed9e1750f06af url: "https://pub.dev" source: hosted - version: "3.1.1" + version: "3.2.0" url_launcher_macos: dependency: transitive description: @@ -1132,26 +1241,26 @@ packages: dependency: transitive description: name: url_launcher_web - sha256: "8d9e750d8c9338601e709cd0885f95825086bd8b642547f26bda435aade95d8a" + sha256: "772638d3b34c779ede05ba3d38af34657a05ac55b06279ea6edd409e323dca8e" url: "https://pub.dev" source: hosted - version: "2.3.1" + version: "2.3.3" url_launcher_windows: dependency: transitive description: name: url_launcher_windows - sha256: ecf9725510600aa2bb6d7ddabe16357691b6d2805f66216a97d1b881e21beff7 + sha256: "49c10f879746271804767cb45551ec5592cdab00ee105c06dddde1a98f73b185" url: "https://pub.dev" source: hosted - version: "3.1.1" + version: "3.1.2" uuid: dependency: transitive description: name: uuid - sha256: "814e9e88f21a176ae1359149021870e87f7cddaf633ab678a5d2b0bff7fd1ba8" + sha256: "83d37c7ad7aaf9aa8e275490669535c8080377cfa7a7004c24dfac53afffaa90" url: "https://pub.dev" source: hosted - version: "4.4.0" + version: "4.4.2" vector_math: dependency: transitive description: @@ -1164,18 +1273,18 @@ packages: dependency: transitive description: name: vm_service - sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec" + sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" url: "https://pub.dev" source: hosted - version: "14.2.1" + version: "14.2.5" wakelock_plus: dependency: "direct main" description: name: wakelock_plus - sha256: "14758533319a462ffb5aa3b7ddb198e59b29ac3b02da14173a1715d65d4e6e68" + sha256: bf4ee6f17a2fa373ed3753ad0e602b7603f8c75af006d5b9bdade263928c0484 url: "https://pub.dev" source: hosted - version: "1.2.5" + version: "1.2.8" wakelock_plus_platform_interface: dependency: transitive description: @@ -1196,34 +1305,34 @@ packages: dependency: transitive description: name: web - sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27" + sha256: d43c1d6b787bf0afad444700ae7f4db8827f701bc61c255ac8d328c6f4d52062 url: "https://pub.dev" source: hosted - version: "0.5.1" + version: "1.0.0" web_socket: dependency: transitive description: name: web_socket - sha256: "24301d8c293ce6fe327ffe6f59d8fd8834735f0ec36e4fd383ec7ff8a64aa078" + sha256: "3c12d96c0c9a4eec095246debcea7b86c0324f22df69893d538fcc6f1b8cce83" url: "https://pub.dev" source: hosted - version: "0.1.5" + version: "0.1.6" web_socket_channel: dependency: transitive description: name: web_socket_channel - sha256: a2d56211ee4d35d9b344d9d4ce60f362e4f5d1aafb988302906bd732bc731276 + sha256: "9f187088ed104edd8662ca07af4b124465893caf063ba29758f97af57e61da8f" url: "https://pub.dev" source: hosted - version: "3.0.0" + version: "3.0.1" win32: dependency: transitive description: name: win32 - sha256: a79dbe579cb51ecd6d30b17e0cae4e0ea15e2c0e66f69ad4198f22a6789e94f4 + sha256: "68d1e89a91ed61ad9c370f9f8b6effed9ae5e0ede22a270bdfa6daf79fc2290a" url: "https://pub.dev" source: hosted - version: "5.5.1" + version: "5.5.4" xdg_directories: dependency: transitive description: @@ -1249,5 +1358,5 @@ packages: source: hosted version: "3.1.2" sdks: - dart: ">=3.4.3 <4.0.0" - flutter: ">=3.22.2" + dart: ">=3.5.0 <4.0.0" + flutter: ">=3.24.0" diff --git a/app/pubspec.yaml b/app/pubspec.yaml index 1f327ef..75bcb11 100644 --- a/app/pubspec.yaml +++ b/app/pubspec.yaml @@ -4,15 +4,15 @@ publish_to: "none" version: 0.1.0 environment: - sdk: ">=3.4.3 <4.0.0" - flutter: 3.22.2 + sdk: ">=3.5.0 <4.0.0" + flutter: '>=3.24.0' dependencies: android_intent_plus: ^5.0.2 content_resolver: ^0.3.1 desktop_drop: ^0.4.4 - drift: ^2.11.1 - file_picker: ^8.0.5 + file_picker: ^8.1.2 + floor: ^1.5.0 flutter: sdk: flutter flutter_displaymode: ^0.6.0 @@ -21,7 +21,7 @@ dependencies: flutter_localizations: sdk: flutter geocoding: ^3.0.0 - geolocator: ^12.0.0 + geolocator: ^13.0.0 go_router: ^14.2.0 google_fonts: ^6.2.1 http: ^1.2.1 @@ -33,8 +33,9 @@ dependencies: path_provider: ^2.0.0 receive_intent: ^0.2.4 screen_brightness: ^1.0.0 - share_plus: ^9.0.0 + share_plus: ^10.0.2 shared_preferences: ^2.2.3 + sqflite: ^2.3.3+1 sqlite3_flutter_libs: ^0.5.0 url_launcher: ^6.3.0 wakelock_plus: ^1.2.5 @@ -47,7 +48,7 @@ dependency_overrides: dev_dependencies: build_runner: ^2.4.6 - drift_dev: ^2.11.1 + floor_generator: ^1.5.0 flutter_lints: ^4.0.0 flutter_test: sdk: flutter diff --git a/apple_passkit/example/pubspec.lock b/apple_passkit/example/pubspec.lock index d7f4733..45a6e09 100644 --- a/apple_passkit/example/pubspec.lock +++ b/apple_passkit/example/pubspec.lock @@ -109,18 +109,18 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a" + sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" url: "https://pub.dev" source: hosted - version: "10.0.4" + version: "10.0.5" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8" + sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" url: "https://pub.dev" source: hosted - version: "3.0.3" + version: "3.0.5" leak_tracker_testing: dependency: transitive description: @@ -149,18 +149,18 @@ packages: dependency: transitive description: name: material_color_utilities - sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" + sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec url: "https://pub.dev" source: hosted - version: "0.8.0" + version: "0.11.1" meta: dependency: transitive description: name: meta - sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136" + sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 url: "https://pub.dev" source: hosted - version: "1.12.0" + version: "1.15.0" path: dependency: transitive description: @@ -173,10 +173,10 @@ packages: dependency: transitive description: name: platform - sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec" + sha256: "9b71283fc13df574056616011fb138fd3b793ea47cc509c189a6c3fa5f8a1a65" url: "https://pub.dev" source: hosted - version: "3.1.4" + version: "3.1.5" process: dependency: transitive description: @@ -242,10 +242,10 @@ packages: dependency: transitive description: name: test_api - sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f" + sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" url: "https://pub.dev" source: hosted - version: "0.7.0" + version: "0.7.2" vector_math: dependency: transitive description: @@ -258,10 +258,10 @@ packages: dependency: transitive description: name: vm_service - sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec" + sha256: f652077d0bdf60abe4c1f6377448e8655008eef28f128bc023f7b5e8dfeb48fc url: "https://pub.dev" source: hosted - version: "14.2.1" + version: "14.2.4" webdriver: dependency: transitive description: diff --git a/passkit_server/pubspec.lock b/passkit_server/pubspec.lock new file mode 100644 index 0000000..31c5e84 --- /dev/null +++ b/passkit_server/pubspec.lock @@ -0,0 +1,474 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + _fe_analyzer_shared: + dependency: transitive + description: + name: _fe_analyzer_shared + sha256: "5aaf60d96c4cd00fe7f21594b5ad6a1b699c80a27420f8a837f4d68473ef09e3" + url: "https://pub.dev" + source: hosted + version: "68.0.0" + _macros: + dependency: transitive + description: dart + source: sdk + version: "0.1.0" + analyzer: + dependency: transitive + description: + name: analyzer + sha256: "21f1d3720fd1c70316399d5e2bccaebb415c434592d778cce8acb967b8578808" + url: "https://pub.dev" + source: hosted + version: "6.5.0" + archive: + dependency: transitive + description: + name: archive + sha256: cb6a278ef2dbb298455e1a713bda08524a175630ec643a242c399c932a0a1f7d + url: "https://pub.dev" + source: hosted + version: "3.6.1" + args: + dependency: transitive + description: + name: args + sha256: "7cf60b9f0cc88203c5a190b4cd62a99feea42759a7fa695010eb5de1c0b2252a" + url: "https://pub.dev" + source: hosted + version: "2.5.0" + async: + dependency: transitive + description: + name: async + sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" + url: "https://pub.dev" + source: hosted + version: "2.11.0" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + clock: + dependency: transitive + description: + name: clock + sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + url: "https://pub.dev" + source: hosted + version: "1.1.1" + collection: + dependency: transitive + description: + name: collection + sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf + url: "https://pub.dev" + source: hosted + version: "1.19.0" + convert: + dependency: transitive + description: + name: convert + sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592" + url: "https://pub.dev" + source: hosted + version: "3.1.1" + coverage: + dependency: transitive + description: + name: coverage + sha256: "576aaab8b1abdd452e0f656c3e73da9ead9d7880e15bdc494189d9c1a1baf0db" + url: "https://pub.dev" + source: hosted + version: "1.9.0" + crypto: + dependency: transitive + description: + name: crypto + sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab + url: "https://pub.dev" + source: hosted + version: "3.0.3" + csslib: + dependency: transitive + description: + name: csslib + sha256: "706b5707578e0c1b4b7550f64078f0a0f19dec3f50a178ffae7006b0a9ca58fb" + url: "https://pub.dev" + source: hosted + version: "1.0.0" + file: + dependency: transitive + description: + name: file + sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" + url: "https://pub.dev" + source: hosted + version: "7.0.0" + frontend_server_client: + dependency: transitive + description: + name: frontend_server_client + sha256: f64a0333a82f30b0cca061bc3d143813a486dc086b574bfb233b7c1372427694 + url: "https://pub.dev" + source: hosted + version: "4.0.0" + glob: + dependency: transitive + description: + name: glob + sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63" + url: "https://pub.dev" + source: hosted + version: "2.1.2" + http: + dependency: transitive + description: + name: http + sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010 + url: "https://pub.dev" + source: hosted + version: "1.2.2" + http_methods: + dependency: transitive + description: + name: http_methods + sha256: "6bccce8f1ec7b5d701e7921dca35e202d425b57e317ba1a37f2638590e29e566" + url: "https://pub.dev" + source: hosted + version: "1.1.1" + http_multi_server: + dependency: transitive + description: + name: http_multi_server + sha256: "97486f20f9c2f7be8f514851703d0119c3596d14ea63227af6f7a481ef2b2f8b" + url: "https://pub.dev" + source: hosted + version: "3.2.1" + http_parser: + dependency: transitive + description: + name: http_parser + sha256: "40f592dd352890c3b60fec1b68e786cefb9603e05ff303dbc4dda49b304ecdf4" + url: "https://pub.dev" + source: hosted + version: "4.1.0" + intl: + dependency: transitive + description: + name: intl + sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf + url: "https://pub.dev" + source: hosted + version: "0.19.0" + io: + dependency: transitive + description: + name: io + sha256: "2ec25704aba361659e10e3e5f5d672068d332fc8ac516421d483a11e5cbd061e" + url: "https://pub.dev" + source: hosted + version: "1.0.4" + js: + dependency: transitive + description: + name: js + sha256: c1b2e9b5ea78c45e1a0788d29606ba27dc5f71f019f32ca5140f61ef071838cf + url: "https://pub.dev" + source: hosted + version: "0.7.1" + json_annotation: + dependency: transitive + description: + name: json_annotation + sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1" + url: "https://pub.dev" + source: hosted + version: "4.9.0" + lints: + dependency: "direct dev" + description: + name: lints + sha256: "976c774dd944a42e83e2467f4cc670daef7eed6295b10b36ae8c85bcbf828235" + url: "https://pub.dev" + source: hosted + version: "4.0.0" + logging: + dependency: transitive + description: + name: logging + sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340" + url: "https://pub.dev" + source: hosted + version: "1.2.0" + macros: + dependency: transitive + description: + name: macros + sha256: "12e8a9842b5a7390de7a781ec63d793527582398d16ea26c60fed58833c9ae79" + url: "https://pub.dev" + source: hosted + version: "0.1.0-main.0" + matcher: + dependency: transitive + description: + name: matcher + sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb + url: "https://pub.dev" + source: hosted + version: "0.12.16+1" + meta: + dependency: transitive + description: + name: meta + sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 + url: "https://pub.dev" + source: hosted + version: "1.15.0" + mime: + dependency: transitive + description: + name: mime + sha256: "2e123074287cc9fd6c09de8336dae606d1ddb88d9ac47358826db698c176a1f2" + url: "https://pub.dev" + source: hosted + version: "1.0.5" + node_preamble: + dependency: transitive + description: + name: node_preamble + sha256: "6e7eac89047ab8a8d26cf16127b5ed26de65209847630400f9aefd7cd5c730db" + url: "https://pub.dev" + source: hosted + version: "2.0.2" + package_config: + dependency: transitive + description: + name: package_config + sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd" + url: "https://pub.dev" + source: hosted + version: "2.1.0" + passkit: + dependency: "direct main" + description: + name: passkit + sha256: "31ebf71adacfe9db2478dbe95024da52d161b53fb271bf9c682a13e315e79975" + url: "https://pub.dev" + source: hosted + version: "0.0.4" + path: + dependency: transitive + description: + name: path + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" + url: "https://pub.dev" + source: hosted + version: "1.9.0" + pool: + dependency: transitive + description: + name: pool + sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a" + url: "https://pub.dev" + source: hosted + version: "1.5.1" + pub_semver: + dependency: transitive + description: + name: pub_semver + sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c" + url: "https://pub.dev" + source: hosted + version: "2.1.4" + shelf: + dependency: "direct main" + description: + name: shelf + sha256: e7dd780a7ffb623c57850b33f43309312fc863fb6aa3d276a754bb299839ef12 + url: "https://pub.dev" + source: hosted + version: "1.4.2" + shelf_packages_handler: + dependency: transitive + description: + name: shelf_packages_handler + sha256: "89f967eca29607c933ba9571d838be31d67f53f6e4ee15147d5dc2934fee1b1e" + url: "https://pub.dev" + source: hosted + version: "3.0.2" + shelf_router: + dependency: "direct main" + description: + name: shelf_router + sha256: f5e5d492440a7fb165fe1e2e1a623f31f734d3370900070b2b1e0d0428d59864 + url: "https://pub.dev" + source: hosted + version: "1.1.4" + shelf_static: + dependency: transitive + description: + name: shelf_static + sha256: a41d3f53c4adf0f57480578c1d61d90342cd617de7fc8077b1304643c2d85c1e + url: "https://pub.dev" + source: hosted + version: "1.1.2" + shelf_web_socket: + dependency: transitive + description: + name: shelf_web_socket + sha256: "073c147238594ecd0d193f3456a5fe91c4b0abbcc68bf5cd95b36c4e194ac611" + url: "https://pub.dev" + source: hosted + version: "2.0.0" + source_map_stack_trace: + dependency: transitive + description: + name: source_map_stack_trace + sha256: "84cf769ad83aa6bb61e0aa5a18e53aea683395f196a6f39c4c881fb90ed4f7ae" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + source_maps: + dependency: transitive + description: + name: source_maps + sha256: "708b3f6b97248e5781f493b765c3337db11c5d2c81c3094f10904bfa8004c703" + url: "https://pub.dev" + source: hosted + version: "0.10.12" + source_span: + dependency: transitive + description: + name: source_span + sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" + url: "https://pub.dev" + source: hosted + version: "1.10.0" + stack_trace: + dependency: transitive + description: + name: stack_trace + sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" + url: "https://pub.dev" + source: hosted + version: "1.11.1" + stream_channel: + dependency: transitive + description: + name: stream_channel + sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 + url: "https://pub.dev" + source: hosted + version: "2.1.2" + string_scanner: + dependency: transitive + description: + name: string_scanner + sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3" + url: "https://pub.dev" + source: hosted + version: "1.3.0" + term_glyph: + dependency: transitive + description: + name: term_glyph + sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 + url: "https://pub.dev" + source: hosted + version: "1.2.1" + test: + dependency: "direct dev" + description: + name: test + sha256: "713a8789d62f3233c46b4a90b174737b2c04cb6ae4500f2aa8b1be8f03f5e67f" + url: "https://pub.dev" + source: hosted + version: "1.25.8" + test_api: + dependency: transitive + description: + name: test_api + sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c" + url: "https://pub.dev" + source: hosted + version: "0.7.3" + test_core: + dependency: transitive + description: + name: test_core + sha256: "12391302411737c176b0b5d6491f466b0dd56d4763e347b6714efbaa74d7953d" + url: "https://pub.dev" + source: hosted + version: "0.6.5" + typed_data: + dependency: transitive + description: + name: typed_data + sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c + url: "https://pub.dev" + source: hosted + version: "1.3.2" + vm_service: + dependency: transitive + description: + name: vm_service + sha256: f652077d0bdf60abe4c1f6377448e8655008eef28f128bc023f7b5e8dfeb48fc + url: "https://pub.dev" + source: hosted + version: "14.2.4" + watcher: + dependency: transitive + description: + name: watcher + sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8" + url: "https://pub.dev" + source: hosted + version: "1.1.0" + web: + dependency: transitive + description: + name: web + sha256: d43c1d6b787bf0afad444700ae7f4db8827f701bc61c255ac8d328c6f4d52062 + url: "https://pub.dev" + source: hosted + version: "1.0.0" + web_socket: + dependency: transitive + description: + name: web_socket + sha256: "3c12d96c0c9a4eec095246debcea7b86c0324f22df69893d538fcc6f1b8cce83" + url: "https://pub.dev" + source: hosted + version: "0.1.6" + web_socket_channel: + dependency: transitive + description: + name: web_socket_channel + sha256: "9f187088ed104edd8662ca07af4b124465893caf063ba29758f97af57e61da8f" + url: "https://pub.dev" + source: hosted + version: "3.0.1" + webkit_inspection_protocol: + dependency: transitive + description: + name: webkit_inspection_protocol + sha256: "87d3f2333bb240704cd3f1c6b5b7acd8a10e7f0bc28c28dcf14e782014f4a572" + url: "https://pub.dev" + source: hosted + version: "1.2.1" + yaml: + dependency: transitive + description: + name: yaml + sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5" + url: "https://pub.dev" + source: hosted + version: "3.1.2" +sdks: + dart: ">=3.4.4 <4.0.0" diff --git a/passkit_ui/example/pubspec.lock b/passkit_ui/example/pubspec.lock index ac17e44..1fdc051 100644 --- a/passkit_ui/example/pubspec.lock +++ b/passkit_ui/example/pubspec.lock @@ -77,10 +77,10 @@ packages: dependency: transitive description: name: crypto - sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab + sha256: ec30d999af904f33454ba22ed9a86162b35e52b44ac4807d1d93c288041d7d27 url: "https://pub.dev" source: hosted - version: "3.0.3" + version: "3.0.5" csslib: dependency: transitive description: @@ -119,10 +119,10 @@ packages: dependency: transitive description: name: http - sha256: "761a297c042deedc1ffbb156d6e2af13886bb305c2a343a4d972504cd67dd938" + sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010 url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.2.2" http_parser: dependency: transitive description: @@ -159,18 +159,18 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a" + sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" url: "https://pub.dev" source: hosted - version: "10.0.4" + version: "10.0.5" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8" + sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" url: "https://pub.dev" source: hosted - version: "3.0.3" + version: "3.0.5" leak_tracker_testing: dependency: transitive description: @@ -199,18 +199,18 @@ packages: dependency: transitive description: name: material_color_utilities - sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" + sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec url: "https://pub.dev" source: hosted - version: "0.8.0" + version: "0.11.1" meta: dependency: transitive description: name: meta - sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136" + sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 url: "https://pub.dev" source: hosted - version: "1.12.0" + version: "1.15.0" passkit: dependency: "direct main" description: @@ -269,10 +269,10 @@ packages: dependency: transitive description: name: qr - sha256: "64957a3930367bf97cc211a5af99551d630f2f4625e38af10edd6b19131b64b3" + sha256: "5a1d2586170e172b8a8c8470bbbffd5eb0cd38a66c0d77155ea138d3af3a4445" url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "3.0.2" sky_engine: dependency: transitive description: flutter @@ -322,10 +322,10 @@ packages: dependency: transitive description: name: test_api - sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f" + sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" url: "https://pub.dev" source: hosted - version: "0.7.0" + version: "0.7.2" typed_data: dependency: transitive description: @@ -346,18 +346,18 @@ packages: dependency: transitive description: name: vm_service - sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec" + sha256: f652077d0bdf60abe4c1f6377448e8655008eef28f128bc023f7b5e8dfeb48fc url: "https://pub.dev" source: hosted - version: "14.2.1" + version: "14.2.4" web: dependency: transitive description: name: web - sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27" + sha256: d43c1d6b787bf0afad444700ae7f4db8827f701bc61c255ac8d328c6f4d52062 url: "https://pub.dev" source: hosted - version: "0.5.1" + version: "1.0.0" sdks: - dart: ">=3.3.0 <4.0.0" + dart: ">=3.4.0 <4.0.0" flutter: ">=3.18.0-18.0.pre.54"