diff --git a/assets/filters/location/germany.png b/assets/filters/location/germany.png deleted file mode 100644 index 7fce53e..0000000 Binary files a/assets/filters/location/germany.png and /dev/null differ diff --git a/assets/filters/location/germany_frankfurt_am_main.png b/assets/filters/location/germany_frankfurt_am_main.png deleted file mode 100644 index 4050672..0000000 Binary files a/assets/filters/location/germany_frankfurt_am_main.png and /dev/null differ diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 5218817..75f2a71 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -187,6 +187,9 @@ PODS: - shared_preferences_foundation (0.0.1): - Flutter - FlutterMacOS + - sqflite_darwin (0.0.4): + - Flutter + - FlutterMacOS - sqlite3 (3.49.1): - sqlite3/common (= 3.49.1) - sqlite3/common (3.49.1) @@ -237,6 +240,7 @@ DEPENDENCIES: - permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`) - restart_app (from `.symlinks/plugins/restart_app/ios`) - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`) + - sqflite_darwin (from `.symlinks/plugins/sqflite_darwin/darwin`) - sqlite3 - sqlite3_flutter_libs (from `.symlinks/plugins/sqlite3_flutter_libs/darwin`) - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) @@ -300,6 +304,8 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/restart_app/ios" shared_preferences_foundation: :path: ".symlinks/plugins/shared_preferences_foundation/darwin" + sqflite_darwin: + :path: ".symlinks/plugins/sqflite_darwin/darwin" sqlite3_flutter_libs: :path: ".symlinks/plugins/sqlite3_flutter_libs/darwin" url_launcher_ios: @@ -341,6 +347,7 @@ SPEC CHECKSUMS: SDWebImage: f84b0feeb08d2d11e6a9b843cb06d75ebf5b8868 SDWebImageWebPCoder: e38c0a70396191361d60c092933e22c20d5b1380 shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7 + sqflite_darwin: 20b2a3a3b70e43edae938624ce550a3cbf66a3d0 sqlite3: fc1400008a9b3525f5914ed715a5d1af0b8f4983 sqlite3_flutter_libs: f6acaa2172e6bb3e2e70c771661905080e8ebcf2 url_launcher_ios: 694010445543906933d732453a59da0a173ae33d diff --git a/lib/src/components/image_editor/layers/filters/location_filter.dart b/lib/src/components/image_editor/layers/filters/location_filter.dart index a5ea42c..a690332 100644 --- a/lib/src/components/image_editor/layers/filters/location_filter.dart +++ b/lib/src/components/image_editor/layers/filters/location_filter.dart @@ -2,8 +2,12 @@ import 'package:flutter/material.dart'; import 'package:twonly/globals.dart'; import 'package:twonly/src/components/image_editor/layers/filter_layer.dart'; import 'package:twonly/src/components/image_editor/layers/filters/datetime_filter.dart'; -import 'package:twonly/src/components/image_editor/layers/filters/image_filter.dart'; import 'package:twonly/src/proto/api/server_to_client.pb.dart'; +import 'dart:convert'; +import 'package:http/http.dart' as http; +import 'package:path_provider/path_provider.dart'; +import 'package:cached_network_image/cached_network_image.dart'; +import 'dart:io'; class LocationFilter extends StatefulWidget { const LocationFilter({super.key}); @@ -12,17 +16,8 @@ class LocationFilter extends StatefulWidget { State createState() => _LocationFilterState(); } -Map cities = { - "Frankfurt am Main": "germany_frankfurt_am_main.png", -}; - -Map countries = { - "Germany": "germany.png", -}; - class _LocationFilterState extends State { - String? selectedImage; - String overlayText = ""; + String? _imageUrl; Response_Location? location; @override @@ -35,34 +30,60 @@ class _LocationFilterState extends State { final res = await apiProvider.getCurrentLocation(); if (res.isSuccess) { location = res.value.location; - - if (cities.containsKey(location!.city)) { - selectedImage = cities[location!.city]; - overlayText = location!.city; - } else if (countries.containsKey(location!.county)) { - selectedImage = countries[location!.county]; - overlayText = location!.county; - } - + _searchForImage(); setState(() {}); } } + void _searchForImage() async { + if (location == null) return; + List imageIndex = await getStickerIndex(); + // Normalize the city and country for search + String normalizedCity = location!.city.toLowerCase().replaceAll(' ', '_'); + String normalizedCountry = location!.county.toLowerCase(); + + // Search for the city first + for (var item in imageIndex) { + if (item.contains('/cities/$normalizedCountry/')) { + // Check if the item matches the normalized city + if (item.endsWith('$normalizedCity.png')) { + if (item.startsWith("/api/")) { + _imageUrl = "https://twonly.eu/$item"; + setState(() {}); + } + return; + } + } + } + + // If city not found, search for the country + if (_imageUrl == null) { + for (var item in imageIndex) { + if (item.contains('/countries/') && item.contains(normalizedCountry)) { + if (item.startsWith("/api/")) { + _imageUrl = "https://twonly.eu/$item"; + setState(() {}); + } + break; + } + } + } + } + @override Widget build(BuildContext context) { - if (selectedImage != null) { - return Stack( - children: [ - ImageFilter(imagePath: "location/${selectedImage!}"), - Positioned( - bottom: 55, - left: 0, - right: 0, - child: Center( - child: Text(overlayText), + if (_imageUrl != null) { + return FilterSceleton( + child: Positioned( + bottom: 0, + left: 40, + right: 40, + child: Center( + child: CachedNetworkImage( + imageUrl: _imageUrl!, ), - ) - ], + ), + ), ); } @@ -76,7 +97,6 @@ class _LocationFilterState extends State { mainAxisAlignment: MainAxisAlignment.start, children: [ FilterText(location!.city), - FilterText(location!.region), FilterText(location!.county), ], ), @@ -88,3 +108,25 @@ class _LocationFilterState extends State { return DateTimeFilter(color: Colors.black); } } + +Future> getStickerIndex() async { + final directory = await getApplicationCacheDirectory(); + final indexFile = File('${directory.path}/index.json'); + + if (await indexFile.exists()) { + final lastModified = await indexFile.lastModified(); + final difference = DateTime.now().difference(lastModified); + if (difference.inHours < 24) { + final content = await indexFile.readAsString(); + return await json.decode(content).whereType().toList(); + } + } + final response = + await http.get(Uri.parse('https://twonly.eu/api/sticker/index.json')); + if (response.statusCode == 200) { + await indexFile.writeAsString(response.body); + return json.decode(response.body).whereType().toList(); + } else { + return []; + } +} diff --git a/pubspec.lock b/pubspec.lock index d3aebfe..51c6bf4 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -137,6 +137,30 @@ packages: url: "https://pub.dev" source: hosted version: "8.9.5" + cached_network_image: + dependency: "direct main" + description: + name: cached_network_image + sha256: "7c1183e361e5c8b0a0f21a28401eecdbde252441106a9816400dd4c2b2424916" + url: "https://pub.dev" + source: hosted + version: "3.4.1" + cached_network_image_platform_interface: + dependency: transitive + description: + name: cached_network_image_platform_interface + sha256: "35814b016e37fbdc91f7ae18c8caf49ba5c88501813f73ce8a07027a395e2829" + url: "https://pub.dev" + source: hosted + version: "4.1.1" + cached_network_image_web: + dependency: transitive + description: + name: cached_network_image_web + sha256: "980842f4e8e2535b8dbd3d5ca0b1f0ba66bf61d14cc3a17a9b4788a3685ba062" + url: "https://pub.dev" + source: hosted + version: "1.3.1" camera: dependency: "direct main" description: @@ -438,6 +462,14 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_cache_manager: + dependency: transitive + description: + name: flutter_cache_manager + sha256: "400b6592f16a4409a7f2bb929a9a7e38c72cceb8ffb99ee57bbf2cb2cecf8386" + url: "https://pub.dev" + source: hosted + version: "3.4.1" flutter_image_compress: dependency: "direct main" description: @@ -964,6 +996,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.3.1" + octo_image: + dependency: transitive + description: + name: octo_image + sha256: "34faa6639a78c7e3cbe79be6f9f96535867e879748ade7d17c9b1ae7536293bd" + url: "https://pub.dev" + source: hosted + version: "2.1.0" optional: dependency: transitive description: @@ -1228,6 +1268,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.2" + rxdart: + dependency: transitive + description: + name: rxdart + sha256: "5c3004a4a8dbb94bd4bf5412a4def4acdaa12e12f269737a5751369e12d1a962" + url: "https://pub.dev" + source: hosted + version: "0.28.0" screenshot: dependency: "direct main" description: @@ -1345,6 +1393,46 @@ packages: url: "https://pub.dev" source: hosted version: "7.0.0" + sqflite: + dependency: transitive + description: + name: sqflite + sha256: e2297b1da52f127bc7a3da11439985d9b536f75070f3325e62ada69a5c585d03 + url: "https://pub.dev" + source: hosted + version: "2.4.2" + sqflite_android: + dependency: transitive + description: + name: sqflite_android + sha256: "2b3070c5fa881839f8b402ee4a39c1b4d561704d4ebbbcfb808a119bc2a1701b" + url: "https://pub.dev" + source: hosted + version: "2.4.1" + sqflite_common: + dependency: transitive + description: + name: sqflite_common + sha256: "84731e8bfd8303a3389903e01fb2141b6e59b5973cacbb0929021df08dddbe8b" + url: "https://pub.dev" + source: hosted + version: "2.5.5" + sqflite_darwin: + dependency: transitive + description: + name: sqflite_darwin + sha256: "279832e5cde3fe99e8571879498c9211f3ca6391b0d818df4e17d9fff5c6ccb3" + url: "https://pub.dev" + source: hosted + version: "2.4.2" + sqflite_platform_interface: + dependency: transitive + description: + name: sqflite_platform_interface + sha256: "8dd4515c7bdcae0a785b0062859336de775e8c65db81ae33dd5445f35be61920" + url: "https://pub.dev" + source: hosted + version: "2.4.0" sqlite3: dependency: transitive description: @@ -1401,6 +1489,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.4.1" + synchronized: + dependency: transitive + description: + name: synchronized + sha256: "0669c70faae6270521ee4f05bffd2919892d42d1276e6c495be80174b6bc0ef6" + url: "https://pub.dev" + source: hosted + version: "3.3.1" term_glyph: dependency: transitive description: @@ -1505,6 +1601,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.1.4" + uuid: + dependency: transitive + description: + name: uuid + sha256: a5be9ef6618a7ac1e964353ef476418026db906c4facdedaa299b7a2e71690ff + url: "https://pub.dev" + source: hosted + version: "4.5.1" vector_graphics: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 8218f75..f9c7d2b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -62,6 +62,7 @@ dependencies: flutter_volume_controller: ^1.3.3 fixnum: ^1.1.1 mutex: ^3.1.0 + cached_network_image: ^3.4.1 # avatar_maker # avatar_maker: # path: ./dependencies/avatar_maker/ @@ -96,6 +97,5 @@ flutter: - assets/animated_icons/ - assets/animations/ - assets/filters/ - - assets/filters/location/ - assets/filters/random/