From a2cf390fdfef0e5b9c13bbe4ec078c4051dbe8b3 Mon Sep 17 00:00:00 2001 From: Ali Ince Date: Tue, 7 Jan 2025 10:01:33 +0100 Subject: [PATCH 01/29] chore: update pubspec --- apps/enmeshed/pubspec.lock | 71 ++++++------------- apps/enmeshed/pubspec.yaml | 1 + pubspec.lock | 140 +++++++++++++------------------------ 3 files changed, 71 insertions(+), 141 deletions(-) diff --git a/apps/enmeshed/pubspec.lock b/apps/enmeshed/pubspec.lock index b89c7e76c..6c9e52427 100644 --- a/apps/enmeshed/pubspec.lock +++ b/apps/enmeshed/pubspec.lock @@ -13,10 +13,10 @@ packages: dependency: "direct main" description: name: app_links - sha256: ad1a6d598e7e39b46a34f746f9a8b011ee147e4c275d407fa457e7a62f84dd99 + sha256: "433df2e61b10519407475d7f69e470789d23d593f28224c38ba1068597be7950" url: "https://pub.dev" source: hosted - version: "6.3.2" + version: "6.3.3" app_links_linux: dependency: transitive description: @@ -65,22 +65,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.11.0" - barcode: - dependency: transitive - description: - name: barcode - sha256: ab180ce22c6555d77d45f0178a523669db67f95856e3378259ef2ffeb43e6003 - url: "https://pub.dev" - source: hosted - version: "2.2.8" - bidi: - dependency: transitive - description: - name: bidi - sha256: "9a712c7ddf708f7c41b1923aa83648a3ed44cfd75b04f72d598c45e5be287f9d" - url: "https://pub.dev" - source: hosted - version: "2.0.12" boolean_selector: dependency: transitive description: @@ -189,18 +173,18 @@ packages: dependency: transitive description: name: device_info_plus - sha256: f545ffbadee826f26f2e1a0f0cbd667ae9a6011cc0f77c0f8f00a969655e6e95 + sha256: "4fa68e53e26ab17b70ca39f072c285562cfc1589df5bb1e9295db90f6645f431" url: "https://pub.dev" source: hosted - version: "11.1.1" + version: "11.2.0" device_info_plus_platform_interface: dependency: transitive description: name: device_info_plus_platform_interface - sha256: "282d3cf731045a2feb66abfe61bbc40870ae50a3ed10a4d3d217556c35c8c2ba" + sha256: "0b04e02b30791224b31969eb1b50d723498f402971bff3630bca2ba839bd1ed2" url: "https://pub.dev" source: hosted - version: "7.0.1" + version: "7.0.2" enmeshed_runtime_bridge: dependency: "direct main" description: @@ -494,10 +478,10 @@ packages: dependency: transitive description: name: flutter_plugin_android_lifecycle - sha256: "9b78450b89f059e96c9ebb355fa6b3df1d6b330436e0b885fb49594c41721398" + sha256: "615a505aef59b151b46bbeef55b36ce2b6ed299d160c51d84281946f0aa0ce0e" url: "https://pub.dev" source: hosted - version: "2.0.23" + version: "2.0.24" flutter_slidable: dependency: "direct main" description: @@ -520,10 +504,10 @@ packages: dependency: "direct main" description: name: get_it - sha256: c49895c1ecb0ee2a0ec568d39de882e2c299ba26355aa6744ab1001f98cebd15 + sha256: f126a3e286b7f5b578bf436d5592968706c4c1de28a228b870ce375d9f743103 url: "https://pub.dev" source: hosted - version: "8.0.2" + version: "8.0.3" glob: dependency: transitive description: @@ -580,13 +564,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.2" - identity_recovery_kit: - dependency: "direct overridden" - description: - path: "../../packages/identity_recovery_kit" - relative: true - source: path - version: "1.0.0" image: dependency: "direct main" description: @@ -847,18 +824,18 @@ packages: dependency: "direct main" description: name: package_info_plus - sha256: da8d9ac8c4b1df253d1a328b7bf01ae77ef132833479ab40763334db13b91cce + sha256: "70c421fe9d9cc1a9a7f3b05ae56befd469fe4f8daa3b484823141a55442d858d" url: "https://pub.dev" source: hosted - version: "8.1.1" + version: "8.1.2" package_info_plus_platform_interface: dependency: transitive description: name: package_info_plus_platform_interface - sha256: ac1f4a4847f1ade8e6a87d1f39f5d7c67490738642e2542f559ec38c37489a66 + sha256: a5ef9986efc7bf772f2696183a3992615baa76c1ffb1189318dd8803778fb05b url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "3.0.2" path: dependency: "direct main" description: @@ -923,14 +900,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.3.0" - pdf: - dependency: transitive - description: - name: pdf - sha256: "05df53f8791587402493ac97b9869d3824eccbc77d97855f4545cf72df3cae07" - url: "https://pub.dev" - source: hosted - version: "3.11.1" permission_handler: dependency: "direct main" description: @@ -1078,26 +1047,26 @@ packages: dependency: transitive description: name: shared_preferences - sha256: "95f9997ca1fb9799d494d0cb2a780fd7be075818d59f00c43832ed112b158a82" + sha256: "3c7e73920c694a436afaf65ab60ce3453d91f84208d761fbd83fc21182134d93" url: "https://pub.dev" source: hosted - version: "2.3.3" + version: "2.3.4" shared_preferences_android: dependency: transitive description: name: shared_preferences_android - sha256: "7f172d1b06de5da47b6264c2692ee2ead20bbbc246690427cdb4fc301cd0c549" + sha256: "02a7d8a9ef346c9af715811b01fbd8e27845ad2c41148eefd31321471b41863d" url: "https://pub.dev" source: hosted - version: "2.3.4" + version: "2.4.0" shared_preferences_foundation: dependency: transitive description: name: shared_preferences_foundation - sha256: "07e050c7cd39bad516f8d64c455f04508d09df104be326d8c02551590a0d513d" + sha256: "6a52cfcdaeac77cad8c97b539ff688ccfc458c007b4db12be584fbe5c0e49e03" url: "https://pub.dev" source: hosted - version: "2.5.3" + version: "2.5.4" shared_preferences_linux: dependency: transitive description: diff --git a/apps/enmeshed/pubspec.yaml b/apps/enmeshed/pubspec.yaml index 9decc16b8..8167743bc 100644 --- a/apps/enmeshed/pubspec.yaml +++ b/apps/enmeshed/pubspec.yaml @@ -64,6 +64,7 @@ flutter: generate: true uses-material-design: true assets: + - path: assets/tag_example.json - path: assets/i18n/ - path: assets/texts/ - path: assets/pictures/ diff --git a/pubspec.lock b/pubspec.lock index 30122eb7a..9f1ebfc0a 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -21,26 +21,26 @@ packages: dependency: transitive description: name: async - sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" + sha256: d2872f9c19731c2e5f10444b14686eb7cc85c76274bd6c16e1816bff9a3bab63 url: "https://pub.dev" source: hosted - version: "2.11.0" - boolean_selector: + version: "2.12.0" + charcode: dependency: transitive description: - name: boolean_selector - sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" + name: charcode + sha256: fb0f1107cac15a5ea6ef0a6ef71a807b9e4267c713bb93e00e92d737cc8dbd8a url: "https://pub.dev" source: hosted - version: "2.1.1" - charcode: + version: "1.4.0" + checked_yaml: dependency: transitive description: - name: charcode - sha256: fb98c0f6d12c920a02ee2d998da788bca066ca5f148492b7085ee23372b12306 + name: checked_yaml + sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff url: "https://pub.dev" source: hosted - version: "1.3.1" + version: "2.0.3" cli_launcher: dependency: transitive description: @@ -61,18 +61,18 @@ packages: dependency: transitive description: name: clock - sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.1.2" collection: dependency: transitive description: name: collection - sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf + sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" url: "https://pub.dev" source: hosted - version: "1.19.0" + version: "1.19.1" conventional_commit: dependency: transitive description: @@ -85,10 +85,10 @@ packages: dependency: transitive description: name: file - sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" + sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 url: "https://pub.dev" source: hosted - version: "7.0.0" + version: "7.0.1" flutter_lints: dependency: "direct dev" description: @@ -125,10 +125,10 @@ packages: dependency: transitive description: name: http_parser - sha256: "76d306a1c3afb33fe82e2bbacad62a61f409b5634c915fceb0d799de1a913360" + sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571" url: "https://pub.dev" source: hosted - version: "4.1.1" + version: "4.1.2" intl: dependency: transitive description: @@ -141,10 +141,10 @@ packages: dependency: transitive description: name: io - sha256: "2ec25704aba361659e10e3e5f5d672068d332fc8ac516421d483a11e5cbd061e" + sha256: dfd5a80599cf0165756e3181807ed3e77daf6dd4137caaad72d0b7931597650b url: "https://pub.dev" source: hosted - version: "1.0.4" + version: "1.0.5" json_annotation: dependency: transitive description: @@ -157,34 +157,26 @@ packages: dependency: transitive description: name: lints - sha256: "3315600f3fb3b135be672bf4a178c55f274bebe368325ae18462c89ac1e3b413" + sha256: c35bb79562d980e9a453fc715854e1ed39e24e7d0297a880ef54e17f9874a9d7 url: "https://pub.dev" source: hosted - version: "5.0.0" - matcher: - dependency: transitive - description: - name: matcher - sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb - url: "https://pub.dev" - source: hosted - version: "0.12.16+1" + version: "5.1.1" melos: dependency: "direct dev" description: name: melos - sha256: a62abfa8c7826cec927f8585572bb9adf591be152150494d879ca2c75118809d + sha256: c52e27c0b291e42180aff81cbf5bc6028099e065cfd4e5f9a4095ab603dfd711 url: "https://pub.dev" source: hosted - version: "6.2.0" + version: "6.3.0" meta: dependency: transitive description: name: meta - sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 + sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c url: "https://pub.dev" source: hosted - version: "1.15.0" + version: "1.16.0" mustache_template: dependency: transitive description: @@ -197,18 +189,18 @@ packages: dependency: transitive description: name: path - sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" + sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" url: "https://pub.dev" source: hosted - version: "1.9.0" + version: "1.9.1" platform: dependency: transitive description: name: platform - sha256: "9b71283fc13df574056616011fb138fd3b793ea47cc509c189a6c3fa5f8a1a65" + sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984" url: "https://pub.dev" source: hosted - version: "3.1.5" + version: "3.1.6" pool: dependency: transitive description: @@ -221,10 +213,10 @@ packages: dependency: transitive description: name: process - sha256: "21e54fd2faf1b5bdd5102afd25012184a6793927648ea81eea80552ac9405b32" + sha256: "107d8be718f120bbba9dcd1e95e3bd325b1b4a4f07db64154635ba03f2567a0d" url: "https://pub.dev" source: hosted - version: "5.0.2" + version: "5.0.3" prompts: dependency: transitive description: @@ -237,10 +229,10 @@ packages: dependency: transitive description: name: pub_semver - sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c" + sha256: "7b3cfbf654f3edd0c6298ecd5be782ce997ddf0e00531b9464b55245185bbbbd" url: "https://pub.dev" source: hosted - version: "2.1.4" + version: "2.1.5" pub_updater: dependency: transitive description: @@ -249,70 +241,46 @@ packages: url: "https://pub.dev" source: hosted version: "0.4.0" - pubspec: + pubspec_parse: dependency: transitive description: - name: pubspec - sha256: f534a50a2b4d48dc3bc0ec147c8bd7c304280fff23b153f3f11803c4d49d927e + name: pubspec_parse + sha256: "81876843eb50dc2e1e5b151792c9a985c5ed2536914115ed04e9c8528f6647b0" url: "https://pub.dev" source: hosted - version: "2.3.0" - quiver: - dependency: transitive - description: - name: quiver - sha256: ea0b925899e64ecdfbf9c7becb60d5b50e706ade44a85b2363be2a22d88117d2 - url: "https://pub.dev" - source: hosted - version: "3.2.2" + version: "1.4.0" source_span: dependency: transitive description: name: source_span - sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" + sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c" url: "https://pub.dev" source: hosted - version: "1.10.0" + version: "1.10.1" stack_trace: dependency: transitive description: name: stack_trace - sha256: "9f47fd3630d76be3ab26f0ee06d213679aa425996925ff3feffdec504931c377" + sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" url: "https://pub.dev" source: hosted - version: "1.12.0" - stream_channel: - dependency: transitive - description: - name: stream_channel - sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 - url: "https://pub.dev" - source: hosted - version: "2.1.2" + version: "1.12.1" string_scanner: dependency: transitive description: name: string_scanner - sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3" + sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43" url: "https://pub.dev" source: hosted - version: "1.3.0" + version: "1.4.1" term_glyph: dependency: transitive description: name: term_glyph - sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 - url: "https://pub.dev" - source: hosted - version: "1.2.1" - test_api: - dependency: transitive - description: - name: test_api - sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c" + sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e" url: "https://pub.dev" source: hosted - version: "0.7.3" + version: "1.2.2" typed_data: dependency: transitive description: @@ -321,14 +289,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.4.0" - uri: - dependency: transitive - description: - name: uri - sha256: "889eea21e953187c6099802b7b4cf5219ba8f3518f604a1033064d45b1b8268a" - url: "https://pub.dev" - source: hosted - version: "1.0.0" web: dependency: transitive description: @@ -341,17 +301,17 @@ packages: dependency: transitive description: name: yaml - sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5" + sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce url: "https://pub.dev" source: hosted - version: "3.1.2" + version: "3.1.3" yaml_edit: dependency: transitive description: name: yaml_edit - sha256: e9c1a3543d2da0db3e90270dbb1e4eebc985ee5e3ffe468d83224472b2194a5f + sha256: fb38626579fb345ad00e674e2af3a5c9b0cc4b9bfb8fd7f7ff322c7c9e62aef5 url: "https://pub.dev" source: hosted - version: "2.2.1" + version: "2.2.2" sdks: dart: ">=3.6.0 <4.0.0" From 44985e41848a69920b6a39976e20f299945d5d25 Mon Sep 17 00:00:00 2001 From: Ali Ince Date: Tue, 7 Jan 2025 10:02:27 +0100 Subject: [PATCH 02/29] chore: add translations --- apps/enmeshed/lib/l10n/app_de.arb | 7 +++++++ apps/enmeshed/lib/l10n/app_en.arb | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/apps/enmeshed/lib/l10n/app_de.arb b/apps/enmeshed/lib/l10n/app_de.arb index 68753155d..2894019c8 100644 --- a/apps/enmeshed/lib/l10n/app_de.arb +++ b/apps/enmeshed/lib/l10n/app_de.arb @@ -589,6 +589,9 @@ "files_noResults": "Keine Ergebnisse", "files_noResultsDescription": "Für den eingegeben Suchbegriff konnten keine Ergebnisse gefunden werden.", "files_uploadInProgress": "Die Datei wird hochgeladen.", + "files_assignTags": "Vergeben Sie Tags!", + "files_assignTagsDescription": "Mit Tags bringen Sie Ordnung in Ihre Dateien und Dokumente. So finden Sie jederzeit schnell wieder, was sie brauchen.", + "files_assignTagsButton": "Tags vergeben", "files_uploadFile": "Datei hochladen", "files_selectFile": "Datei auswählen", "files_createdAt": "Erstellt", @@ -608,6 +611,10 @@ "files_fileType_other": "Andere ...", "files_fileSize": "Größe", "files_tag": "Tag", + "files_tags": "Tags", + "files_editFile": "Dokument bearbeiten", + "files_selectedTags": "Ausgewählte Tags:", + "files_availableTags": "Verfügbare Tags:", "filter": "Filter", "apply_filter": "Filtern", "deviceOnboarding_title": "Gerät hinzufügen", diff --git a/apps/enmeshed/lib/l10n/app_en.arb b/apps/enmeshed/lib/l10n/app_en.arb index f5ded11d8..a58c316d7 100644 --- a/apps/enmeshed/lib/l10n/app_en.arb +++ b/apps/enmeshed/lib/l10n/app_en.arb @@ -589,6 +589,9 @@ "files_noResults": "No results", "files_noResultsDescription": "No results could be found for the search query entered.", "files_uploadInProgress": "Uploading the file.", + "files_assignTags": "Assign tags!", + "files_assignTagsDescription": "With tags, you bring order to your files and documents. So you can always find what you need quickly.", + "files_assignTagsButton": "Assign tags", "files_uploadFile": "Upload File", "files_selectFile": "Select your file", "files_createdAt": "Created", @@ -608,6 +611,10 @@ "files_fileType_other": "Other ...", "files_fileSize": "Size", "files_tag": "Tag", + "files_tags": "Tags", + "files_editFile": "Edit file", + "files_selectedTags": "Selected tags:", + "files_availableTags": "Available tags:", "filter": "Filter", "apply_filter": "Apply filters", "deviceOnboarding_title": "Add device", From 5c4791aea49b3e5c64eec4e90ff62a553a48c19d Mon Sep 17 00:00:00 2001 From: Ali Ince Date: Tue, 7 Jan 2025 10:02:51 +0100 Subject: [PATCH 03/29] chore: add example for tag collections --- apps/enmeshed/assets/tag_example.json | 113 ++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 apps/enmeshed/assets/tag_example.json diff --git a/apps/enmeshed/assets/tag_example.json b/apps/enmeshed/assets/tag_example.json new file mode 100644 index 000000000..805717b1a --- /dev/null +++ b/apps/enmeshed/assets/tag_example.json @@ -0,0 +1,113 @@ +{ + "supportedLanguages": ["de", "en"], + "tagsForAttributeValueTypes": { + "IdentityFileReference": { + "schulabschluss": { + "displayNames": { + "de": "Abschluss", + "en": "Degree" + }, + "children": { + "realschule": { + "displayNames": { + "de": "Realschule", + "en": "Secondary School" + }, + "children": { + "zeugnis": { + "displayNames": { + "de": "Zeugnis", + "en": "Diploma" + } + } + } + }, + "gymnasium": { + "displayNames": { + "de": "Gymnasium", + "en": "High School" + }, + "children": { + "zeugnis": { + "displayNames": { + "de": "Zeugnis", + "en": "Diploma" + } + }, + "abitur": { + "displayNames": { + "de": "Abitur", + "en": "A-Level Certificate" + } + } + } + } + } + }, + "versicherungsunterlagen": { + "displayNames": { + "de": "Versicherungsunterlagen", + "en": "Insurance documents" + }, + "children": { + "haftpflichtversicherung": { + "displayNames": { + "de": "Haftpflichtversicherung", + "en": "Liability Insurance" + }, + "children": { + "police": { + "displayNames": { + "de": "Versicherungspolice", + "en": "Insurance Policy" + } + } + } + }, + "krankenversicherung": { + "displayNames": { + "de": "Krankenversicherung", + "en": "Health Insurance" + }, + "children": { + "karte": { + "displayNames": { + "de": "Versicherungskarte", + "en": "Insurance Card" + } + }, + "nachweise": { + "displayNames": { + "de": "Nachweise", + "en": "Proofs" + } + } + } + } + } + } + }, + "PhoneNumber": { + "notfall": { + "displayNames": { + "de": "Notfallkontakt", + "en": "Emergency Contact" + } + } + }, + "StreetAddress": { + "lieferung": { + "displayNames": { + "de": "Lieferadresse", + "en": "Deliver Address" + } + }, + "heimat": { + "displayNames": { + "de": "Heimatadresse", + "en": "Home Address" + } + } + } + } + } \ No newline at end of file From d8cc59e8ef204aa99c1d5b25a014bff1805e7c66 Mon Sep 17 00:00:00 2001 From: Ali Ince Date: Tue, 7 Jan 2025 10:03:56 +0100 Subject: [PATCH 04/29] chore: reload files on pop --- apps/enmeshed/lib/account/my_data/file/files_screen.dart | 6 ++++-- apps/enmeshed/lib/core/widgets/file_item.dart | 8 +++++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/apps/enmeshed/lib/account/my_data/file/files_screen.dart b/apps/enmeshed/lib/account/my_data/file/files_screen.dart index 8f5b99a96..139f8d7f4 100644 --- a/apps/enmeshed/lib/account/my_data/file/files_screen.dart +++ b/apps/enmeshed/lib/account/my_data/file/files_screen.dart @@ -127,6 +127,7 @@ class _FilesScreenState extends State { accountId: widget.accountId, fileRecord: _filteredFileRecords[index], trailing: const Icon(Icons.chevron_right), + reload: () => _loadFiles(), ), itemCount: _filteredFileRecords.length, separatorBuilder: (context, index) => const Divider(height: 2, indent: 16), @@ -255,13 +256,14 @@ class _FilesScreenState extends State { fileRecord: item, query: keyword, accountId: widget.accountId, - onTap: () { + onTap: () async { controller ..clear() ..closeView(null); FocusScope.of(context).unfocus(); - context.push('/account/${widget.accountId}/my-data/files/${item.file.id}', extra: item); + await context.push('/account/${widget.accountId}/my-data/files/${item.file.id}', extra: item); + _loadFiles(); }, ), ); diff --git a/apps/enmeshed/lib/core/widgets/file_item.dart b/apps/enmeshed/lib/core/widgets/file_item.dart index 8bd297af3..a56e627ef 100644 --- a/apps/enmeshed/lib/core/widgets/file_item.dart +++ b/apps/enmeshed/lib/core/widgets/file_item.dart @@ -12,6 +12,7 @@ class FileItem extends StatelessWidget { final Widget? trailing; final String? query; final void Function()? onTap; + final VoidCallback? reload; const FileItem({ required this.accountId, @@ -19,6 +20,7 @@ class FileItem extends StatelessWidget { this.trailing, this.query, this.onTap, + this.reload, super.key, }); @@ -47,7 +49,11 @@ class FileItem extends StatelessWidget { ), leading: FileIcon(filename: fileRecord.file.filename), trailing: trailing, - onTap: onTap ?? () => context.push('/account/$accountId/my-data/files/${fileRecord.file.id}', extra: fileRecord), + onTap: onTap ?? + () async { + await context.push('/account/$accountId/my-data/files/${fileRecord.file.id}', extra: fileRecord); + if (reload != null) reload!(); + }, ); } } From a96d0d1a13ba3b11541b2bc2fc20ea551cfbed70 Mon Sep 17 00:00:00 2001 From: Ali Ince Date: Tue, 7 Jan 2025 10:06:19 +0100 Subject: [PATCH 05/29] refactor: outsource file infos --- .../file/widgets/file_info_container.dart | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 apps/enmeshed/lib/account/my_data/file/widgets/file_info_container.dart diff --git a/apps/enmeshed/lib/account/my_data/file/widgets/file_info_container.dart b/apps/enmeshed/lib/account/my_data/file/widgets/file_info_container.dart new file mode 100644 index 000000000..5690db5d3 --- /dev/null +++ b/apps/enmeshed/lib/account/my_data/file/widgets/file_info_container.dart @@ -0,0 +1,54 @@ +import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; + +import '/core/constants.dart'; +import '/core/utils/extensions.dart'; + +class FileInfoContainer extends StatelessWidget { + final String createdBy; + final String createdAt; + + const FileInfoContainer({required this.createdBy, required this.createdAt, super.key}); + + @override + Widget build(BuildContext context) { + return Container( + padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 6), + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.primaryContainer, + borderRadius: BorderRadius.circular(4), + ), + child: Row( + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + '${context.l10n.files_owner}: ', + style: Theme.of(context).textTheme.labelLarge!.copyWith(color: Theme.of(context).colorScheme.onSurfaceVariant), + ), + Text( + '${context.l10n.files_createdAt}: ', + style: Theme.of(context).textTheme.labelLarge!.copyWith(color: Theme.of(context).colorScheme.onSurfaceVariant), + ), + ], + ), + Gaps.w24, + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(context.i18nTranslate(createdBy), style: Theme.of(context).textTheme.bodyMedium), + Text(context.i18nTranslate(_formatDate(context, createdAt)), style: Theme.of(context).textTheme.bodyMedium), + ], + ), + ], + ), + ); + } + + String _formatDate(BuildContext context, String date) { + final locale = Localizations.localeOf(context); + final parsedDate = DateTime.parse(date).toLocal(); + return DateFormat('EEEE, d. MMMM y', locale.toString()).format(parsedDate); + } +} From 9b012a2929f65b84c80b4604cea69258127ee49c Mon Sep 17 00:00:00 2001 From: Ali Ince Date: Tue, 7 Jan 2025 10:08:23 +0100 Subject: [PATCH 06/29] feat: implement tagging and updating of tags --- .../my_data/file/modals/edit_file.dart | 181 ++++++++++++++++++ .../my_data/file/utils/get_tag_label.dart | 13 ++ .../file/widgets/available_tags_section.dart | 92 +++++++++ .../file/widgets/file_tags_container.dart | 44 +++++ .../file/widgets/selected_tag_section.dart | 94 +++++++++ 5 files changed, 424 insertions(+) create mode 100644 apps/enmeshed/lib/account/my_data/file/modals/edit_file.dart create mode 100644 apps/enmeshed/lib/account/my_data/file/utils/get_tag_label.dart create mode 100644 apps/enmeshed/lib/account/my_data/file/widgets/available_tags_section.dart create mode 100644 apps/enmeshed/lib/account/my_data/file/widgets/file_tags_container.dart create mode 100644 apps/enmeshed/lib/account/my_data/file/widgets/selected_tag_section.dart diff --git a/apps/enmeshed/lib/account/my_data/file/modals/edit_file.dart b/apps/enmeshed/lib/account/my_data/file/modals/edit_file.dart new file mode 100644 index 000000000..87753a405 --- /dev/null +++ b/apps/enmeshed/lib/account/my_data/file/modals/edit_file.dart @@ -0,0 +1,181 @@ +import 'package:enmeshed_runtime_bridge/enmeshed_runtime_bridge.dart'; +import 'package:enmeshed_types/enmeshed_types.dart'; +import 'package:flutter/material.dart'; +import 'package:get_it/get_it.dart'; +import 'package:go_router/go_router.dart'; + +import '/core/core.dart'; +import '../widgets/available_tags_section.dart'; +import '../widgets/selected_tag_section.dart'; + +class EditFile extends StatefulWidget { + final String accountId; + final String fileTitle; + final LocalAttributeDVO fileReferenceAttribute; + final AttributeTagCollectionDTO? tagCollection; + final void Function({String? attributeId}) onSave; + + const EditFile( + {required this.accountId, required this.fileTitle, required this.fileReferenceAttribute, this.tagCollection, required this.onSave, super.key}); + + @override + State createState() => _EditFileState(); +} + +class _EditFileState extends State { + late final TextEditingController _titleController; + bool _loading = false; + + String _selectedTags = ''; + + List get _selectedTagsList => _selectedTags.isEmpty ? [] : _selectedTags.split('+%+'); + + @override + void initState() { + super.initState(); + + _titleController = TextEditingController(text: widget.fileTitle)..addListener(() => setState(() {})); + if (widget.fileReferenceAttribute.tags != null && widget.fileReferenceAttribute.tags!.isNotEmpty) { + _selectedTags = widget.fileReferenceAttribute.tags!.first; + } + } + + @override + void dispose() { + super.dispose(); + _titleController.dispose(); + } + + @override + Widget build(BuildContext context) { + return Stack( + children: [ + Padding( + padding: EdgeInsets.only(top: 16, left: 24, right: 24, bottom: MediaQuery.viewInsetsOf(context).bottom + 24), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Text(context.l10n.files_editFile, style: Theme.of(context).textTheme.titleLarge), + Gaps.h24, + Text(context.l10n.mandatoryField), + Gaps.h24, + TextField( + controller: _titleController, + readOnly: true, + decoration: InputDecoration( + suffixIcon: IconButton(onPressed: null, icon: const Icon(Icons.cancel_outlined)), + labelText: context.l10n.title, + border: OutlineInputBorder( + borderRadius: const BorderRadius.all(Radius.circular(8)), + borderSide: BorderSide(color: Theme.of(context).colorScheme.outline), + ), + focusedBorder: OutlineInputBorder( + borderRadius: const BorderRadius.all(Radius.circular(8)), + borderSide: BorderSide(color: Theme.of(context).colorScheme.primary), + ), + ), + ), + Gaps.h40, + Text(context.l10n.files_tags, style: Theme.of(context).textTheme.titleMedium), + Gaps.h24, + Text(context.l10n.files_assignTagsDescription, style: Theme.of(context).textTheme.bodySmall?.copyWith(letterSpacing: 0.4)), + Gaps.h24, + if (_selectedTags.isNotEmpty) ...[ + SelectedTagSection( + tagCollection: widget.tagCollection, + selectedTagsList: _selectedTagsList, + onTagDeleted: (tagPath) { + setState(() { + final tagIndex = _selectedTagsList.indexOf(tagPath); + if (tagIndex != -1) { + _selectedTags = tagIndex == 0 ? '' : _selectedTagsList.take(tagIndex).join('+%+'); + } + }); + }, + ), + ], + if (widget.tagCollection != null) ...[ + Gaps.h24, + AvailableTagsSection( + tagCollection: widget.tagCollection, + selectedTags: _selectedTagsList, + onTagSelected: _handleTagSelected, + ), + ], + Gaps.h24, + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + TextButton(onPressed: () => Navigator.of(context).pop(), child: const Text('Abbrechen')), + Gaps.w8, + FilledButton(onPressed: _confirmEnabled ? _confirm : null, child: const Text('Speichern')), + ], + ), + ], + ), + ), + if (_loading) const ModalLoadingOverlay(text: 'Dokument wird gespeichert...', isDialog: false), + ], + ); + } + + bool get _confirmEnabled => _titleController.text.isNotEmpty; + + Future _confirm() async { + if (_confirmEnabled) setState(() => _loading = true); + + final session = GetIt.I.get().getSession(widget.accountId); + + final succeedAttributeResult = await session.consumptionServices.attributes.succeedRepositoryAttribute( + predecessorId: widget.fileReferenceAttribute.id, + value: (widget.fileReferenceAttribute as RepositoryAttributeDVO).value as IdentityFileReferenceAttributeValue, + tags: [_selectedTags], + ); + + if (succeedAttributeResult.isError) { + if (!mounted) return; + + await showDialog( + context: context, + builder: (context) { + return AlertDialog( + title: Text(context.l10n.error, style: Theme.of(context).textTheme.titleLarge), + content: Text(context.l10n.error_succeedAttribute), + ); + }, + ); + + setState(() => _loading = false); + return; + } + + widget.onSave(attributeId: succeedAttributeResult.value.successor.id); + if (mounted) context.pop(); + } + + void _handleTagSelected({ + required String tagPath, + required AttributeTagDTO tagData, + required bool selected, + }) { + if (selected) { + final pathParts = tagPath.split('.'); + final lastPart = pathParts.last; + + if (_selectedTagsList.isEmpty) { + setState(() => _selectedTags = pathParts.first); + + return; + } + + setState(() => _selectedTags = [..._selectedTagsList, lastPart].join('+%+')); + } else { + final pathParts = tagPath.split('.'); + final lastPart = pathParts.last; + + final tagIndex = _selectedTagsList.indexOf(lastPart); + if (tagIndex != -1) setState(() => _selectedTags = tagIndex == 0 ? '' : _selectedTagsList.take(tagIndex).join('+%+')); + } + } +} diff --git a/apps/enmeshed/lib/account/my_data/file/utils/get_tag_label.dart b/apps/enmeshed/lib/account/my_data/file/utils/get_tag_label.dart new file mode 100644 index 000000000..cec759d86 --- /dev/null +++ b/apps/enmeshed/lib/account/my_data/file/utils/get_tag_label.dart @@ -0,0 +1,13 @@ +import 'package:enmeshed_types/enmeshed_types.dart'; +import 'package:flutter/material.dart'; + +String getTagLabel(BuildContext context, AttributeTagCollectionDTO? tagCollection, AttributeTagDTO tagData) { + final displayNames = tagData.displayNames; + final currentLocale = Localizations.localeOf(context).languageCode; + + if (tagCollection != null && tagCollection.supportedLanguages.contains(currentLocale) && displayNames.containsKey(currentLocale)) { + return displayNames[currentLocale]!; + } + + return displayNames['en']!; +} diff --git a/apps/enmeshed/lib/account/my_data/file/widgets/available_tags_section.dart b/apps/enmeshed/lib/account/my_data/file/widgets/available_tags_section.dart new file mode 100644 index 000000000..419434e16 --- /dev/null +++ b/apps/enmeshed/lib/account/my_data/file/widgets/available_tags_section.dart @@ -0,0 +1,92 @@ +import 'package:enmeshed_types/enmeshed_types.dart'; +import 'package:flutter/material.dart'; + +import '/core/constants.dart'; +import '/core/utils/extensions.dart'; +import '../utils/get_tag_label.dart'; + +typedef AvailableTagsData = ({Map tagsMap, String currentPath}); + +class AvailableTagsSection extends StatelessWidget { + final AttributeTagCollectionDTO? tagCollection; + final List selectedTags; + final void Function({ + required String tagPath, + required AttributeTagDTO tagData, + required bool selected, + }) onTagSelected; + + const AvailableTagsSection({required this.tagCollection, required this.selectedTags, required this.onTagSelected, super.key}); + + @override + Widget build(BuildContext context) { + if (tagCollection == null) return const SizedBox.shrink(); + + final availableTagsData = _getAvailableTagsData(); + if (availableTagsData == null) return const SizedBox.shrink(); + + final currentPath = availableTagsData.currentPath; + + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(context.l10n.files_availableTags, style: Theme.of(context).textTheme.titleMedium), + Gaps.h8, + Wrap( + spacing: 10, + children: availableTagsData.tagsMap.entries.map((entry) { + return FilterChip( + label: Text(getTagLabel(context, tagCollection, entry.value)), + selected: selectedTags.contains(entry.key.split('.').last), + onSelected: (selected) => onTagSelected( + tagPath: currentPath.isEmpty ? entry.key : '$currentPath.${entry.key}', + tagData: entry.value, + selected: selected, + ), + ); + }).toList(), + ) + ], + ); + } + + AvailableTagsData? _getAvailableTagsData() { + var currentLevel = tagCollection!.tagsForAttributeValueTypes['IdentityFileReference'] ?? {}; + + if (selectedTags.isEmpty) return (tagsMap: currentLevel, currentPath: ''); + + String currentPath = ''; + for (var i = 0; i < selectedTags.length; i++) { + final tag = selectedTags[i]; + + if (i == 0) { + if (!currentLevel.containsKey(tag)) { + return (tagsMap: currentLevel, currentPath: ''); + } + currentPath = tag; + currentLevel = currentLevel[tag]!.children ?? {}; + } else { + var found = false; + String? nextPath; + Map? nextLevel; + + currentLevel.forEach((key, value) { + if (key.split('.').last == tag && !found) { + nextPath = currentPath.isEmpty ? key : '$currentPath.$key'; + nextLevel = value.children ?? {}; + found = true; + } + }); + + if (!found) return (tagsMap: currentLevel, currentPath: currentPath); + + currentPath = nextPath!; + currentLevel = nextLevel!; + } + } + + if (currentLevel.isEmpty) return null; + + return (tagsMap: currentLevel, currentPath: currentPath); + } +} diff --git a/apps/enmeshed/lib/account/my_data/file/widgets/file_tags_container.dart b/apps/enmeshed/lib/account/my_data/file/widgets/file_tags_container.dart new file mode 100644 index 000000000..60d5e9baf --- /dev/null +++ b/apps/enmeshed/lib/account/my_data/file/widgets/file_tags_container.dart @@ -0,0 +1,44 @@ +import 'package:enmeshed_types/enmeshed_types.dart'; +import 'package:flutter/material.dart'; + +import '/core/constants.dart'; +import '/core/utils/extensions.dart'; +import 'selected_tag_section.dart'; + +class FileTagsContainer extends StatelessWidget { + final List? tags; + final AttributeTagCollectionDTO? tagCollection; + final VoidCallback onEditFile; + + const FileTagsContainer({required this.tags, required this.tagCollection, required this.onEditFile, super.key}); + + @override + Widget build(BuildContext context) { + if (tags == null) { + return Container( + padding: const EdgeInsets.only(top: 16, bottom: 24, left: 16, right: 16), + color: Theme.of(context).colorScheme.surfaceContainer, + child: Column( + children: [ + Row( + children: [ + Icon(Icons.warning_rounded, color: context.customColors.warning), + Gaps.w8, + Text(context.l10n.files_assignTags), + ], + ), + Gaps.h16, + Text(context.l10n.files_assignTagsDescription, style: Theme.of(context).textTheme.bodySmall), + Gaps.h24, + OutlinedButton( + onPressed: onEditFile, + child: Text(context.l10n.files_assignTagsButton), + ), + ], + ), + ); + } + + return SelectedTagSection(tagCollection: tagCollection, selectedTagsList: tags!); + } +} diff --git a/apps/enmeshed/lib/account/my_data/file/widgets/selected_tag_section.dart b/apps/enmeshed/lib/account/my_data/file/widgets/selected_tag_section.dart new file mode 100644 index 000000000..d6ddc6b35 --- /dev/null +++ b/apps/enmeshed/lib/account/my_data/file/widgets/selected_tag_section.dart @@ -0,0 +1,94 @@ +import 'package:enmeshed_types/enmeshed_types.dart'; +import 'package:flutter/material.dart'; + +import '/core/constants.dart'; +import '/core/utils/extensions.dart'; +import '../utils/get_tag_label.dart'; + +class SelectedTagSection extends StatelessWidget { + final AttributeTagCollectionDTO? tagCollection; + final List selectedTagsList; + final void Function(String)? onTagDeleted; + + const SelectedTagSection({required this.tagCollection, required this.selectedTagsList, this.onTagDeleted, super.key}); + + @override + Widget build(BuildContext context) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (onTagDeleted != null) ...[ + Text(context.l10n.files_selectedTags, style: Theme.of(context).textTheme.titleMedium), + Gaps.h8, + ], + Wrap( + spacing: onTagDeleted == null ? 4 : 10, + crossAxisAlignment: WrapCrossAlignment.center, + children: selectedTagsList.asMap().entries.expand((entry) { + final index = entry.key; + final tagPath = entry.value; + final tag = _getTagByPath(tagPath); + if (tag == null) return const []; + + return [ + Chip( + label: Text( + getTagLabel(context, tagCollection, tag), + style: Theme.of(context).textTheme.labelLarge?.copyWith(color: Theme.of(context).colorScheme.onSecondaryContainer), + ), + deleteIcon: const Icon(Icons.close), + backgroundColor: Theme.of(context).colorScheme.secondaryContainer, + side: BorderSide.none, + onDeleted: onTagDeleted != null ? () => onTagDeleted!(tagPath) : null, + padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 4), + ), + if (onTagDeleted == null && index < selectedTagsList.length - 1) + Icon( + Icons.arrow_forward_ios, + size: 12, + color: Theme.of(context).colorScheme.secondaryContainer, + ), + ]; + }).toList(), + ), + ], + ); + } + + AttributeTagDTO? _getTagByPath(String simplifiedTag) { + if (tagCollection == null) return null; + + var currentLevel = tagCollection!.tagsForAttributeValueTypes['IdentityFileReference'] ?? {}; + + for (var i = 0; i < selectedTagsList.length; i++) { + final tag = selectedTagsList[i]; + if (tag == simplifiedTag) { + if (i == 0) return currentLevel[tag]; + + for (var j = 0; j < i; j++) { + final previousTag = selectedTagsList[j]; + if (j == 0) { + currentLevel = currentLevel[previousTag]!.children ?? {}; + } else { + var found = false; + currentLevel.forEach((key, value) { + if (key.split('.').last == previousTag && !found) { + currentLevel = value.children ?? {}; + found = true; + } + }); + } + } + + AttributeTagDTO? foundTag; + currentLevel.forEach((key, value) { + if (key.split('.').last == tag) foundTag = value; + }); + + return foundTag; + } + } + + return null; + } +} From 781ce74b74aa7cf53e527d167972c8c786ae9def Mon Sep 17 00:00:00 2001 From: Ali Ince Date: Tue, 7 Jan 2025 10:08:36 +0100 Subject: [PATCH 07/29] chore: update file detail screen --- .../my_data/file/file_detail_screen.dart | 191 +++++++++--------- 1 file changed, 98 insertions(+), 93 deletions(-) diff --git a/apps/enmeshed/lib/account/my_data/file/file_detail_screen.dart b/apps/enmeshed/lib/account/my_data/file/file_detail_screen.dart index 827827466..0930d7d7c 100644 --- a/apps/enmeshed/lib/account/my_data/file/file_detail_screen.dart +++ b/apps/enmeshed/lib/account/my_data/file/file_detail_screen.dart @@ -1,10 +1,15 @@ +import 'dart:convert'; + import 'package:enmeshed_runtime_bridge/enmeshed_runtime_bridge.dart'; import 'package:enmeshed_types/enmeshed_types.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:get_it/get_it.dart'; -import 'package:intl/intl.dart'; import '/core/core.dart'; +import 'modals/edit_file.dart'; +import 'widgets/file_info_container.dart'; +import 'widgets/file_tags_container.dart'; class FileDetailScreen extends StatefulWidget { final String accountId; @@ -25,8 +30,13 @@ class FileDetailScreen extends StatefulWidget { } class _FileDetailScreenState extends State { + late final Session _session; + FileDVO? _fileDVO; + LocalAttributeDVO? _fileReferenceAttribute; List? _tags; + AttributeTagCollectionDTO? _tagCollection; + bool _isLoadingFile = false; bool _isOpeningFile = false; @@ -34,123 +44,104 @@ class _FileDetailScreenState extends State { void initState() { super.initState(); + _session = GetIt.I.get().getSession(widget.accountId); + _fileDVO = widget.preLoadedFile; + _fileReferenceAttribute = widget.fileReferenceAttribute; _tags = widget.fileReferenceAttribute?.tags; - if (_fileDVO == null) _load(); + _load(); } @override Widget build(BuildContext context) { return Scaffold( resizeToAvoidBottomInset: false, - appBar: AppBar( - title: Text(_fileDVO!.title, style: Theme.of(context).textTheme.titleLarge), - ), + appBar: AppBar(title: Text(_fileDVO!.title, style: Theme.of(context).textTheme.titleLarge)), body: SafeArea( child: Padding( - padding: EdgeInsets.only(top: 8, left: 24, right: 24, bottom: MediaQuery.viewInsetsOf(context).bottom + 42), - child: _fileDVO == null - ? const Center(child: CircularProgressIndicator()) - : Column( - crossAxisAlignment: CrossAxisAlignment.start, + padding: EdgeInsets.only(top: 16, left: 16, right: 16, bottom: MediaQuery.viewInsetsOf(context).bottom + 42), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Center( + child: Column( children: [ - Center( - child: Column( - children: [ - FileIcon(filename: _fileDVO!.filename, color: Theme.of(context).colorScheme.primaryContainer, size: 40), - Gaps.h8, - Text(_fileDVO!.filename, style: Theme.of(context).textTheme.labelLarge), - Text('${bytesText(context: context, bytes: _fileDVO!.filesize)} - ${getFileExtension(_fileDVO!.filename)}'), - ], - ), - ), - Gaps.h24, - if (_tags != null) - Chip( - label: Text( - _tags!.join(', '), - style: TextStyle(color: Theme.of(context).colorScheme.onSecondaryContainer), - ), - shape: RoundedRectangleBorder( - borderRadius: const BorderRadius.all(Radius.circular(8)), - side: BorderSide(color: Theme.of(context).colorScheme.secondaryContainer), - ), - backgroundColor: Theme.of(context).colorScheme.secondaryContainer, - padding: EdgeInsets.zero, - labelPadding: const EdgeInsets.symmetric(horizontal: 6), - ), - Row( - children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - '${context.l10n.files_owner}: ', - style: Theme.of(context).textTheme.labelLarge!.copyWith(color: Theme.of(context).colorScheme.onSurfaceVariant), - ), - Text( - '${context.l10n.files_createdAt}: ', - style: Theme.of(context).textTheme.labelLarge!.copyWith(color: Theme.of(context).colorScheme.onSurfaceVariant), - ), - ], - ), - Gaps.w24, - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - context.i18nTranslate(_fileDVO!.createdBy.name), - style: Theme.of(context).textTheme.bodyMedium, - ), - Text( - context.i18nTranslate(_formatDate(context, _fileDVO!.createdAt)), - style: Theme.of(context).textTheme.bodyMedium, - ), - ], - ), - ], - ), - Gaps.h32, - Row( - children: [ - Gaps.w8, - IconButton( - onPressed: _isLoadingFile || DateTime.parse(_fileDVO!.expiresAt).isBefore(DateTime.now()) ? null : _downloadAndSaveFile, - icon: _isLoadingFile - ? const SizedBox(width: 24, height: 24, child: CircularProgressIndicator()) - : const Icon(Icons.file_download, size: 24), - ), - Gaps.w8, - IconButton( - onPressed: _isOpeningFile || DateTime.parse(_fileDVO!.expiresAt).isBefore(DateTime.now()) ? null : _openFile, - icon: _isOpeningFile - ? const SizedBox(width: 24, height: 24, child: CircularProgressIndicator()) - : const Icon(Icons.open_with, size: 24), - ), - ], - ), + FileIcon(filename: _fileDVO!.filename, color: Theme.of(context).colorScheme.primary, size: 40), + Gaps.h8, + Text(_fileDVO!.filename, style: Theme.of(context).textTheme.labelLarge), + Text('${bytesText(context: context, bytes: _fileDVO!.filesize)} - ${getFileExtension(_fileDVO!.filename)}'), ], ), + ), + Gaps.h48, + if (_fileReferenceAttribute != null) ...[ + FileTagsContainer(tags: _tags?.first.split('+%+'), tagCollection: _tagCollection, onEditFile: _onEditFilePressed), + Gaps.h16, + ], + FileInfoContainer(createdBy: _fileDVO!.createdBy.name, createdAt: _fileDVO!.createdAt), + Gaps.h32, + Row( + children: [ + if (_fileReferenceAttribute != null) IconButton(onPressed: _onEditFilePressed, icon: const Icon(Icons.edit_outlined, size: 24)), + Gaps.w8, + IconButton( + onPressed: _isLoadingFile || DateTime.parse(_fileDVO!.expiresAt).isBefore(DateTime.now()) ? null : _downloadAndSaveFile, + icon: _isLoadingFile + ? const SizedBox(width: 24, height: 24, child: CircularProgressIndicator()) + : const Icon(Icons.file_download, size: 24), + ), + Gaps.w8, + IconButton( + onPressed: _isOpeningFile || DateTime.parse(_fileDVO!.expiresAt).isBefore(DateTime.now()) ? null : _openFile, + icon: _isOpeningFile + ? const SizedBox(width: 24, height: 24, child: CircularProgressIndicator()) + : const Icon(Icons.open_with, size: 24), + ), + ], + ), + ], + ), ), ), ); } - String _formatDate(BuildContext context, String date) { - final locale = Localizations.localeOf(context); - final parsedDate = DateTime.parse(date).toLocal(); - return DateFormat('EEEE, d. MMMM y', locale.toString()).format(parsedDate); + Future _load() async { + await _loadFile(); + await _loadTagCollection(); + await _loadTags(); } - Future _load() async { - final session = GetIt.I.get().getSession(widget.accountId); - final response = await session.transportServices.files.getFile(fileId: widget.preLoadedFile.id); - final expanded = await session.expander.expandFileDTO(response.value); + Future _loadFile() async { + final response = await _session.transportServices.files.getFile(fileId: widget.preLoadedFile.id); + final expanded = await _session.expander.expandFileDTO(response.value); setState(() => _fileDVO = expanded); } + Future _loadTagCollection() async { + // TODO: (aince) this is a temporary solution to load the tag collection + final jsonString = await rootBundle.loadString('assets/tag_example.json'); + final jsonData = json.decode(jsonString) as Map; + final tagCollection = AttributeTagCollectionDTO.fromJson(jsonData); + // final tagCollection = await _session.consumptionServices.attributes.getAttributeTagCollection(); + + setState(() => _tagCollection = tagCollection); + } + + Future _loadTags({String? attributeId}) async { + if (_fileReferenceAttribute != null) { + final response = await _session.consumptionServices.attributes.getAttribute(attributeId: attributeId ?? _fileReferenceAttribute!.id); + final expanded = await _session.expander.expandLocalAttributeDTO(response.value); + + setState(() { + _tags = expanded.tags; + _fileReferenceAttribute = expanded; + }); + } + } + Future _downloadAndSaveFile() async { setState(() => _isLoadingFile = true); @@ -180,4 +171,18 @@ class _FileDetailScreenState extends State { if (mounted) setState(() => _isOpeningFile = false); } + + void _onEditFilePressed() { + showModalBottomSheet( + context: context, + isScrollControlled: true, + builder: (_) => EditFile( + accountId: widget.accountId, + fileTitle: _fileDVO!.title, + fileReferenceAttribute: _fileReferenceAttribute!, + tagCollection: _tagCollection, + onSave: _loadTags, + ), + ); + } } From a8f5c0f1daa3fbf67a7bbf046096221b5d8c8271 Mon Sep 17 00:00:00 2001 From: Ali Ince Date: Wed, 8 Jan 2025 09:42:04 +0100 Subject: [PATCH 08/29] fix: linter errors --- .../account/my_data/file/file_detail_screen.dart | 10 +++++----- .../lib/account/my_data/file/files_screen.dart | 4 ++-- .../lib/account/my_data/file/modals/edit_file.dart | 14 ++++++++++---- .../file/widgets/available_tags_section.dart | 4 ++-- apps/enmeshed/lib/core/widgets/file_item.dart | 2 +- 5 files changed, 20 insertions(+), 14 deletions(-) diff --git a/apps/enmeshed/lib/account/my_data/file/file_detail_screen.dart b/apps/enmeshed/lib/account/my_data/file/file_detail_screen.dart index 0930d7d7c..9a0220514 100644 --- a/apps/enmeshed/lib/account/my_data/file/file_detail_screen.dart +++ b/apps/enmeshed/lib/account/my_data/file/file_detail_screen.dart @@ -32,10 +32,10 @@ class FileDetailScreen extends StatefulWidget { class _FileDetailScreenState extends State { late final Session _session; - FileDVO? _fileDVO; - LocalAttributeDVO? _fileReferenceAttribute; - List? _tags; - AttributeTagCollectionDTO? _tagCollection; + late FileDVO? _fileDVO; + late LocalAttributeDVO? _fileReferenceAttribute; + late List? _tags; + late AttributeTagCollectionDTO? _tagCollection; bool _isLoadingFile = false; bool _isOpeningFile = false; @@ -121,7 +121,7 @@ class _FileDetailScreenState extends State { } Future _loadTagCollection() async { - // TODO: (aince) this is a temporary solution to load the tag collection + // TODO(aince42): this is a temporary solution to load the tag collection final jsonString = await rootBundle.loadString('assets/tag_example.json'); final jsonData = json.decode(jsonString) as Map; final tagCollection = AttributeTagCollectionDTO.fromJson(jsonData); diff --git a/apps/enmeshed/lib/account/my_data/file/files_screen.dart b/apps/enmeshed/lib/account/my_data/file/files_screen.dart index 139f8d7f4..34a6cff8e 100644 --- a/apps/enmeshed/lib/account/my_data/file/files_screen.dart +++ b/apps/enmeshed/lib/account/my_data/file/files_screen.dart @@ -127,7 +127,7 @@ class _FilesScreenState extends State { accountId: widget.accountId, fileRecord: _filteredFileRecords[index], trailing: const Icon(Icons.chevron_right), - reload: () => _loadFiles(), + reload: _loadFiles, ), itemCount: _filteredFileRecords.length, separatorBuilder: (context, index) => const Divider(height: 2, indent: 16), @@ -263,7 +263,7 @@ class _FilesScreenState extends State { FocusScope.of(context).unfocus(); await context.push('/account/${widget.accountId}/my-data/files/${item.file.id}', extra: item); - _loadFiles(); + unawaited(_loadFiles()); }, ), ); diff --git a/apps/enmeshed/lib/account/my_data/file/modals/edit_file.dart b/apps/enmeshed/lib/account/my_data/file/modals/edit_file.dart index 87753a405..a17bffaa8 100644 --- a/apps/enmeshed/lib/account/my_data/file/modals/edit_file.dart +++ b/apps/enmeshed/lib/account/my_data/file/modals/edit_file.dart @@ -12,11 +12,17 @@ class EditFile extends StatefulWidget { final String accountId; final String fileTitle; final LocalAttributeDVO fileReferenceAttribute; - final AttributeTagCollectionDTO? tagCollection; final void Function({String? attributeId}) onSave; + final AttributeTagCollectionDTO? tagCollection; - const EditFile( - {required this.accountId, required this.fileTitle, required this.fileReferenceAttribute, this.tagCollection, required this.onSave, super.key}); + const EditFile({ + required this.accountId, + required this.fileTitle, + required this.fileReferenceAttribute, + required this.onSave, + this.tagCollection, + super.key, + }); @override State createState() => _EditFileState(); @@ -64,7 +70,7 @@ class _EditFileState extends State { controller: _titleController, readOnly: true, decoration: InputDecoration( - suffixIcon: IconButton(onPressed: null, icon: const Icon(Icons.cancel_outlined)), + suffixIcon: const IconButton(onPressed: null, icon: Icon(Icons.cancel_outlined)), labelText: context.l10n.title, border: OutlineInputBorder( borderRadius: const BorderRadius.all(Radius.circular(8)), diff --git a/apps/enmeshed/lib/account/my_data/file/widgets/available_tags_section.dart b/apps/enmeshed/lib/account/my_data/file/widgets/available_tags_section.dart index 419434e16..f06d493f0 100644 --- a/apps/enmeshed/lib/account/my_data/file/widgets/available_tags_section.dart +++ b/apps/enmeshed/lib/account/my_data/file/widgets/available_tags_section.dart @@ -45,7 +45,7 @@ class AvailableTagsSection extends StatelessWidget { ), ); }).toList(), - ) + ), ], ); } @@ -55,7 +55,7 @@ class AvailableTagsSection extends StatelessWidget { if (selectedTags.isEmpty) return (tagsMap: currentLevel, currentPath: ''); - String currentPath = ''; + var currentPath = ''; for (var i = 0; i < selectedTags.length; i++) { final tag = selectedTags[i]; diff --git a/apps/enmeshed/lib/core/widgets/file_item.dart b/apps/enmeshed/lib/core/widgets/file_item.dart index a56e627ef..083b83821 100644 --- a/apps/enmeshed/lib/core/widgets/file_item.dart +++ b/apps/enmeshed/lib/core/widgets/file_item.dart @@ -52,7 +52,7 @@ class FileItem extends StatelessWidget { onTap: onTap ?? () async { await context.push('/account/$accountId/my-data/files/${fileRecord.file.id}', extra: fileRecord); - if (reload != null) reload!(); + reload?.call(); }, ); } From c9068d6b801513933e8a15fbadd7da6da629f7e4 Mon Sep 17 00:00:00 2001 From: Ali Ince Date: Wed, 8 Jan 2025 10:44:42 +0100 Subject: [PATCH 09/29] fix: missing translations --- apps/enmeshed/lib/account/my_data/file/modals/edit_file.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/enmeshed/lib/account/my_data/file/modals/edit_file.dart b/apps/enmeshed/lib/account/my_data/file/modals/edit_file.dart index a17bffaa8..62cdc0d94 100644 --- a/apps/enmeshed/lib/account/my_data/file/modals/edit_file.dart +++ b/apps/enmeshed/lib/account/my_data/file/modals/edit_file.dart @@ -113,9 +113,9 @@ class _EditFileState extends State { Row( mainAxisAlignment: MainAxisAlignment.end, children: [ - TextButton(onPressed: () => Navigator.of(context).pop(), child: const Text('Abbrechen')), + TextButton(onPressed: () => Navigator.of(context).pop(), child: Text(context.l10n.cancel)), Gaps.w8, - FilledButton(onPressed: _confirmEnabled ? _confirm : null, child: const Text('Speichern')), + FilledButton(onPressed: _confirmEnabled ? _confirm : null, child: Text(context.l10n.save)), ], ), ], From 5a1fb05698d4498bfa2cd1588b43597701cfc241 Mon Sep 17 00:00:00 2001 From: Ali Ince Date: Wed, 8 Jan 2025 10:45:13 +0100 Subject: [PATCH 10/29] fix: error on add new file --- apps/enmeshed/lib/core/widgets/upload_file.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/enmeshed/lib/core/widgets/upload_file.dart b/apps/enmeshed/lib/core/widgets/upload_file.dart index be6c13cfe..03e5f918a 100644 --- a/apps/enmeshed/lib/core/widgets/upload_file.dart +++ b/apps/enmeshed/lib/core/widgets/upload_file.dart @@ -21,7 +21,7 @@ import 'modal_loading_overlay.dart'; class UploadFile extends StatefulWidget { final String accountId; - final void Function(FileDVO) onFileUploaded; + final Future Function(FileDVO) onFileUploaded; final bool popOnUpload; final Widget? leading; @@ -175,7 +175,7 @@ class _UploadFileState extends State { final fileReference = await _createFileReferenceAttribute(file); - widget.onFileUploaded(file); + await widget.onFileUploaded(file); if (mounted && widget.popOnUpload) { context.pop(); From 8d0e57903eeb2cc034c5923c8ba78fc358f1b8df Mon Sep 17 00:00:00 2001 From: Ali Ince Date: Wed, 8 Jan 2025 10:45:34 +0100 Subject: [PATCH 11/29] chore: add comment for fallback --- apps/enmeshed/lib/account/my_data/file/utils/get_tag_label.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/enmeshed/lib/account/my_data/file/utils/get_tag_label.dart b/apps/enmeshed/lib/account/my_data/file/utils/get_tag_label.dart index cec759d86..9aca04755 100644 --- a/apps/enmeshed/lib/account/my_data/file/utils/get_tag_label.dart +++ b/apps/enmeshed/lib/account/my_data/file/utils/get_tag_label.dart @@ -9,5 +9,6 @@ String getTagLabel(BuildContext context, AttributeTagCollectionDTO? tagCollectio return displayNames[currentLocale]!; } + // Fallback to English return displayNames['en']!; } From dc67a5c64fd8dd5c87d73ffbdfb65c9502939612 Mon Sep 17 00:00:00 2001 From: Ali Ince Date: Wed, 8 Jan 2025 10:45:53 +0100 Subject: [PATCH 12/29] fix: late initialization error --- apps/enmeshed/lib/account/my_data/file/file_detail_screen.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/enmeshed/lib/account/my_data/file/file_detail_screen.dart b/apps/enmeshed/lib/account/my_data/file/file_detail_screen.dart index 9a0220514..c92b090ce 100644 --- a/apps/enmeshed/lib/account/my_data/file/file_detail_screen.dart +++ b/apps/enmeshed/lib/account/my_data/file/file_detail_screen.dart @@ -35,7 +35,7 @@ class _FileDetailScreenState extends State { late FileDVO? _fileDVO; late LocalAttributeDVO? _fileReferenceAttribute; late List? _tags; - late AttributeTagCollectionDTO? _tagCollection; + AttributeTagCollectionDTO? _tagCollection; bool _isLoadingFile = false; bool _isOpeningFile = false; From b9b75ddcf8cf1c68567229430f3672a15896ef2c Mon Sep 17 00:00:00 2001 From: Siolto Date: Thu, 9 Jan 2025 10:48:15 +0100 Subject: [PATCH 13/29] refactor: simplify _getAvailableTagsData() --- .../file/widgets/available_tags_section.dart | 35 ++++--------------- 1 file changed, 7 insertions(+), 28 deletions(-) diff --git a/apps/enmeshed/lib/account/my_data/file/widgets/available_tags_section.dart b/apps/enmeshed/lib/account/my_data/file/widgets/available_tags_section.dart index f06d493f0..380452736 100644 --- a/apps/enmeshed/lib/account/my_data/file/widgets/available_tags_section.dart +++ b/apps/enmeshed/lib/account/my_data/file/widgets/available_tags_section.dart @@ -52,41 +52,20 @@ class AvailableTagsSection extends StatelessWidget { AvailableTagsData? _getAvailableTagsData() { var currentLevel = tagCollection!.tagsForAttributeValueTypes['IdentityFileReference'] ?? {}; - if (selectedTags.isEmpty) return (tagsMap: currentLevel, currentPath: ''); var currentPath = ''; - for (var i = 0; i < selectedTags.length; i++) { - final tag = selectedTags[i]; - - if (i == 0) { - if (!currentLevel.containsKey(tag)) { - return (tagsMap: currentLevel, currentPath: ''); - } - currentPath = tag; - currentLevel = currentLevel[tag]!.children ?? {}; - } else { - var found = false; - String? nextPath; - Map? nextLevel; - - currentLevel.forEach((key, value) { - if (key.split('.').last == tag && !found) { - nextPath = currentPath.isEmpty ? key : '$currentPath.$key'; - nextLevel = value.children ?? {}; - found = true; - } - }); + for (final tag in selectedTags) { + if (!currentLevel.containsKey(tag)) { + return (tagsMap: currentLevel, currentPath: currentPath); + } - if (!found) return (tagsMap: currentLevel, currentPath: currentPath); + currentPath = currentPath.isEmpty ? tag : '$currentPath.$tag'; + currentLevel = currentLevel[tag]!.children ?? {}; - currentPath = nextPath!; - currentLevel = nextLevel!; - } + if (currentLevel.isEmpty) return null; } - if (currentLevel.isEmpty) return null; - return (tagsMap: currentLevel, currentPath: currentPath); } } From 2996d200f93698852d3c74e6673852cc94aa8d08 Mon Sep 17 00:00:00 2001 From: Ali Ince Date: Mon, 20 Jan 2025 10:43:01 +0100 Subject: [PATCH 14/29] fix: add missing translation --- apps/enmeshed/lib/account/my_data/file/modals/edit_file.dart | 2 +- apps/enmeshed/lib/l10n/app_de.arb | 1 + apps/enmeshed/lib/l10n/app_en.arb | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/enmeshed/lib/account/my_data/file/modals/edit_file.dart b/apps/enmeshed/lib/account/my_data/file/modals/edit_file.dart index 62cdc0d94..a5398a85d 100644 --- a/apps/enmeshed/lib/account/my_data/file/modals/edit_file.dart +++ b/apps/enmeshed/lib/account/my_data/file/modals/edit_file.dart @@ -121,7 +121,7 @@ class _EditFileState extends State { ], ), ), - if (_loading) const ModalLoadingOverlay(text: 'Dokument wird gespeichert...', isDialog: false), + if (_loading) ModalLoadingOverlay(text: context.l10n.files_saving, isDialog: false), ], ); } diff --git a/apps/enmeshed/lib/l10n/app_de.arb b/apps/enmeshed/lib/l10n/app_de.arb index e9e24f5e6..1b0041711 100644 --- a/apps/enmeshed/lib/l10n/app_de.arb +++ b/apps/enmeshed/lib/l10n/app_de.arb @@ -624,6 +624,7 @@ "files_tag": "Tag", "files_tags": "Tags", "files_editFile": "Dokument bearbeiten", + "files_saving": "Dokument wird gespeichert...", "files_selectedTags": "Ausgewählte Tags:", "files_availableTags": "Verfügbare Tags:", "filter": "Filter", diff --git a/apps/enmeshed/lib/l10n/app_en.arb b/apps/enmeshed/lib/l10n/app_en.arb index 0a2080f01..cef185b95 100644 --- a/apps/enmeshed/lib/l10n/app_en.arb +++ b/apps/enmeshed/lib/l10n/app_en.arb @@ -624,6 +624,7 @@ "files_tag": "Tag", "files_tags": "Tags", "files_editFile": "Edit file", + "files_saving": "File is being saved...", "files_selectedTags": "Selected tags:", "files_availableTags": "Available tags:", "filter": "Filter", From 8b0cbc798858926589b4db1945802b75c368793d Mon Sep 17 00:00:00 2001 From: Ali Ince Date: Mon, 20 Jan 2025 10:44:36 +0100 Subject: [PATCH 15/29] chore: update dependencies --- apps/enmeshed/ios/Podfile.lock | 36 +++++++++++++++++----------------- apps/enmeshed/pubspec.lock | 28 +++++++++++++------------- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/apps/enmeshed/ios/Podfile.lock b/apps/enmeshed/ios/Podfile.lock index cae028d6e..daa4dfce8 100644 --- a/apps/enmeshed/ios/Podfile.lock +++ b/apps/enmeshed/ios/Podfile.lock @@ -209,41 +209,41 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/url_launcher_ios/ios" SPEC CHECKSUMS: - app_links: 3da4c36b46cac3bf24eb897f1a6ce80bda109874 - croppy: 979e8ddc254f4642bffe7d52dc7193354b27ba30 - device_info_plus: 21fcca2080fbcd348be798aa36c3e5ed849eefbe + app_links: e7a6750a915a9e161c58d91bc610e8cd1d4d0ad0 + croppy: b6199bc8d56bd2e03cc11609d1c47ad9875c1321 + device_info_plus: bf2e3232933866d73fe290f2942f2156cdd10342 DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60 - file_picker: 9b3292d7c8bc68c8a7bf8eb78f730e49c8efc517 + file_picker: 09aa5ec1ab24135ccd7a1621c46c84134bfd6655 Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 - flutter_inappwebview_ios: b89ba3482b96fb25e00c967aae065701b66e9b99 - flutter_keyboard_visibility: 4625131e43015dbbe759d9b20daaf77e0e3f6619 - flutter_local_notifications: 395056b3175ba4f08480a7c5de30cd36d69827e4 - flutter_native_splash: 6cad9122ea0fad137d23137dd14b937f3e90b145 + flutter_inappwebview_ios: 6f63631e2c62a7c350263b13fa5427aedefe81d4 + flutter_keyboard_visibility: 0339d06371254c3eb25eeb90ba8d17dca8f9c069 + flutter_local_notifications: df98d66e515e1ca797af436137b4459b160ad8c9 + flutter_native_splash: f71420956eb811e6d310720fee915f1d42852e7a GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7 GoogleMLKit: eff9e23ec1d90ea4157a1ee2e32a4f610c5b3318 GoogleToolboxForMac: d1a2cbf009c453f4d6ded37c105e2f67a32206d8 GoogleUtilities: 26a3abef001b6533cf678d3eb38fd3f614b7872d GTMSessionFetcher: 5aea5ba6bd522a239e236100971f10cb71b96ab6 - image_picker_ios: 7fe1ff8e34c1790d6fff70a32484959f563a928a + image_picker_ios: c560581cceedb403a6ff17f2f816d7fea1421fc1 MLImage: 0ad1c5f50edd027672d8b26b0fee78a8b4a0fc56 MLKitBarcodeScanning: 0a3064da0a7f49ac24ceb3cb46a5bc67496facd2 MLKitCommon: 07c2c33ae5640e5380beaaa6e4b9c249a205542d MLKitVision: 45e79d68845a2de77e2dd4d7f07947f0ed157b0e - mobile_scanner: af8f71879eaba2bbcb4d86c6a462c3c0e7f23036 + mobile_scanner: fd0054c52ede661e80bf5a4dea477a2467356bee nanopb: fad817b59e0457d11a5dfbde799381cd727c1275 - open_file_ios: 5ff7526df64e4394b4fe207636b67a95e83078bb + open_file_ios: 461db5853723763573e140de3193656f91990d9e OrderedSet: e539b66b644ff081c73a262d24ad552a69be3a94 - package_info_plus: af8e2ca6888548050f16fa2f1938db7b5a5df499 - path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564 - permission_handler_apple: 4ed2196e43d0651e8ff7ca3483a069d469701f2d - printing: 54ff03f28fe9ba3aa93358afb80a8595a071dd07 + package_info_plus: c0502532a26c7662a62a356cebe2692ec5fe4ec4 + path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46 + permission_handler_apple: 9878588469a2b0d0fc1e048d9f43605f92e6cec2 + printing: 233e1b73bd1f4a05615548e9b5a324c98588640b PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 - push_ios: d8edf21b48ecb1ee9e384dd0cd9c1b049fd1ca11 + push_ios: 2bd1b4d3f782209da1f571db1250af236957e807 SDWebImage: dfe95b2466a9823cf9f0c6d01217c06550d7b29a - shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7 + shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78 SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4 - url_launcher_ios: 694010445543906933d732453a59da0a173ae33d + url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe PODFILE CHECKSUM: 4355a5654b74c37e4f7c691bc7791921e63d7f9d diff --git a/apps/enmeshed/pubspec.lock b/apps/enmeshed/pubspec.lock index dc51aec29..c58a5983b 100644 --- a/apps/enmeshed/pubspec.lock +++ b/apps/enmeshed/pubspec.lock @@ -141,10 +141,10 @@ packages: dependency: "direct main" description: name: croppy - sha256: "14bb40fd6c1771b093a907ddbf24df9aa49a4e6e379dd630602eb446e30ec629" + sha256: bf99b00023df0d7d047e04d27d496d87cbefd968f578d0bd30f342ff75570a12 url: "https://pub.dev" source: hosted - version: "1.3.1" + version: "1.3.3" cross_file: dependency: transitive description: @@ -181,18 +181,18 @@ packages: dependency: transitive description: name: dbus - sha256: "365c771ac3b0e58845f39ec6deebc76e3276aa9922b0cc60840712094d9047ac" + sha256: "79e0c23480ff85dc68de79e2cd6334add97e48f7f4865d17686dd6ea81a47e8c" url: "https://pub.dev" source: hosted - version: "0.7.10" + version: "0.7.11" device_info_plus: dependency: transitive description: name: device_info_plus - sha256: "4fa68e53e26ab17b70ca39f072c285562cfc1589df5bb1e9295db90f6645f431" + sha256: b37d37c2f912ad4e8ec694187de87d05de2a3cb82b465ff1f65f65a2d05de544 url: "https://pub.dev" source: hosted - version: "11.2.0" + version: "11.2.1" device_info_plus_platform_interface: dependency: transitive description: @@ -433,10 +433,10 @@ packages: dependency: "direct dev" description: name: flutter_launcher_icons - sha256: "31cd0885738e87c72d6f055564d37fabcdacee743b396b78c7636c169cac64f5" + sha256: bfa04787c85d80ecb3f8777bde5fc10c3de809240c48fa061a2c2bf15ea5211c url: "https://pub.dev" source: hosted - version: "0.14.2" + version: "0.14.3" flutter_local_notifications: dependency: transitive description: @@ -767,10 +767,10 @@ packages: dependency: "direct main" description: name: mobile_scanner - sha256: "728828a798d1a2ee506beb652ca23d974c542c96ed03dcbd5eaf97bef96cdaad" + sha256: "57d6269d10912d5d583606b46d963d7c5d0299d2c37add8b7192dd769d40a319" url: "https://pub.dev" source: hosted - version: "6.0.2" + version: "6.0.3" open_file: dependency: "direct main" description: @@ -839,10 +839,10 @@ packages: dependency: "direct main" description: name: package_info_plus - sha256: "70c421fe9d9cc1a9a7f3b05ae56befd469fe4f8daa3b484823141a55442d858d" + sha256: "739e0a5c3c4055152520fa321d0645ee98e932718b4c8efeeb51451968fe0790" url: "https://pub.dev" source: hosted - version: "8.1.2" + version: "8.1.3" package_info_plus_platform_interface: dependency: transitive description: @@ -1094,10 +1094,10 @@ packages: dependency: transitive description: name: shared_preferences_android - sha256: bf808be89fe9dc467475e982c1db6c2faf3d2acf54d526cd5ec37d86c99dbd84 + sha256: "138b7bbbc7f59c56236e426c37afb8f78cbc57b094ac64c440e0bb90e380a4f5" url: "https://pub.dev" source: hosted - version: "2.4.1" + version: "2.4.2" shared_preferences_foundation: dependency: transitive description: From 72fdae291619eff14487cd70cfd2492ffb9887b0 Mon Sep 17 00:00:00 2001 From: Ali Ince Date: Mon, 20 Jan 2025 10:46:02 +0100 Subject: [PATCH 16/29] chore: remove unused textfield --- apps/enmeshed/lib/core/widgets/upload_file.dart | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/apps/enmeshed/lib/core/widgets/upload_file.dart b/apps/enmeshed/lib/core/widgets/upload_file.dart index 8b8613ce4..1a78c2cb9 100644 --- a/apps/enmeshed/lib/core/widgets/upload_file.dart +++ b/apps/enmeshed/lib/core/widgets/upload_file.dart @@ -37,7 +37,6 @@ class UploadFile extends StatefulWidget { class _UploadFileState extends State { late final TextEditingController _titleController; - final _tagController = TextEditingController(); File? _selectedFile; bool _loading = false; @@ -53,7 +52,6 @@ class _UploadFileState extends State { @override void dispose() { _titleController.dispose(); - _tagController.dispose(); super.dispose(); } @@ -111,15 +109,6 @@ class _UploadFileState extends State { }), ], ), - Gaps.h8, - TextField( - controller: _tagController, - decoration: InputDecoration( - labelText: context.l10n.files_tag, - border: const OutlineInputBorder(borderRadius: BorderRadius.all(Radius.circular(8))), - focusedBorder: const OutlineInputBorder(borderRadius: BorderRadius.all(Radius.circular(8))), - ), - ), Gaps.h44, Row( mainAxisAlignment: MainAxisAlignment.end, @@ -236,7 +225,6 @@ class _UploadFileState extends State { createEnabledNotifier: createEnabledNotifier, value: IdentityFileReferenceAttributeValue(value: file.truncatedReference), onAttributeCreated: () => createEnabledNotifier.value = true, - tags: _tagController.text.isNotEmpty ? [_tagController.text] : null, ); final session = GetIt.I.get().getSession(widget.accountId); From a25c1c9a11149ad0d863b7bbab71d9c078da0b26 Mon Sep 17 00:00:00 2001 From: Ali Ince Date: Mon, 20 Jan 2025 10:46:37 +0100 Subject: [PATCH 17/29] chore: make check in file detail screen --- .../my_data/file/file_detail_screen.dart | 6 ++- .../file/widgets/file_tags_container.dart | 54 ++++++++----------- 2 files changed, 28 insertions(+), 32 deletions(-) diff --git a/apps/enmeshed/lib/account/my_data/file/file_detail_screen.dart b/apps/enmeshed/lib/account/my_data/file/file_detail_screen.dart index c92b090ce..9ec8264ba 100644 --- a/apps/enmeshed/lib/account/my_data/file/file_detail_screen.dart +++ b/apps/enmeshed/lib/account/my_data/file/file_detail_screen.dart @@ -1,5 +1,6 @@ import 'dart:convert'; +import 'package:enmeshed/account/my_data/file/widgets/selected_tag_section.dart'; import 'package:enmeshed_runtime_bridge/enmeshed_runtime_bridge.dart'; import 'package:enmeshed_types/enmeshed_types.dart'; import 'package:flutter/material.dart'; @@ -76,7 +77,10 @@ class _FileDetailScreenState extends State { ), Gaps.h48, if (_fileReferenceAttribute != null) ...[ - FileTagsContainer(tags: _tags?.first.split('+%+'), tagCollection: _tagCollection, onEditFile: _onEditFilePressed), + if (_tags == null) + FileTagsContainer(onEditFile: _onEditFilePressed) + else + SelectedTagSection(tagCollection: _tagCollection, selectedTagsList: _tags!.first.split('+%+')), Gaps.h16, ], FileInfoContainer(createdBy: _fileDVO!.createdBy.name, createdAt: _fileDVO!.createdAt), diff --git a/apps/enmeshed/lib/account/my_data/file/widgets/file_tags_container.dart b/apps/enmeshed/lib/account/my_data/file/widgets/file_tags_container.dart index 60d5e9baf..3a0e108cf 100644 --- a/apps/enmeshed/lib/account/my_data/file/widgets/file_tags_container.dart +++ b/apps/enmeshed/lib/account/my_data/file/widgets/file_tags_container.dart @@ -1,44 +1,36 @@ -import 'package:enmeshed_types/enmeshed_types.dart'; import 'package:flutter/material.dart'; import '/core/constants.dart'; import '/core/utils/extensions.dart'; -import 'selected_tag_section.dart'; class FileTagsContainer extends StatelessWidget { - final List? tags; - final AttributeTagCollectionDTO? tagCollection; final VoidCallback onEditFile; - const FileTagsContainer({required this.tags, required this.tagCollection, required this.onEditFile, super.key}); + const FileTagsContainer({required this.onEditFile, super.key}); @override Widget build(BuildContext context) { - if (tags == null) { - return Container( - padding: const EdgeInsets.only(top: 16, bottom: 24, left: 16, right: 16), - color: Theme.of(context).colorScheme.surfaceContainer, - child: Column( - children: [ - Row( - children: [ - Icon(Icons.warning_rounded, color: context.customColors.warning), - Gaps.w8, - Text(context.l10n.files_assignTags), - ], - ), - Gaps.h16, - Text(context.l10n.files_assignTagsDescription, style: Theme.of(context).textTheme.bodySmall), - Gaps.h24, - OutlinedButton( - onPressed: onEditFile, - child: Text(context.l10n.files_assignTagsButton), - ), - ], - ), - ); - } - - return SelectedTagSection(tagCollection: tagCollection, selectedTagsList: tags!); + return Container( + padding: const EdgeInsets.only(top: 16, bottom: 24, left: 16, right: 16), + color: Theme.of(context).colorScheme.surfaceContainer, + child: Column( + children: [ + Row( + children: [ + Icon(Icons.warning_rounded, color: context.customColors.warning), + Gaps.w8, + Text(context.l10n.files_assignTags), + ], + ), + Gaps.h16, + Text(context.l10n.files_assignTagsDescription, style: Theme.of(context).textTheme.bodySmall), + Gaps.h24, + OutlinedButton( + onPressed: onEditFile, + child: Text(context.l10n.files_assignTagsButton), + ), + ], + ), + ); } } From 1988aa6446183d05e722a1832beab73fd46e0d6d Mon Sep 17 00:00:00 2001 From: Ali Ince Date: Fri, 24 Jan 2025 12:39:53 +0100 Subject: [PATCH 18/29] fix: imports --- apps/enmeshed/lib/account/my_data/file/modals/edit_file.dart | 1 + .../account/my_data/file/widgets/available_tags_section.dart | 4 ++-- .../lib/account/my_data/file/widgets/file_info_container.dart | 4 ++-- .../lib/account/my_data/file/widgets/file_tags_container.dart | 4 ++-- .../account/my_data/file/widgets/selected_tag_section.dart | 4 ++-- 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/apps/enmeshed/lib/account/my_data/file/modals/edit_file.dart b/apps/enmeshed/lib/account/my_data/file/modals/edit_file.dart index a5398a85d..38fdcba60 100644 --- a/apps/enmeshed/lib/account/my_data/file/modals/edit_file.dart +++ b/apps/enmeshed/lib/account/my_data/file/modals/edit_file.dart @@ -1,5 +1,6 @@ import 'package:enmeshed_runtime_bridge/enmeshed_runtime_bridge.dart'; import 'package:enmeshed_types/enmeshed_types.dart'; +import 'package:enmeshed_ui_kit/enmeshed_ui_kit.dart'; import 'package:flutter/material.dart'; import 'package:get_it/get_it.dart'; import 'package:go_router/go_router.dart'; diff --git a/apps/enmeshed/lib/account/my_data/file/widgets/available_tags_section.dart b/apps/enmeshed/lib/account/my_data/file/widgets/available_tags_section.dart index 380452736..ea5328daf 100644 --- a/apps/enmeshed/lib/account/my_data/file/widgets/available_tags_section.dart +++ b/apps/enmeshed/lib/account/my_data/file/widgets/available_tags_section.dart @@ -1,8 +1,8 @@ import 'package:enmeshed_types/enmeshed_types.dart'; +import 'package:enmeshed_ui_kit/enmeshed_ui_kit.dart'; import 'package:flutter/material.dart'; -import '/core/constants.dart'; -import '/core/utils/extensions.dart'; +import '/core/core.dart'; import '../utils/get_tag_label.dart'; typedef AvailableTagsData = ({Map tagsMap, String currentPath}); diff --git a/apps/enmeshed/lib/account/my_data/file/widgets/file_info_container.dart b/apps/enmeshed/lib/account/my_data/file/widgets/file_info_container.dart index 5690db5d3..a31f6e148 100644 --- a/apps/enmeshed/lib/account/my_data/file/widgets/file_info_container.dart +++ b/apps/enmeshed/lib/account/my_data/file/widgets/file_info_container.dart @@ -1,8 +1,8 @@ +import 'package:enmeshed_ui_kit/enmeshed_ui_kit.dart'; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; -import '/core/constants.dart'; -import '/core/utils/extensions.dart'; +import '/core/core.dart'; class FileInfoContainer extends StatelessWidget { final String createdBy; diff --git a/apps/enmeshed/lib/account/my_data/file/widgets/file_tags_container.dart b/apps/enmeshed/lib/account/my_data/file/widgets/file_tags_container.dart index 3a0e108cf..a0f0c60c2 100644 --- a/apps/enmeshed/lib/account/my_data/file/widgets/file_tags_container.dart +++ b/apps/enmeshed/lib/account/my_data/file/widgets/file_tags_container.dart @@ -1,7 +1,7 @@ +import 'package:enmeshed_ui_kit/enmeshed_ui_kit.dart'; import 'package:flutter/material.dart'; -import '/core/constants.dart'; -import '/core/utils/extensions.dart'; +import '/core/core.dart'; class FileTagsContainer extends StatelessWidget { final VoidCallback onEditFile; diff --git a/apps/enmeshed/lib/account/my_data/file/widgets/selected_tag_section.dart b/apps/enmeshed/lib/account/my_data/file/widgets/selected_tag_section.dart index d6ddc6b35..e058849e1 100644 --- a/apps/enmeshed/lib/account/my_data/file/widgets/selected_tag_section.dart +++ b/apps/enmeshed/lib/account/my_data/file/widgets/selected_tag_section.dart @@ -1,8 +1,8 @@ import 'package:enmeshed_types/enmeshed_types.dart'; +import 'package:enmeshed_ui_kit/enmeshed_ui_kit.dart'; import 'package:flutter/material.dart'; -import '/core/constants.dart'; -import '/core/utils/extensions.dart'; +import '/core/core.dart'; import '../utils/get_tag_label.dart'; class SelectedTagSection extends StatelessWidget { From 45b5c06e462db1aacaaa8bf567da62ffb19c7894 Mon Sep 17 00:00:00 2001 From: Ali Ince Date: Mon, 27 Jan 2025 09:34:25 +0100 Subject: [PATCH 19/29] chore: update tagCollection to single level tags example --- .../assets/single_level_tags_example.json | 58 +++++++++ apps/enmeshed/assets/tag_example.json | 113 ------------------ 2 files changed, 58 insertions(+), 113 deletions(-) create mode 100644 apps/enmeshed/assets/single_level_tags_example.json delete mode 100644 apps/enmeshed/assets/tag_example.json diff --git a/apps/enmeshed/assets/single_level_tags_example.json b/apps/enmeshed/assets/single_level_tags_example.json new file mode 100644 index 000000000..87688bc60 --- /dev/null +++ b/apps/enmeshed/assets/single_level_tags_example.json @@ -0,0 +1,58 @@ +{ + "supportedLanguages": [ + "de", + "en" + ], + "tagsForAttributeValueTypes": { + "IdentityFileReference": { + "schulabschluss": { + "displayNames": { + "de": "Abschluss", + "en": "Degree" + } + }, + "abitur": { + "displayNames": { + "de": "Abitur", + "en": "High School Diploma" + } + }, + "fachhochschulreife": { + "displayNames": { + "de": "Fachhochschulreife", + "en": "University of Applied Sciences Entrance Qualification" + } + }, + "grundschule": { + "displayNames": { + "de": "Grundschule", + "en": "Primary School" + } + }, + "hauptschulabschluss": { + "displayNames": { + "de": "Hauptschulabschluss", + "en": "Secondary School Certificate" + } + }, + "mittlerer_schulabschluss": { + "displayNames": { + "de": "Mittlerer Schulabschluss", + "en": "Intermediate School Certificate" + } + }, + "praktikum": { + "displayNames": { + "de": "Praktikum", + "en": "Internship" + } + }, + "versicherungsunterlagen": { + "displayNames": { + "de": "Versicherungsunterlagen", + "en": "Insurance documents" + } + } + } + } +} \ No newline at end of file diff --git a/apps/enmeshed/assets/tag_example.json b/apps/enmeshed/assets/tag_example.json deleted file mode 100644 index 805717b1a..000000000 --- a/apps/enmeshed/assets/tag_example.json +++ /dev/null @@ -1,113 +0,0 @@ -{ - "supportedLanguages": ["de", "en"], - "tagsForAttributeValueTypes": { - "IdentityFileReference": { - "schulabschluss": { - "displayNames": { - "de": "Abschluss", - "en": "Degree" - }, - "children": { - "realschule": { - "displayNames": { - "de": "Realschule", - "en": "Secondary School" - }, - "children": { - "zeugnis": { - "displayNames": { - "de": "Zeugnis", - "en": "Diploma" - } - } - } - }, - "gymnasium": { - "displayNames": { - "de": "Gymnasium", - "en": "High School" - }, - "children": { - "zeugnis": { - "displayNames": { - "de": "Zeugnis", - "en": "Diploma" - } - }, - "abitur": { - "displayNames": { - "de": "Abitur", - "en": "A-Level Certificate" - } - } - } - } - } - }, - "versicherungsunterlagen": { - "displayNames": { - "de": "Versicherungsunterlagen", - "en": "Insurance documents" - }, - "children": { - "haftpflichtversicherung": { - "displayNames": { - "de": "Haftpflichtversicherung", - "en": "Liability Insurance" - }, - "children": { - "police": { - "displayNames": { - "de": "Versicherungspolice", - "en": "Insurance Policy" - } - } - } - }, - "krankenversicherung": { - "displayNames": { - "de": "Krankenversicherung", - "en": "Health Insurance" - }, - "children": { - "karte": { - "displayNames": { - "de": "Versicherungskarte", - "en": "Insurance Card" - } - }, - "nachweise": { - "displayNames": { - "de": "Nachweise", - "en": "Proofs" - } - } - } - } - } - } - }, - "PhoneNumber": { - "notfall": { - "displayNames": { - "de": "Notfallkontakt", - "en": "Emergency Contact" - } - } - }, - "StreetAddress": { - "lieferung": { - "displayNames": { - "de": "Lieferadresse", - "en": "Deliver Address" - } - }, - "heimat": { - "displayNames": { - "de": "Heimatadresse", - "en": "Home Address" - } - } - } - } - } \ No newline at end of file From 4c5422e14f4cc53ee7553a1516970423cb4032e5 Mon Sep 17 00:00:00 2001 From: Ali Ince Date: Mon, 27 Jan 2025 09:35:57 +0100 Subject: [PATCH 20/29] chore: update translations --- apps/enmeshed/lib/l10n/app_de.arb | 7 ++----- apps/enmeshed/lib/l10n/app_en.arb | 7 ++----- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/apps/enmeshed/lib/l10n/app_de.arb b/apps/enmeshed/lib/l10n/app_de.arb index 706caa09b..237cfbdf9 100644 --- a/apps/enmeshed/lib/l10n/app_de.arb +++ b/apps/enmeshed/lib/l10n/app_de.arb @@ -599,7 +599,7 @@ "files_noResults": "Keine Ergebnisse", "files_noResultsDescription": "Für den eingegeben Suchbegriff konnten keine Ergebnisse gefunden werden.", "files_uploadInProgress": "Die Datei wird hochgeladen.", - "files_assignTags": "Vergeben Sie Tags!", + "files_assignTagsTitle": "Vergeben Sie Tags!", "files_assignTagsDescription": "Mit Tags bringen Sie Ordnung in Ihre Dateien und Dokumente. So finden Sie jederzeit schnell wieder, was sie brauchen.", "files_assignTagsButton": "Tags vergeben", "files_uploadFile": "Datei hochladen", @@ -620,12 +620,9 @@ "files_fileType_powerPoint": "PowerPoint-Dokumente", "files_fileType_other": "Andere ...", "files_fileSize": "Größe", - "files_tag": "Tag", - "files_tags": "Tags", + "files_assignTags": "Tags vergeben", "files_editFile": "Dokument bearbeiten", "files_saving": "Dokument wird gespeichert...", - "files_selectedTags": "Ausgewählte Tags:", - "files_availableTags": "Verfügbare Tags:", "filter": "Filter", "apply_filter": "Filtern", "deviceOnboarding_title": "Gerät hinzufügen", diff --git a/apps/enmeshed/lib/l10n/app_en.arb b/apps/enmeshed/lib/l10n/app_en.arb index bdb10e5ea..d220593c5 100644 --- a/apps/enmeshed/lib/l10n/app_en.arb +++ b/apps/enmeshed/lib/l10n/app_en.arb @@ -599,7 +599,7 @@ "files_noResults": "No results", "files_noResultsDescription": "No results could be found for the search query entered.", "files_uploadInProgress": "Uploading the file.", - "files_assignTags": "Assign tags!", + "files_assignTagsTitle": "Assign tags!", "files_assignTagsDescription": "With tags, you bring order to your files and documents. So you can always find what you need quickly.", "files_assignTagsButton": "Assign tags", "files_uploadFile": "Upload File", @@ -620,12 +620,9 @@ "files_fileType_powerPoint": "PowerPoint Document", "files_fileType_other": "Other ...", "files_fileSize": "Size", - "files_tag": "Tag", - "files_tags": "Tags", + "files_assignTags": "Assign tags", "files_editFile": "Edit file", "files_saving": "File is being saved...", - "files_selectedTags": "Selected tags:", - "files_availableTags": "Available tags:", "filter": "Filter", "apply_filter": "Apply filters", "deviceOnboarding_title": "Add device", From 586898273be643ab8e3c12c69607dd4446bcd839 Mon Sep 17 00:00:00 2001 From: Ali Ince Date: Mon, 27 Jan 2025 09:36:14 +0100 Subject: [PATCH 21/29] chore: update assets path --- apps/enmeshed/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/enmeshed/pubspec.yaml b/apps/enmeshed/pubspec.yaml index 67b414a50..9695a506a 100644 --- a/apps/enmeshed/pubspec.yaml +++ b/apps/enmeshed/pubspec.yaml @@ -68,7 +68,7 @@ flutter: generate: true uses-material-design: true assets: - - path: assets/tag_example.json + - path: assets/single_level_tags_example.json - path: assets/i18n/ - path: assets/texts/ - path: assets/pictures/ From 3a94ea978413f844b14cc40ee56c1973c8168a45 Mon Sep 17 00:00:00 2001 From: Ali Ince Date: Mon, 27 Jan 2025 09:38:16 +0100 Subject: [PATCH 22/29] chore: update ui and logic for dispaying and editing tags --- .../my_data/file/file_detail_screen.dart | 20 ++-- .../my_data/file/modals/edit_file.dart | 73 ++++---------- .../file/widgets/available_tags_section.dart | 66 +++---------- .../file/widgets/file_tags_container.dart | 2 +- .../file/widgets/selected_tag_section.dart | 94 ------------------- .../file/widgets/selected_tags_section.dart | 35 +++++++ 6 files changed, 82 insertions(+), 208 deletions(-) delete mode 100644 apps/enmeshed/lib/account/my_data/file/widgets/selected_tag_section.dart create mode 100644 apps/enmeshed/lib/account/my_data/file/widgets/selected_tags_section.dart diff --git a/apps/enmeshed/lib/account/my_data/file/file_detail_screen.dart b/apps/enmeshed/lib/account/my_data/file/file_detail_screen.dart index 82b9c6b7f..bcf10b40c 100644 --- a/apps/enmeshed/lib/account/my_data/file/file_detail_screen.dart +++ b/apps/enmeshed/lib/account/my_data/file/file_detail_screen.dart @@ -1,6 +1,6 @@ import 'dart:convert'; -import 'package:enmeshed/account/my_data/file/widgets/selected_tag_section.dart'; +import 'package:enmeshed/account/my_data/file/widgets/selected_tags_section.dart'; import 'package:enmeshed_runtime_bridge/enmeshed_runtime_bridge.dart'; import 'package:enmeshed_types/enmeshed_types.dart'; import 'package:enmeshed_ui_kit/enmeshed_ui_kit.dart'; @@ -77,19 +77,21 @@ class _FileDetailScreenState extends State { ), ), Gaps.h48, - if (_fileReferenceAttribute != null) ...[ - if (_tags == null) + if (_isEditable) ...[ + if (_tags == null || _tags!.isEmpty) FileTagsContainer(onEditFile: _onEditFilePressed) else - SelectedTagSection(tagCollection: _tagCollection, selectedTagsList: _tags!.first.split('+%+')), + SelectedTagsSection(tagCollection: _tagCollection!, selectedTagsList: _tags!), Gaps.h16, ], FileInfoContainer(createdBy: _fileDVO!.createdBy.name, createdAt: _fileDVO!.createdAt), Gaps.h32, Row( children: [ - if (_fileReferenceAttribute != null) IconButton(onPressed: _onEditFilePressed, icon: const Icon(Icons.edit_outlined, size: 24)), - Gaps.w8, + if (_isEditable) ...[ + IconButton(onPressed: _onEditFilePressed, icon: const Icon(Icons.edit_outlined, size: 24)), + Gaps.w8, + ], IconButton( onPressed: _isLoadingFile || DateTime.parse(_fileDVO!.expiresAt).isBefore(DateTime.now()) ? null : _downloadAndSaveFile, icon: _isLoadingFile @@ -112,6 +114,8 @@ class _FileDetailScreenState extends State { ); } + bool get _isEditable => _fileReferenceAttribute != null && _tagCollection != null; + Future _load() async { await _loadFile(); await _loadTagCollection(); @@ -127,7 +131,7 @@ class _FileDetailScreenState extends State { Future _loadTagCollection() async { // TODO(aince42): this is a temporary solution to load the tag collection - final jsonString = await rootBundle.loadString('assets/tag_example.json'); + final jsonString = await rootBundle.loadString('assets/single_level_tags_example.json'); final jsonData = json.decode(jsonString) as Map; final tagCollection = AttributeTagCollectionDTO.fromJson(jsonData); // final tagCollection = await _session.consumptionServices.attributes.getAttributeTagCollection(); @@ -185,7 +189,7 @@ class _FileDetailScreenState extends State { accountId: widget.accountId, fileTitle: _fileDVO!.title, fileReferenceAttribute: _fileReferenceAttribute!, - tagCollection: _tagCollection, + tagCollection: _tagCollection!, onSave: _loadTags, ), ); diff --git a/apps/enmeshed/lib/account/my_data/file/modals/edit_file.dart b/apps/enmeshed/lib/account/my_data/file/modals/edit_file.dart index 38fdcba60..195b244ce 100644 --- a/apps/enmeshed/lib/account/my_data/file/modals/edit_file.dart +++ b/apps/enmeshed/lib/account/my_data/file/modals/edit_file.dart @@ -7,21 +7,20 @@ import 'package:go_router/go_router.dart'; import '/core/core.dart'; import '../widgets/available_tags_section.dart'; -import '../widgets/selected_tag_section.dart'; class EditFile extends StatefulWidget { final String accountId; final String fileTitle; final LocalAttributeDVO fileReferenceAttribute; final void Function({String? attributeId}) onSave; - final AttributeTagCollectionDTO? tagCollection; + final AttributeTagCollectionDTO tagCollection; const EditFile({ required this.accountId, required this.fileTitle, required this.fileReferenceAttribute, required this.onSave, - this.tagCollection, + required this.tagCollection, super.key, }); @@ -33,9 +32,7 @@ class _EditFileState extends State { late final TextEditingController _titleController; bool _loading = false; - String _selectedTags = ''; - - List get _selectedTagsList => _selectedTags.isEmpty ? [] : _selectedTags.split('+%+'); + List _selectedTags = []; @override void initState() { @@ -43,13 +40,14 @@ class _EditFileState extends State { _titleController = TextEditingController(text: widget.fileTitle)..addListener(() => setState(() {})); if (widget.fileReferenceAttribute.tags != null && widget.fileReferenceAttribute.tags!.isNotEmpty) { - _selectedTags = widget.fileReferenceAttribute.tags!.first; + _selectedTags = widget.fileReferenceAttribute.tags!; } } @override void dispose() { super.dispose(); + _titleController.dispose(); } @@ -83,38 +81,19 @@ class _EditFileState extends State { ), ), ), - Gaps.h40, - Text(context.l10n.files_tags, style: Theme.of(context).textTheme.titleMedium), Gaps.h24, - Text(context.l10n.files_assignTagsDescription, style: Theme.of(context).textTheme.bodySmall?.copyWith(letterSpacing: 0.4)), - Gaps.h24, - if (_selectedTags.isNotEmpty) ...[ - SelectedTagSection( - tagCollection: widget.tagCollection, - selectedTagsList: _selectedTagsList, - onTagDeleted: (tagPath) { - setState(() { - final tagIndex = _selectedTagsList.indexOf(tagPath); - if (tagIndex != -1) { - _selectedTags = tagIndex == 0 ? '' : _selectedTagsList.take(tagIndex).join('+%+'); - } - }); - }, - ), - ], - if (widget.tagCollection != null) ...[ - Gaps.h24, - AvailableTagsSection( - tagCollection: widget.tagCollection, - selectedTags: _selectedTagsList, - onTagSelected: _handleTagSelected, - ), - ], + Text(context.l10n.files_assignTags, style: Theme.of(context).textTheme.titleMedium), Gaps.h24, + AvailableTagsSection( + tagCollection: widget.tagCollection, + selectedTags: _selectedTags, + onTagSelected: _handleTagSelected, + ), + Gaps.h40, Row( mainAxisAlignment: MainAxisAlignment.end, children: [ - TextButton(onPressed: () => Navigator.of(context).pop(), child: Text(context.l10n.cancel)), + OutlinedButton(onPressed: () => Navigator.of(context).pop(), child: Text(context.l10n.cancel)), Gaps.w8, FilledButton(onPressed: _confirmEnabled ? _confirm : null, child: Text(context.l10n.save)), ], @@ -137,7 +116,7 @@ class _EditFileState extends State { final succeedAttributeResult = await session.consumptionServices.attributes.succeedRepositoryAttribute( predecessorId: widget.fileReferenceAttribute.id, value: (widget.fileReferenceAttribute as RepositoryAttributeDVO).value as IdentityFileReferenceAttributeValue, - tags: [_selectedTags], + tags: _selectedTags, ); if (succeedAttributeResult.isError) { @@ -163,26 +142,14 @@ class _EditFileState extends State { void _handleTagSelected({ required String tagPath, - required AttributeTagDTO tagData, required bool selected, }) { - if (selected) { - final pathParts = tagPath.split('.'); - final lastPart = pathParts.last; - - if (_selectedTagsList.isEmpty) { - setState(() => _selectedTags = pathParts.first); - - return; + setState(() { + if (selected) { + _selectedTags = [..._selectedTags, tagPath]; + } else { + _selectedTags = _selectedTags.where((tag) => tag != tagPath).toList(); } - - setState(() => _selectedTags = [..._selectedTagsList, lastPart].join('+%+')); - } else { - final pathParts = tagPath.split('.'); - final lastPart = pathParts.last; - - final tagIndex = _selectedTagsList.indexOf(lastPart); - if (tagIndex != -1) setState(() => _selectedTags = tagIndex == 0 ? '' : _selectedTagsList.take(tagIndex).join('+%+')); - } + }); } } diff --git a/apps/enmeshed/lib/account/my_data/file/widgets/available_tags_section.dart b/apps/enmeshed/lib/account/my_data/file/widgets/available_tags_section.dart index ea5328daf..16fa7cf90 100644 --- a/apps/enmeshed/lib/account/my_data/file/widgets/available_tags_section.dart +++ b/apps/enmeshed/lib/account/my_data/file/widgets/available_tags_section.dart @@ -1,18 +1,13 @@ import 'package:enmeshed_types/enmeshed_types.dart'; -import 'package:enmeshed_ui_kit/enmeshed_ui_kit.dart'; import 'package:flutter/material.dart'; -import '/core/core.dart'; import '../utils/get_tag_label.dart'; -typedef AvailableTagsData = ({Map tagsMap, String currentPath}); - class AvailableTagsSection extends StatelessWidget { - final AttributeTagCollectionDTO? tagCollection; + final AttributeTagCollectionDTO tagCollection; final List selectedTags; final void Function({ required String tagPath, - required AttributeTagDTO tagData, required bool selected, }) onTagSelected; @@ -20,52 +15,19 @@ class AvailableTagsSection extends StatelessWidget { @override Widget build(BuildContext context) { - if (tagCollection == null) return const SizedBox.shrink(); - - final availableTagsData = _getAvailableTagsData(); - if (availableTagsData == null) return const SizedBox.shrink(); - - final currentPath = availableTagsData.currentPath; - - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text(context.l10n.files_availableTags, style: Theme.of(context).textTheme.titleMedium), - Gaps.h8, - Wrap( - spacing: 10, - children: availableTagsData.tagsMap.entries.map((entry) { - return FilterChip( - label: Text(getTagLabel(context, tagCollection, entry.value)), - selected: selectedTags.contains(entry.key.split('.').last), - onSelected: (selected) => onTagSelected( - tagPath: currentPath.isEmpty ? entry.key : '$currentPath.${entry.key}', - tagData: entry.value, - selected: selected, - ), - ); - }).toList(), - ), - ], + final availableTags = tagCollection.tagsForAttributeValueTypes['IdentityFileReference'] ?? {}; + if (availableTags.isEmpty) return const SizedBox.shrink(); + + return Wrap( + spacing: 10, + children: availableTags.entries.map((entry) { + return ChoiceChip( + label: Text(getTagLabel(context, tagCollection, entry.value)), + selected: selectedTags.contains(entry.key), + showCheckmark: false, + onSelected: (selected) => onTagSelected(tagPath: entry.key, selected: selected), + ); + }).toList(), ); } - - AvailableTagsData? _getAvailableTagsData() { - var currentLevel = tagCollection!.tagsForAttributeValueTypes['IdentityFileReference'] ?? {}; - if (selectedTags.isEmpty) return (tagsMap: currentLevel, currentPath: ''); - - var currentPath = ''; - for (final tag in selectedTags) { - if (!currentLevel.containsKey(tag)) { - return (tagsMap: currentLevel, currentPath: currentPath); - } - - currentPath = currentPath.isEmpty ? tag : '$currentPath.$tag'; - currentLevel = currentLevel[tag]!.children ?? {}; - - if (currentLevel.isEmpty) return null; - } - - return (tagsMap: currentLevel, currentPath: currentPath); - } } diff --git a/apps/enmeshed/lib/account/my_data/file/widgets/file_tags_container.dart b/apps/enmeshed/lib/account/my_data/file/widgets/file_tags_container.dart index a0f0c60c2..9d20de43f 100644 --- a/apps/enmeshed/lib/account/my_data/file/widgets/file_tags_container.dart +++ b/apps/enmeshed/lib/account/my_data/file/widgets/file_tags_container.dart @@ -19,7 +19,7 @@ class FileTagsContainer extends StatelessWidget { children: [ Icon(Icons.warning_rounded, color: context.customColors.warning), Gaps.w8, - Text(context.l10n.files_assignTags), + Text(context.l10n.files_assignTagsTitle), ], ), Gaps.h16, diff --git a/apps/enmeshed/lib/account/my_data/file/widgets/selected_tag_section.dart b/apps/enmeshed/lib/account/my_data/file/widgets/selected_tag_section.dart deleted file mode 100644 index e058849e1..000000000 --- a/apps/enmeshed/lib/account/my_data/file/widgets/selected_tag_section.dart +++ /dev/null @@ -1,94 +0,0 @@ -import 'package:enmeshed_types/enmeshed_types.dart'; -import 'package:enmeshed_ui_kit/enmeshed_ui_kit.dart'; -import 'package:flutter/material.dart'; - -import '/core/core.dart'; -import '../utils/get_tag_label.dart'; - -class SelectedTagSection extends StatelessWidget { - final AttributeTagCollectionDTO? tagCollection; - final List selectedTagsList; - final void Function(String)? onTagDeleted; - - const SelectedTagSection({required this.tagCollection, required this.selectedTagsList, this.onTagDeleted, super.key}); - - @override - Widget build(BuildContext context) { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - if (onTagDeleted != null) ...[ - Text(context.l10n.files_selectedTags, style: Theme.of(context).textTheme.titleMedium), - Gaps.h8, - ], - Wrap( - spacing: onTagDeleted == null ? 4 : 10, - crossAxisAlignment: WrapCrossAlignment.center, - children: selectedTagsList.asMap().entries.expand((entry) { - final index = entry.key; - final tagPath = entry.value; - final tag = _getTagByPath(tagPath); - if (tag == null) return const []; - - return [ - Chip( - label: Text( - getTagLabel(context, tagCollection, tag), - style: Theme.of(context).textTheme.labelLarge?.copyWith(color: Theme.of(context).colorScheme.onSecondaryContainer), - ), - deleteIcon: const Icon(Icons.close), - backgroundColor: Theme.of(context).colorScheme.secondaryContainer, - side: BorderSide.none, - onDeleted: onTagDeleted != null ? () => onTagDeleted!(tagPath) : null, - padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 4), - ), - if (onTagDeleted == null && index < selectedTagsList.length - 1) - Icon( - Icons.arrow_forward_ios, - size: 12, - color: Theme.of(context).colorScheme.secondaryContainer, - ), - ]; - }).toList(), - ), - ], - ); - } - - AttributeTagDTO? _getTagByPath(String simplifiedTag) { - if (tagCollection == null) return null; - - var currentLevel = tagCollection!.tagsForAttributeValueTypes['IdentityFileReference'] ?? {}; - - for (var i = 0; i < selectedTagsList.length; i++) { - final tag = selectedTagsList[i]; - if (tag == simplifiedTag) { - if (i == 0) return currentLevel[tag]; - - for (var j = 0; j < i; j++) { - final previousTag = selectedTagsList[j]; - if (j == 0) { - currentLevel = currentLevel[previousTag]!.children ?? {}; - } else { - var found = false; - currentLevel.forEach((key, value) { - if (key.split('.').last == previousTag && !found) { - currentLevel = value.children ?? {}; - found = true; - } - }); - } - } - - AttributeTagDTO? foundTag; - currentLevel.forEach((key, value) { - if (key.split('.').last == tag) foundTag = value; - }); - - return foundTag; - } - } - - return null; - } -} diff --git a/apps/enmeshed/lib/account/my_data/file/widgets/selected_tags_section.dart b/apps/enmeshed/lib/account/my_data/file/widgets/selected_tags_section.dart new file mode 100644 index 000000000..4ca5b9f58 --- /dev/null +++ b/apps/enmeshed/lib/account/my_data/file/widgets/selected_tags_section.dart @@ -0,0 +1,35 @@ +import 'package:enmeshed_types/enmeshed_types.dart'; +import 'package:flutter/material.dart'; + +import '../utils/get_tag_label.dart'; + +class SelectedTagsSection extends StatelessWidget { + final AttributeTagCollectionDTO tagCollection; + final List selectedTagsList; + + const SelectedTagsSection({required this.tagCollection, required this.selectedTagsList, super.key}); + + @override + Widget build(BuildContext context) { + final availableTags = tagCollection.tagsForAttributeValueTypes['IdentityFileReference'] ?? {}; + if (availableTags.isEmpty) return const SizedBox.shrink(); + + return Wrap( + spacing: 10, + children: selectedTagsList.map((tagPath) { + final tag = availableTags[tagPath]; + if (tag == null) return const SizedBox.shrink(); + + return Chip( + label: Text( + getTagLabel(context, tagCollection, tag), + style: Theme.of(context).textTheme.labelSmall?.copyWith(color: Theme.of(context).colorScheme.onSecondaryContainer), + ), + side: BorderSide.none, + backgroundColor: Theme.of(context).colorScheme.secondaryContainer, + padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 4), + ); + }).toList(), + ); + } +} From a66bb9a16e01664b2fbe43bb67a9457b81cfcae0 Mon Sep 17 00:00:00 2001 From: Ali Ince Date: Tue, 28 Jan 2025 09:39:35 +0100 Subject: [PATCH 23/29] chore: use real tag collection data --- .../assets/single_level_tags_example.json | 58 ------------------- .../my_data/file/file_detail_screen.dart | 13 ++--- apps/enmeshed/pubspec.yaml | 1 - 3 files changed, 4 insertions(+), 68 deletions(-) delete mode 100644 apps/enmeshed/assets/single_level_tags_example.json diff --git a/apps/enmeshed/assets/single_level_tags_example.json b/apps/enmeshed/assets/single_level_tags_example.json deleted file mode 100644 index 87688bc60..000000000 --- a/apps/enmeshed/assets/single_level_tags_example.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "supportedLanguages": [ - "de", - "en" - ], - "tagsForAttributeValueTypes": { - "IdentityFileReference": { - "schulabschluss": { - "displayNames": { - "de": "Abschluss", - "en": "Degree" - } - }, - "abitur": { - "displayNames": { - "de": "Abitur", - "en": "High School Diploma" - } - }, - "fachhochschulreife": { - "displayNames": { - "de": "Fachhochschulreife", - "en": "University of Applied Sciences Entrance Qualification" - } - }, - "grundschule": { - "displayNames": { - "de": "Grundschule", - "en": "Primary School" - } - }, - "hauptschulabschluss": { - "displayNames": { - "de": "Hauptschulabschluss", - "en": "Secondary School Certificate" - } - }, - "mittlerer_schulabschluss": { - "displayNames": { - "de": "Mittlerer Schulabschluss", - "en": "Intermediate School Certificate" - } - }, - "praktikum": { - "displayNames": { - "de": "Praktikum", - "en": "Internship" - } - }, - "versicherungsunterlagen": { - "displayNames": { - "de": "Versicherungsunterlagen", - "en": "Insurance documents" - } - } - } - } -} \ No newline at end of file diff --git a/apps/enmeshed/lib/account/my_data/file/file_detail_screen.dart b/apps/enmeshed/lib/account/my_data/file/file_detail_screen.dart index bcf10b40c..417cf4eb8 100644 --- a/apps/enmeshed/lib/account/my_data/file/file_detail_screen.dart +++ b/apps/enmeshed/lib/account/my_data/file/file_detail_screen.dart @@ -1,11 +1,8 @@ -import 'dart:convert'; - import 'package:enmeshed/account/my_data/file/widgets/selected_tags_section.dart'; import 'package:enmeshed_runtime_bridge/enmeshed_runtime_bridge.dart'; import 'package:enmeshed_types/enmeshed_types.dart'; import 'package:enmeshed_ui_kit/enmeshed_ui_kit.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; import 'package:get_it/get_it.dart'; import '/core/core.dart'; @@ -130,13 +127,11 @@ class _FileDetailScreenState extends State { } Future _loadTagCollection() async { - // TODO(aince42): this is a temporary solution to load the tag collection - final jsonString = await rootBundle.loadString('assets/single_level_tags_example.json'); - final jsonData = json.decode(jsonString) as Map; - final tagCollection = AttributeTagCollectionDTO.fromJson(jsonData); - // final tagCollection = await _session.consumptionServices.attributes.getAttributeTagCollection(); + final tagCollectionResult = await _session.consumptionServices.attributes.getAttributeTagCollection(); + + if (tagCollectionResult.isError) return; - setState(() => _tagCollection = tagCollection); + setState(() => _tagCollection = tagCollectionResult.value); } Future _loadTags({String? attributeId}) async { diff --git a/apps/enmeshed/pubspec.yaml b/apps/enmeshed/pubspec.yaml index 9695a506a..65082f15c 100644 --- a/apps/enmeshed/pubspec.yaml +++ b/apps/enmeshed/pubspec.yaml @@ -68,7 +68,6 @@ flutter: generate: true uses-material-design: true assets: - - path: assets/single_level_tags_example.json - path: assets/i18n/ - path: assets/texts/ - path: assets/pictures/ From 2ebbb8d7c75430a09c7d82b8da75d2fd3fb3947d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20K=C3=B6nig?= Date: Mon, 3 Feb 2025 16:08:59 +0100 Subject: [PATCH 24/29] chore: unfo lockfile changes --- apps/enmeshed/ios/Podfile.lock | 40 ++++++------- apps/enmeshed/pubspec.lock | 103 +++++++++++++++++++++++---------- pubspec.lock | 76 ++++++++++++------------ 3 files changed, 127 insertions(+), 92 deletions(-) diff --git a/apps/enmeshed/ios/Podfile.lock b/apps/enmeshed/ios/Podfile.lock index daa4dfce8..776e09982 100644 --- a/apps/enmeshed/ios/Podfile.lock +++ b/apps/enmeshed/ios/Podfile.lock @@ -3,8 +3,6 @@ PODS: - Flutter - croppy (0.0.1): - Flutter - - device_info_plus (0.0.1): - - Flutter - DKImagePickerController/Core (4.3.9): - DKImagePickerController/ImageDataManager - DKImagePickerController/Resource @@ -131,7 +129,6 @@ PODS: DEPENDENCIES: - app_links (from `.symlinks/plugins/app_links/ios`) - croppy (from `.symlinks/plugins/croppy/ios`) - - device_info_plus (from `.symlinks/plugins/device_info_plus/ios`) - file_picker (from `.symlinks/plugins/file_picker/ios`) - Flutter (from `Flutter`) - flutter_inappwebview_ios (from `.symlinks/plugins/flutter_inappwebview_ios/ios`) @@ -173,8 +170,6 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/app_links/ios" croppy: :path: ".symlinks/plugins/croppy/ios" - device_info_plus: - :path: ".symlinks/plugins/device_info_plus/ios" file_picker: :path: ".symlinks/plugins/file_picker/ios" Flutter: @@ -209,41 +204,40 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/url_launcher_ios/ios" SPEC CHECKSUMS: - app_links: e7a6750a915a9e161c58d91bc610e8cd1d4d0ad0 - croppy: b6199bc8d56bd2e03cc11609d1c47ad9875c1321 - device_info_plus: bf2e3232933866d73fe290f2942f2156cdd10342 + app_links: 3da4c36b46cac3bf24eb897f1a6ce80bda109874 + croppy: 979e8ddc254f4642bffe7d52dc7193354b27ba30 DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60 - file_picker: 09aa5ec1ab24135ccd7a1621c46c84134bfd6655 + file_picker: 9b3292d7c8bc68c8a7bf8eb78f730e49c8efc517 Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 - flutter_inappwebview_ios: 6f63631e2c62a7c350263b13fa5427aedefe81d4 - flutter_keyboard_visibility: 0339d06371254c3eb25eeb90ba8d17dca8f9c069 - flutter_local_notifications: df98d66e515e1ca797af436137b4459b160ad8c9 - flutter_native_splash: f71420956eb811e6d310720fee915f1d42852e7a + flutter_inappwebview_ios: b89ba3482b96fb25e00c967aae065701b66e9b99 + flutter_keyboard_visibility: 4625131e43015dbbe759d9b20daaf77e0e3f6619 + flutter_local_notifications: 395056b3175ba4f08480a7c5de30cd36d69827e4 + flutter_native_splash: 6cad9122ea0fad137d23137dd14b937f3e90b145 GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7 GoogleMLKit: eff9e23ec1d90ea4157a1ee2e32a4f610c5b3318 GoogleToolboxForMac: d1a2cbf009c453f4d6ded37c105e2f67a32206d8 GoogleUtilities: 26a3abef001b6533cf678d3eb38fd3f614b7872d GTMSessionFetcher: 5aea5ba6bd522a239e236100971f10cb71b96ab6 - image_picker_ios: c560581cceedb403a6ff17f2f816d7fea1421fc1 + image_picker_ios: 7fe1ff8e34c1790d6fff70a32484959f563a928a MLImage: 0ad1c5f50edd027672d8b26b0fee78a8b4a0fc56 MLKitBarcodeScanning: 0a3064da0a7f49ac24ceb3cb46a5bc67496facd2 MLKitCommon: 07c2c33ae5640e5380beaaa6e4b9c249a205542d MLKitVision: 45e79d68845a2de77e2dd4d7f07947f0ed157b0e - mobile_scanner: fd0054c52ede661e80bf5a4dea477a2467356bee + mobile_scanner: af8f71879eaba2bbcb4d86c6a462c3c0e7f23036 nanopb: fad817b59e0457d11a5dfbde799381cd727c1275 - open_file_ios: 461db5853723763573e140de3193656f91990d9e + open_file_ios: 5ff7526df64e4394b4fe207636b67a95e83078bb OrderedSet: e539b66b644ff081c73a262d24ad552a69be3a94 - package_info_plus: c0502532a26c7662a62a356cebe2692ec5fe4ec4 - path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46 - permission_handler_apple: 9878588469a2b0d0fc1e048d9f43605f92e6cec2 - printing: 233e1b73bd1f4a05615548e9b5a324c98588640b + package_info_plus: af8e2ca6888548050f16fa2f1938db7b5a5df499 + path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564 + permission_handler_apple: 4ed2196e43d0651e8ff7ca3483a069d469701f2d + printing: 54ff03f28fe9ba3aa93358afb80a8595a071dd07 PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 - push_ios: 2bd1b4d3f782209da1f571db1250af236957e807 + push_ios: d8edf21b48ecb1ee9e384dd0cd9c1b049fd1ca11 SDWebImage: dfe95b2466a9823cf9f0c6d01217c06550d7b29a - shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78 + shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7 SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4 - url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe + url_launcher_ios: 694010445543906933d732453a59da0a173ae33d PODFILE CHECKSUM: 4355a5654b74c37e4f7c691bc7791921e63d7f9d diff --git a/apps/enmeshed/pubspec.lock b/apps/enmeshed/pubspec.lock index a0ff9e570..0c48f4400 100644 --- a/apps/enmeshed/pubspec.lock +++ b/apps/enmeshed/pubspec.lock @@ -137,14 +137,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.19.0" + console: + dependency: transitive + description: + name: console + sha256: e04e7824384c5b39389acdd6dc7d33f3efe6b232f6f16d7626f194f6a01ad69a + url: "https://pub.dev" + source: hosted + version: "4.1.0" croppy: dependency: "direct main" description: name: croppy - sha256: bf99b00023df0d7d047e04d27d496d87cbefd968f578d0bd30f342ff75570a12 + sha256: "14bb40fd6c1771b093a907ddbf24df9aa49a4e6e379dd630602eb446e30ec629" url: "https://pub.dev" source: hosted - version: "1.3.3" + version: "1.3.1" cross_file: dependency: transitive description: @@ -181,26 +189,10 @@ packages: dependency: transitive description: name: dbus - sha256: "79e0c23480ff85dc68de79e2cd6334add97e48f7f4865d17686dd6ea81a47e8c" - url: "https://pub.dev" - source: hosted - version: "0.7.11" - device_info_plus: - dependency: transitive - description: - name: device_info_plus - sha256: b37d37c2f912ad4e8ec694187de87d05de2a3cb82b465ff1f65f65a2d05de544 - url: "https://pub.dev" - source: hosted - version: "11.2.1" - device_info_plus_platform_interface: - dependency: transitive - description: - name: device_info_plus_platform_interface - sha256: "0b04e02b30791224b31969eb1b50d723498f402971bff3630bca2ba839bd1ed2" + sha256: "365c771ac3b0e58845f39ec6deebc76e3276aa9922b0cc60840712094d9047ac" url: "https://pub.dev" source: hosted - version: "7.0.2" + version: "0.7.10" enmeshed_runtime_bridge: dependency: "direct main" description: @@ -440,10 +432,10 @@ packages: dependency: "direct dev" description: name: flutter_launcher_icons - sha256: bfa04787c85d80ecb3f8777bde5fc10c3de809240c48fa061a2c2bf15ea5211c + sha256: "31cd0885738e87c72d6f055564d37fabcdacee743b396b78c7636c169cac64f5" url: "https://pub.dev" source: hosted - version: "0.14.3" + version: "0.14.2" flutter_local_notifications: dependency: transitive description: @@ -543,10 +535,10 @@ packages: dependency: "direct main" description: name: go_router - sha256: "7c2d40b59890a929824f30d442e810116caf5088482629c894b9e4478c67472d" + sha256: "9b736a9fa879d8ad6df7932cbdcc58237c173ab004ef90d8377923d7ad731eaa" url: "https://pub.dev" source: hosted - version: "14.6.3" + version: "14.7.2" gtk: dependency: transitive description: @@ -774,10 +766,19 @@ packages: dependency: "direct main" description: name: mobile_scanner - sha256: "57d6269d10912d5d583606b46d963d7c5d0299d2c37add8b7192dd769d40a319" + sha256: "728828a798d1a2ee506beb652ca23d974c542c96ed03dcbd5eaf97bef96cdaad" url: "https://pub.dev" source: hosted - version: "6.0.3" + version: "6.0.2" + msix: + dependency: "direct dev" + description: + path: "." + ref: "Fix-Flutter-3.27" + resolved-ref: "955467338b11ddcd789a37d268e9cfd884a94b17" + url: "https://github.com/h4h13/msix.git" + source: git + version: "3.16.8" open_file: dependency: "direct main" description: @@ -842,14 +843,22 @@ packages: url: "https://pub.dev" source: hosted version: "0.0.3" + package_config: + dependency: transitive + description: + name: package_config + sha256: "92d4488434b520a62570293fbd33bb556c7d49230791c1b4bbd973baf6d2dc67" + url: "https://pub.dev" + source: hosted + version: "2.1.1" package_info_plus: dependency: "direct main" description: name: package_info_plus - sha256: "739e0a5c3c4055152520fa321d0645ee98e932718b4c8efeeb51451968fe0790" + sha256: "70c421fe9d9cc1a9a7f3b05ae56befd469fe4f8daa3b484823141a55442d858d" url: "https://pub.dev" source: hosted - version: "8.1.3" + version: "8.1.2" package_info_plus_platform_interface: dependency: transitive description: @@ -1018,6 +1027,14 @@ packages: url: "https://pub.dev" source: hosted version: "5.13.4" + pub_semver: + dependency: transitive + description: + name: pub_semver + sha256: "7b3cfbf654f3edd0c6298ecd5be782ce997ddf0e00531b9464b55245185bbbbd" + url: "https://pub.dev" + source: hosted + version: "2.1.5" push: dependency: "direct main" description: @@ -1101,10 +1118,10 @@ packages: dependency: transitive description: name: shared_preferences_android - sha256: "138b7bbbc7f59c56236e426c37afb8f78cbc57b094ac64c440e0bb90e380a4f5" + sha256: bf808be89fe9dc467475e982c1db6c2faf3d2acf54d526cd5ec37d86c99dbd84 url: "https://pub.dev" source: hosted - version: "2.4.2" + version: "2.4.1" shared_preferences_foundation: dependency: transitive description: @@ -1190,6 +1207,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.0" + styled_text: + dependency: transitive + description: + name: styled_text + sha256: fd624172cf629751b4f171dd0ecf9acf02a06df3f8a81bb56c0caa4f1df706c3 + url: "https://pub.dev" + source: hosted + version: "8.1.0" term_glyph: dependency: transitive description: @@ -1390,13 +1415,21 @@ packages: source: hosted version: "5.10.0" win32_registry: - dependency: transitive + dependency: "direct main" description: name: win32_registry sha256: "21ec76dfc731550fd3e2ce7a33a9ea90b828fdf19a5c3bcf556fa992cfa99852" url: "https://pub.dev" source: hosted version: "1.1.5" + windows_notification: + dependency: transitive + description: + name: windows_notification + sha256: be3e650874615f315402c9b9f3656e29af156709c4b5cc272cb4ca0ab7ba94a8 + url: "https://pub.dev" + source: hosted + version: "1.3.0" wolt_modal_sheet: dependency: "direct main" description: @@ -1429,6 +1462,14 @@ packages: url: "https://pub.dev" source: hosted version: "6.2.6" + xmlstream: + dependency: transitive + description: + name: xmlstream + sha256: cfc14e3f256997897df9481ae630d94c2d85ada5187ebeb868bb1aabc2c977b4 + url: "https://pub.dev" + source: hosted + version: "1.1.1" yaml: dependency: transitive description: diff --git a/pubspec.lock b/pubspec.lock index e983a25ec..6add655e8 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -21,18 +21,18 @@ packages: dependency: transitive description: name: async - sha256: d2872f9c19731c2e5f10444b14686eb7cc85c76274bd6c16e1816bff9a3bab63 + sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" url: "https://pub.dev" source: hosted - version: "2.12.0" + version: "2.11.0" charcode: dependency: transitive description: name: charcode - sha256: fb0f1107cac15a5ea6ef0a6ef71a807b9e4267c713bb93e00e92d737cc8dbd8a + sha256: fb98c0f6d12c920a02ee2d998da788bca066ca5f148492b7085ee23372b12306 url: "https://pub.dev" source: hosted - version: "1.4.0" + version: "1.3.1" checked_yaml: dependency: transitive description: @@ -61,18 +61,18 @@ packages: dependency: transitive description: name: clock - sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b + sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf url: "https://pub.dev" source: hosted - version: "1.1.2" + version: "1.1.1" collection: dependency: transitive description: name: collection - sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" + sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf url: "https://pub.dev" source: hosted - version: "1.19.1" + version: "1.19.0" conventional_commit: dependency: transitive description: @@ -85,10 +85,10 @@ packages: dependency: transitive description: name: file - sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 + sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" url: "https://pub.dev" source: hosted - version: "7.0.1" + version: "7.0.0" flutter_lints: dependency: "direct dev" description: @@ -125,10 +125,10 @@ packages: dependency: transitive description: name: http_parser - sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571" + sha256: "76d306a1c3afb33fe82e2bbacad62a61f409b5634c915fceb0d799de1a913360" url: "https://pub.dev" source: hosted - version: "4.1.2" + version: "4.1.1" intl: dependency: transitive description: @@ -141,10 +141,10 @@ packages: dependency: transitive description: name: io - sha256: dfd5a80599cf0165756e3181807ed3e77daf6dd4137caaad72d0b7931597650b + sha256: "2ec25704aba361659e10e3e5f5d672068d332fc8ac516421d483a11e5cbd061e" url: "https://pub.dev" source: hosted - version: "1.0.5" + version: "1.0.4" json_annotation: dependency: transitive description: @@ -157,10 +157,10 @@ packages: dependency: transitive description: name: lints - sha256: c35bb79562d980e9a453fc715854e1ed39e24e7d0297a880ef54e17f9874a9d7 + sha256: "3315600f3fb3b135be672bf4a178c55f274bebe368325ae18462c89ac1e3b413" url: "https://pub.dev" source: hosted - version: "5.1.1" + version: "5.0.0" melos: dependency: "direct dev" description: @@ -173,10 +173,10 @@ packages: dependency: transitive description: name: meta - sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c + sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 url: "https://pub.dev" source: hosted - version: "1.16.0" + version: "1.15.0" mustache_template: dependency: transitive description: @@ -189,18 +189,18 @@ packages: dependency: transitive description: name: path - sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.9.0" platform: dependency: transitive description: name: platform - sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984" + sha256: "9b71283fc13df574056616011fb138fd3b793ea47cc509c189a6c3fa5f8a1a65" url: "https://pub.dev" source: hosted - version: "3.1.6" + version: "3.1.5" pool: dependency: transitive description: @@ -213,10 +213,10 @@ packages: dependency: transitive description: name: process - sha256: "107d8be718f120bbba9dcd1e95e3bd325b1b4a4f07db64154635ba03f2567a0d" + sha256: "21e54fd2faf1b5bdd5102afd25012184a6793927648ea81eea80552ac9405b32" url: "https://pub.dev" source: hosted - version: "5.0.3" + version: "5.0.2" prompts: dependency: transitive description: @@ -229,10 +229,10 @@ packages: dependency: transitive description: name: pub_semver - sha256: "7b3cfbf654f3edd0c6298ecd5be782ce997ddf0e00531b9464b55245185bbbbd" + sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c" url: "https://pub.dev" source: hosted - version: "2.1.5" + version: "2.1.4" pub_updater: dependency: transitive description: @@ -253,34 +253,34 @@ packages: dependency: transitive description: name: source_span - sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c" + sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" url: "https://pub.dev" source: hosted - version: "1.10.1" + version: "1.10.0" stack_trace: dependency: transitive description: name: stack_trace - sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" + sha256: "9f47fd3630d76be3ab26f0ee06d213679aa425996925ff3feffdec504931c377" url: "https://pub.dev" source: hosted - version: "1.12.1" + version: "1.12.0" string_scanner: dependency: transitive description: name: string_scanner - sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43" + sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3" url: "https://pub.dev" source: hosted - version: "1.4.1" + version: "1.3.0" term_glyph: dependency: transitive description: name: term_glyph - sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e" + sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 url: "https://pub.dev" source: hosted - version: "1.2.2" + version: "1.2.1" typed_data: dependency: transitive description: @@ -301,17 +301,17 @@ packages: dependency: transitive description: name: yaml - sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce + sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5" url: "https://pub.dev" source: hosted - version: "3.1.3" + version: "3.1.2" yaml_edit: dependency: transitive description: name: yaml_edit - sha256: fb38626579fb345ad00e674e2af3a5c9b0cc4b9bfb8fd7f7ff322c7c9e62aef5 + sha256: e9c1a3543d2da0db3e90270dbb1e4eebc985ee5e3ffe468d83224472b2194a5f url: "https://pub.dev" source: hosted - version: "2.2.2" + version: "2.2.1" sdks: dart: ">=3.6.0 <4.0.0" From 09aa81cc3c573a469b95a9a473c0a58d1618e471 Mon Sep 17 00:00:00 2001 From: Ali Ince Date: Mon, 3 Feb 2025 16:37:11 +0100 Subject: [PATCH 25/29] refactor: remove useless late initializations --- .../my_data/file/file_detail_screen.dart | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/apps/enmeshed/lib/account/my_data/file/file_detail_screen.dart b/apps/enmeshed/lib/account/my_data/file/file_detail_screen.dart index 417cf4eb8..0cfbfa5dd 100644 --- a/apps/enmeshed/lib/account/my_data/file/file_detail_screen.dart +++ b/apps/enmeshed/lib/account/my_data/file/file_detail_screen.dart @@ -31,9 +31,10 @@ class FileDetailScreen extends StatefulWidget { class _FileDetailScreenState extends State { late final Session _session; - late FileDVO? _fileDVO; - late LocalAttributeDVO? _fileReferenceAttribute; - late List? _tags; + late FileDVO _fileDVO; + + LocalAttributeDVO? _fileReferenceAttribute; + List? _tags; AttributeTagCollectionDTO? _tagCollection; bool _isLoadingFile = false; @@ -56,7 +57,7 @@ class _FileDetailScreenState extends State { Widget build(BuildContext context) { return Scaffold( resizeToAvoidBottomInset: false, - appBar: AppBar(title: Text(_fileDVO!.title, style: Theme.of(context).textTheme.titleLarge)), + appBar: AppBar(title: Text(_fileDVO.title, style: Theme.of(context).textTheme.titleLarge)), body: SafeArea( child: Padding( padding: const EdgeInsets.only(top: 16, left: 16, right: 16), @@ -66,10 +67,10 @@ class _FileDetailScreenState extends State { Center( child: Column( children: [ - FileIcon(filename: _fileDVO!.filename, color: Theme.of(context).colorScheme.primary, size: 40), + FileIcon(filename: _fileDVO.filename, color: Theme.of(context).colorScheme.primary, size: 40), Gaps.h8, - Text(_fileDVO!.filename, style: Theme.of(context).textTheme.labelLarge), - Text('${bytesText(context: context, bytes: _fileDVO!.filesize)} - ${getFileExtension(_fileDVO!.filename)}'), + Text(_fileDVO.filename, style: Theme.of(context).textTheme.labelLarge), + Text('${bytesText(context: context, bytes: _fileDVO.filesize)} - ${getFileExtension(_fileDVO.filename)}'), ], ), ), @@ -81,7 +82,7 @@ class _FileDetailScreenState extends State { SelectedTagsSection(tagCollection: _tagCollection!, selectedTagsList: _tags!), Gaps.h16, ], - FileInfoContainer(createdBy: _fileDVO!.createdBy.name, createdAt: _fileDVO!.createdAt), + FileInfoContainer(createdBy: _fileDVO.createdBy.name, createdAt: _fileDVO.createdAt), Gaps.h32, Row( children: [ @@ -90,14 +91,14 @@ class _FileDetailScreenState extends State { Gaps.w8, ], IconButton( - onPressed: _isLoadingFile || DateTime.parse(_fileDVO!.expiresAt).isBefore(DateTime.now()) ? null : _downloadAndSaveFile, + onPressed: _isLoadingFile || DateTime.parse(_fileDVO.expiresAt).isBefore(DateTime.now()) ? null : _downloadAndSaveFile, icon: _isLoadingFile ? const SizedBox(width: 24, height: 24, child: CircularProgressIndicator()) : const Icon(Icons.file_download, size: 24), ), Gaps.w8, IconButton( - onPressed: _isOpeningFile || DateTime.parse(_fileDVO!.expiresAt).isBefore(DateTime.now()) ? null : _openFile, + onPressed: _isOpeningFile || DateTime.parse(_fileDVO.expiresAt).isBefore(DateTime.now()) ? null : _openFile, icon: _isOpeningFile ? const SizedBox(width: 24, height: 24, child: CircularProgressIndicator()) : const Icon(Icons.open_with, size: 24), @@ -152,7 +153,7 @@ class _FileDetailScreenState extends State { final session = GetIt.I.get().getSession(widget.accountId); await moveFileOnDevice( session: session, - fileDVO: _fileDVO!, + fileDVO: _fileDVO, onError: () { if (mounted) showDownloadFileErrorDialog(context); }, @@ -167,7 +168,7 @@ class _FileDetailScreenState extends State { final session = GetIt.I.get().getSession(widget.accountId); await openFile( session: session, - fileDVO: _fileDVO!, + fileDVO: _fileDVO, onError: () { if (mounted) showDownloadFileErrorDialog(context); }, @@ -182,7 +183,7 @@ class _FileDetailScreenState extends State { isScrollControlled: true, builder: (_) => EditFile( accountId: widget.accountId, - fileTitle: _fileDVO!.title, + fileTitle: _fileDVO.title, fileReferenceAttribute: _fileReferenceAttribute!, tagCollection: _tagCollection!, onSave: _loadTags, From 01de942ea00db79c3662aa363dfeb3e96fd0929e Mon Sep 17 00:00:00 2001 From: Ali Ince Date: Tue, 4 Feb 2025 10:08:21 +0100 Subject: [PATCH 26/29] refactor: add barrel export --- apps/enmeshed/lib/account/my_data/file/widgets/widgets.dart | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 apps/enmeshed/lib/account/my_data/file/widgets/widgets.dart diff --git a/apps/enmeshed/lib/account/my_data/file/widgets/widgets.dart b/apps/enmeshed/lib/account/my_data/file/widgets/widgets.dart new file mode 100644 index 000000000..884b56edb --- /dev/null +++ b/apps/enmeshed/lib/account/my_data/file/widgets/widgets.dart @@ -0,0 +1,4 @@ +export 'available_tags_section.dart'; +export 'file_info_container.dart'; +export 'file_tags_container.dart'; +export 'selected_tags_section.dart'; From 2adcc35f1ef180fa4b33d69af89d63b86acbba41 Mon Sep 17 00:00:00 2001 From: Ali Ince Date: Tue, 4 Feb 2025 10:09:15 +0100 Subject: [PATCH 27/29] chore: update FileDetailScreen - fix: import - chore: add spacing to row - chore: early return --- .../my_data/file/file_detail_screen.dart | 29 ++++++++----------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/apps/enmeshed/lib/account/my_data/file/file_detail_screen.dart b/apps/enmeshed/lib/account/my_data/file/file_detail_screen.dart index 0cfbfa5dd..f66f32e8e 100644 --- a/apps/enmeshed/lib/account/my_data/file/file_detail_screen.dart +++ b/apps/enmeshed/lib/account/my_data/file/file_detail_screen.dart @@ -1,4 +1,3 @@ -import 'package:enmeshed/account/my_data/file/widgets/selected_tags_section.dart'; import 'package:enmeshed_runtime_bridge/enmeshed_runtime_bridge.dart'; import 'package:enmeshed_types/enmeshed_types.dart'; import 'package:enmeshed_ui_kit/enmeshed_ui_kit.dart'; @@ -7,8 +6,7 @@ import 'package:get_it/get_it.dart'; import '/core/core.dart'; import 'modals/edit_file.dart'; -import 'widgets/file_info_container.dart'; -import 'widgets/file_tags_container.dart'; +import 'widgets/widgets.dart'; class FileDetailScreen extends StatefulWidget { final String accountId; @@ -85,18 +83,15 @@ class _FileDetailScreenState extends State { FileInfoContainer(createdBy: _fileDVO.createdBy.name, createdAt: _fileDVO.createdAt), Gaps.h32, Row( + spacing: 8, children: [ - if (_isEditable) ...[ - IconButton(onPressed: _onEditFilePressed, icon: const Icon(Icons.edit_outlined, size: 24)), - Gaps.w8, - ], + if (_isEditable) IconButton(onPressed: _onEditFilePressed, icon: const Icon(Icons.edit_outlined, size: 24)), IconButton( onPressed: _isLoadingFile || DateTime.parse(_fileDVO.expiresAt).isBefore(DateTime.now()) ? null : _downloadAndSaveFile, icon: _isLoadingFile ? const SizedBox(width: 24, height: 24, child: CircularProgressIndicator()) : const Icon(Icons.file_download, size: 24), ), - Gaps.w8, IconButton( onPressed: _isOpeningFile || DateTime.parse(_fileDVO.expiresAt).isBefore(DateTime.now()) ? null : _openFile, icon: _isOpeningFile @@ -136,15 +131,15 @@ class _FileDetailScreenState extends State { } Future _loadTags({String? attributeId}) async { - if (_fileReferenceAttribute != null) { - final response = await _session.consumptionServices.attributes.getAttribute(attributeId: attributeId ?? _fileReferenceAttribute!.id); - final expanded = await _session.expander.expandLocalAttributeDTO(response.value); - - setState(() { - _tags = expanded.tags; - _fileReferenceAttribute = expanded; - }); - } + if (_fileReferenceAttribute == null) return; + + final response = await _session.consumptionServices.attributes.getAttribute(attributeId: attributeId ?? _fileReferenceAttribute!.id); + final expanded = await _session.expander.expandLocalAttributeDTO(response.value); + + setState(() { + _tags = expanded.tags; + _fileReferenceAttribute = expanded; + }); } Future _downloadAndSaveFile() async { From a3c52c34a25d690b9d5d8c15b3f87eb6345b9b89 Mon Sep 17 00:00:00 2001 From: Ali Ince Date: Tue, 4 Feb 2025 11:04:24 +0100 Subject: [PATCH 28/29] refactor: make one line --- apps/enmeshed/lib/account/my_data/file/modals/edit_file.dart | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/apps/enmeshed/lib/account/my_data/file/modals/edit_file.dart b/apps/enmeshed/lib/account/my_data/file/modals/edit_file.dart index 195b244ce..58cdbb416 100644 --- a/apps/enmeshed/lib/account/my_data/file/modals/edit_file.dart +++ b/apps/enmeshed/lib/account/my_data/file/modals/edit_file.dart @@ -140,10 +140,7 @@ class _EditFileState extends State { if (mounted) context.pop(); } - void _handleTagSelected({ - required String tagPath, - required bool selected, - }) { + void _handleTagSelected({required String tagPath, required bool selected}) { setState(() { if (selected) { _selectedTags = [..._selectedTags, tagPath]; From 8c3b5f4fd027d5c6ffbb10a4029613e396cfe5c6 Mon Sep 17 00:00:00 2001 From: Ali Ince Date: Tue, 4 Feb 2025 11:04:48 +0100 Subject: [PATCH 29/29] refactor: add _LoadingIndicator --- .../account/my_data/file/file_detail_screen.dart | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/apps/enmeshed/lib/account/my_data/file/file_detail_screen.dart b/apps/enmeshed/lib/account/my_data/file/file_detail_screen.dart index f66f32e8e..e08632c9e 100644 --- a/apps/enmeshed/lib/account/my_data/file/file_detail_screen.dart +++ b/apps/enmeshed/lib/account/my_data/file/file_detail_screen.dart @@ -88,15 +88,11 @@ class _FileDetailScreenState extends State { if (_isEditable) IconButton(onPressed: _onEditFilePressed, icon: const Icon(Icons.edit_outlined, size: 24)), IconButton( onPressed: _isLoadingFile || DateTime.parse(_fileDVO.expiresAt).isBefore(DateTime.now()) ? null : _downloadAndSaveFile, - icon: _isLoadingFile - ? const SizedBox(width: 24, height: 24, child: CircularProgressIndicator()) - : const Icon(Icons.file_download, size: 24), + icon: _isLoadingFile ? const _LoadingIndicator() : const Icon(Icons.file_download, size: 24), ), IconButton( onPressed: _isOpeningFile || DateTime.parse(_fileDVO.expiresAt).isBefore(DateTime.now()) ? null : _openFile, - icon: _isOpeningFile - ? const SizedBox(width: 24, height: 24, child: CircularProgressIndicator()) - : const Icon(Icons.open_with, size: 24), + icon: _isOpeningFile ? const _LoadingIndicator() : const Icon(Icons.open_with, size: 24), ), ], ), @@ -186,3 +182,10 @@ class _FileDetailScreenState extends State { ); } } + +class _LoadingIndicator extends StatelessWidget { + const _LoadingIndicator(); + + @override + Widget build(BuildContext context) => const SizedBox(width: 24, height: 24, child: CircularProgressIndicator()); +}