Compare commits

..

2 Commits

Author SHA1 Message Date
Jared Bell
c6db38cb09 Merge branch 'main' into ui-polish-4 2023-01-23 10:50:46 -07:00
Jared Bell
5448f97d3d Update icon dimensions to match source PNGs
Retaining base dimension of the icons removes artifacts caused when resizing to non-divisible sizes.

* circle button icons (search)
* Close "X"s
* Main menu icons
2023-01-10 13:22:03 -07:00
289 changed files with 6174 additions and 7902 deletions

1
.gitignore vendored
View File

@ -33,6 +33,7 @@ desktop.ini
/build/
# Web related
lib/generated_plugin_registrant.dart
# Symbolication related
app.*.symbols

View File

@ -1,11 +1,11 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.
# This file should be version controlled.
version:
revision: "efbf63d9c66b9f6ec30e9ad4611189aa80003d31"
channel: "stable"
revision: 75927305ff855f76a9ef704f9b4a86fa2fce7292
channel: beta
project_type: app
@ -13,11 +13,26 @@ project_type: app
migration:
platforms:
- platform: root
create_revision: efbf63d9c66b9f6ec30e9ad4611189aa80003d31
base_revision: efbf63d9c66b9f6ec30e9ad4611189aa80003d31
create_revision: 75927305ff855f76a9ef704f9b4a86fa2fce7292
base_revision: 75927305ff855f76a9ef704f9b4a86fa2fce7292
- platform: android
create_revision: 75927305ff855f76a9ef704f9b4a86fa2fce7292
base_revision: 75927305ff855f76a9ef704f9b4a86fa2fce7292
- platform: ios
create_revision: 75927305ff855f76a9ef704f9b4a86fa2fce7292
base_revision: 75927305ff855f76a9ef704f9b4a86fa2fce7292
- platform: linux
create_revision: 75927305ff855f76a9ef704f9b4a86fa2fce7292
base_revision: 75927305ff855f76a9ef704f9b4a86fa2fce7292
- platform: macos
create_revision: 75927305ff855f76a9ef704f9b4a86fa2fce7292
base_revision: 75927305ff855f76a9ef704f9b4a86fa2fce7292
- platform: web
create_revision: efbf63d9c66b9f6ec30e9ad4611189aa80003d31
base_revision: efbf63d9c66b9f6ec30e9ad4611189aa80003d31
create_revision: 75927305ff855f76a9ef704f9b4a86fa2fce7292
base_revision: 75927305ff855f76a9ef704f9b4a86fa2fce7292
- platform: windows
create_revision: 75927305ff855f76a9ef704f9b4a86fa2fce7292
base_revision: 75927305ff855f76a9ef704f9b4a86fa2fce7292
# User provided section

View File

@ -23,17 +23,32 @@ To try the app you can download it from your favorite app store:
If you're new to Flutter the first thing you'll need is to follow the [setup instructions](https://flutter.dev/docs/get-started/install).
Once Flutter is setup, you can use the latest `stable` channel:
* `flutter channel stable`
Once Flutter is setup, you can use the latest `beta` channel:
* `flutter channel beta`
* `flutter upgrade`
Once on `stable` you're ready to run the app on your local device or simulator:
Once on `beta` you're ready to run the app on your local device or simulator:
* `flutter run -d ios`
* `flutter run -d android`
### Impeller Rendering
### Impeller Rendering Layer
This app uses the new [Impeller Runtime](https://docs.flutter.dev/perf/impeller) by default on iOS.
Impeller is Flutter's next-generation rendering layer, that takes full advantage of modern hardware-accelerated graphics APIs. It is currently available as an **early adopter preview**, but is not yet feature-complete or fully optimized.
The version of Wonderous available in the iOS app store uses Impeller, but by default this code base does not. If you'd like to enable Impeller for iOS, follow these steps:
Edit the `Info.plist` file and set `FLTEnableImpeller` to `true`:
```
<key>FLTEnableImpeller</key>
<true/>
```
Then, switch to the `master` channel and build as normal:
* `flutter channel master`
* `flutter upgrade`
* `flutter run -d ios`
**Note:** Currently, when Impeller is enabled testing in Simulator will not work, you will need to test on a physical device.
# About gskinner
We build innovative digital experiences for smart clients, and we love how Flutter unleashes our creativity when building multi-platform apps. Don't hesitate to [stop by our site](https://gskinner.com/) to learn more about what we do, or check out other [innovative Flutter projects](https://flutter.gskinner.com) we've built. We'd love to hear from you!

View File

@ -9,11 +9,6 @@
# packages, and plugins designed to encourage good coding practices.
include: package:flutter_lints/flutter.yaml
analyzer:
errors:
prefer_const_constructors: ignore
unused_element: ignore # mostly because of super.key
linter:
# The lint rules applied to this project can be customized in the
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
@ -27,8 +22,9 @@ linter:
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
# producing the lint.
rules:
- always_declare_return_types
- always_use_package_imports
- prefer_single_quotes
always_declare_return_types: true
always_use_package_imports: true
prefer_const_constructors: false
prefer_single_quotes: true
# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options

View File

@ -33,7 +33,7 @@ apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android {
compileSdkVersion 34
compileSdkVersion flutter.compileSdkVersion
defaultConfig {
configurations.all {
@ -47,9 +47,17 @@ android {
versionName flutterVersionName
}
signingConfigs {
release {
keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword']
storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
storePassword keystoreProperties['storePassword']
}
}
buildTypes {
release {
signingConfig signingConfigs.debug
signingConfig signingConfigs.release
}
}

View File

@ -1,6 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.gskinner.flutter.wonders">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:label="Wonderous"
android:requestLegacyExternalStorage="true"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 B

After

Width:  |  Height:  |  Size: 70 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 42 KiB

View File

Before

Width:  |  Height:  |  Size: 123 KiB

After

Width:  |  Height:  |  Size: 123 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 B

After

Width:  |  Height:  |  Size: 70 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -1,21 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
<item name="android:forceDarkAllowed">false</item>
<item name="android:windowFullscreen">false</item>
<item name="android:windowDrawsSystemBarBackgrounds">false</item>
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
<item name="android:windowSplashScreenBackground">#272625</item>
<item name="android:windowSplashScreenAnimatedIcon">@drawable/android12splash</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
</resources>

View File

@ -5,10 +5,6 @@
<!-- Show a splash screen on the activity. Automatically removed when
Flutter draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
<item name="android:forceDarkAllowed">false</item>
<item name="android:windowFullscreen">false</item>
<item name="android:windowDrawsSystemBarBackgrounds">false</item>
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your

View File

@ -4,7 +4,6 @@
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
<item name="android:forceDarkAllowed">false</item>
<item name="android:windowFullscreen">false</item>
<item name="android:windowDrawsSystemBarBackgrounds">false</item>
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
<item name="android:windowSplashScreenBackground">#272625</item>
<item name="android:windowSplashScreenAnimatedIcon">@drawable/android12splash</item>

View File

@ -7,7 +7,6 @@
<item name="android:windowBackground">@drawable/launch_background</item>
<item name="android:forceDarkAllowed">false</item>
<item name="android:windowFullscreen">false</item>
<item name="android:windowDrawsSystemBarBackgrounds">false</item>
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.

View File

@ -1,5 +1,5 @@
buildscript {
ext.kotlin_version = '1.9.10'
ext.kotlin_version = '1.6.10'
ext.maps_version = '18.1.0'
repositories {
@ -8,7 +8,7 @@ buildscript {
}
dependencies {
classpath 'com.android.tools.build:gradle:7.3.0'
classpath 'com.android.tools.build:gradle:4.1.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
@ -28,6 +28,6 @@ subprojects {
project.evaluationDependsOn(':app')
}
tasks.register("clean", Delete) {
task clean(type: Delete) {
delete rootProject.buildDir
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 170 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 285 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 565 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 954 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 795 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 795 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 91 KiB

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 168 KiB

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 262 KiB

After

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 217 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -1,83 +1,95 @@
PODS:
- Flutter (1.0.0)
- flutter_inappwebview (0.0.1):
- Flutter
- flutter_inappwebview/Core (= 0.0.1)
- OrderedSet (~> 5.0)
- flutter_inappwebview/Core (0.0.1):
- Flutter
- OrderedSet (~> 5.0)
- flutter_native_splash (0.0.1):
- Flutter
- google_maps_flutter_ios (0.0.1):
- Flutter
- GoogleMaps (< 9.0)
- GoogleMaps
- GoogleMaps (6.2.1):
- GoogleMaps/Maps (= 6.2.1)
- GoogleMaps/Base (6.2.1)
- GoogleMaps/Maps (6.2.1):
- GoogleMaps/Base
- home_widget (0.0.1):
- image_gallery_saver (1.5.0):
- Flutter
- image_gallery_saver (2.0.2):
- integration_test (0.0.1):
- Flutter
- OrderedSet (5.0.0)
- package_info_plus (0.4.5):
- Flutter
- path_provider_foundation (0.0.1):
- path_provider_ios (0.0.1):
- Flutter
- FlutterMacOS
- shared_preferences_foundation (0.0.1):
- share_plus (0.0.1):
- Flutter
- shared_preferences_ios (0.0.1):
- Flutter
- FlutterMacOS
- url_launcher_ios (0.0.1):
- Flutter
- webview_flutter_wkwebview (0.0.1):
- Flutter
DEPENDENCIES:
- Flutter (from `Flutter`)
- flutter_inappwebview (from `.symlinks/plugins/flutter_inappwebview/ios`)
- flutter_native_splash (from `.symlinks/plugins/flutter_native_splash/ios`)
- google_maps_flutter_ios (from `.symlinks/plugins/google_maps_flutter_ios/ios`)
- home_widget (from `.symlinks/plugins/home_widget/ios`)
- image_gallery_saver (from `.symlinks/plugins/image_gallery_saver/ios`)
- integration_test (from `.symlinks/plugins/integration_test/ios`)
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
- path_provider_ios (from `.symlinks/plugins/path_provider_ios/ios`)
- share_plus (from `.symlinks/plugins/share_plus/ios`)
- shared_preferences_ios (from `.symlinks/plugins/shared_preferences_ios/ios`)
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
- webview_flutter_wkwebview (from `.symlinks/plugins/webview_flutter_wkwebview/ios`)
SPEC REPOS:
trunk:
- GoogleMaps
- OrderedSet
EXTERNAL SOURCES:
Flutter:
:path: Flutter
flutter_inappwebview:
:path: ".symlinks/plugins/flutter_inappwebview/ios"
flutter_native_splash:
:path: ".symlinks/plugins/flutter_native_splash/ios"
google_maps_flutter_ios:
:path: ".symlinks/plugins/google_maps_flutter_ios/ios"
home_widget:
:path: ".symlinks/plugins/home_widget/ios"
image_gallery_saver:
:path: ".symlinks/plugins/image_gallery_saver/ios"
integration_test:
:path: ".symlinks/plugins/integration_test/ios"
package_info_plus:
:path: ".symlinks/plugins/package_info_plus/ios"
path_provider_foundation:
:path: ".symlinks/plugins/path_provider_foundation/darwin"
shared_preferences_foundation:
:path: ".symlinks/plugins/shared_preferences_foundation/darwin"
path_provider_ios:
:path: ".symlinks/plugins/path_provider_ios/ios"
share_plus:
:path: ".symlinks/plugins/share_plus/ios"
shared_preferences_ios:
:path: ".symlinks/plugins/shared_preferences_ios/ios"
url_launcher_ios:
:path: ".symlinks/plugins/url_launcher_ios/ios"
webview_flutter_wkwebview:
:path: ".symlinks/plugins/webview_flutter_wkwebview/ios"
SPEC CHECKSUMS:
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
flutter_inappwebview: bfd58618f49dc62f2676de690fc6dcda1d6c3721
flutter_native_splash: 52501b97d1c0a5f898d687f1646226c1f93c56ef
google_maps_flutter_ios: d1318b4ff711612cab16862d7a87e31a7403d458
google_maps_flutter_ios: 66201f392bf62d500f07670a30488a247b9bb5b9
GoogleMaps: 20d7b12be49a14287f797e88e0e31bc4156aaeb4
home_widget: 0434835a4c9a75704264feff6be17ea40e0f0d57
image_gallery_saver: cb43cc43141711190510e92c460eb1655cd343cb
package_info_plus: 115f4ad11e0698c8c1c5d8a689390df880f47e85
path_provider_foundation: 3784922295ac71e43754bd15e0653ccfd36a147c
shared_preferences_foundation: b4c3b4cddf1c21f02770737f147a3f5da9d39695
url_launcher_ios: bbd758c6e7f9fd7b5b1d4cde34d2b95fcce5e812
webview_flutter_wkwebview: 4f3e50f7273d31e5500066ed267e3ae4309c5ae4
image_gallery_saver: 259eab68fb271cfd57d599904f7acdc7832e7ef2
integration_test: a1e7d09bd98eca2fc37aefd79d4f41ad37bdbbe5
OrderedSet: aaeb196f7fef5a9edf55d89760da9176ad40b93c
package_info_plus: 6c92f08e1f853dc01228d6f553146438dafcd14e
path_provider_ios: 14f3d2fd28c4fdb42f44e0f751d12861c43cee02
share_plus: 056a1e8ac890df3e33cb503afffaf1e9b4fbae68
shared_preferences_ios: 548a61f8053b9b8a49ac19c1ffbc8b92c50d68ad
url_launcher_ios: 839c58cdb4279282219f5e248c3321761ff3c4de
PODFILE CHECKSUM: ef19549a9bc3046e7bb7d2fab4d021637c0c58a3
COCOAPODS: 1.15.0
COCOAPODS: 1.11.3

View File

@ -8,18 +8,6 @@
/* Begin PBXBuildFile section */
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
296251252AE7410D00D574FF /* Colors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 296251242AE7410D00D574FF /* Colors.swift */; };
2978ECDD2B62D00C00E36CE8 /* FlutterAssets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2978ECDC2B62D00C00E36CE8 /* FlutterAssets.swift */; };
297F6FC72AD06E0D00FF159E /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 297F6FC62AD06E0D00FF159E /* WidgetKit.framework */; };
297F6FC92AD06E0D00FF159E /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 297F6FC82AD06E0D00FF159E /* SwiftUI.framework */; };
297F6FCC2AD06E0D00FF159E /* WonderousWidgetBundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 297F6FCB2AD06E0D00FF159E /* WonderousWidgetBundle.swift */; };
297F6FCE2AD06E0D00FF159E /* WonderousWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 297F6FCD2AD06E0D00FF159E /* WonderousWidget.swift */; };
297F6FD12AD06E0F00FF159E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 297F6FD02AD06E0F00FF159E /* Assets.xcassets */; };
297F6FD32AD06E0F00FF159E /* WonderousWidget.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = 297F6FCF2AD06E0D00FF159E /* WonderousWidget.intentdefinition */; };
297F6FD42AD06E0F00FF159E /* WonderousWidget.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = 297F6FCF2AD06E0D00FF159E /* WonderousWidget.intentdefinition */; };
297F6FD72AD06E0F00FF159E /* Wonderous WidgetExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 297F6FC52AD06E0D00FF159E /* Wonderous WidgetExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
297FD5742AE18011008D8BFE /* WonderousWidgetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 297FD5732AE18011008D8BFE /* WonderousWidgetView.swift */; };
297FD5762AE19BD9008D8BFE /* WonderWidgetViewComponents.swift in Sources */ = {isa = PBXBuildFile; fileRef = 297FD5752AE19BD9008D8BFE /* WonderWidgetViewComponents.swift */; };
323DE3CFA8490EAB3C4E249C /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4A44ACC5DE81A9C3E5BDA151 /* Pods_Runner.framework */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
@ -29,13 +17,6 @@
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
297F6FD52AD06E0F00FF159E /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 97C146E61CF9000F007C117D /* Project object */;
proxyType = 1;
remoteGlobalIDString = 297F6FC42AD06E0D00FF159E;
remoteInfo = WonderousWidgetExtension;
};
E214FC8827C5A18E005F78FB /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 97C146E61CF9000F007C117D /* Project object */;
@ -46,17 +27,6 @@
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
297F6FD82AD06E0F00FF159E /* Embed Foundation Extensions */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 13;
files = (
297F6FD72AD06E0F00FF159E /* Wonderous WidgetExtension.appex in Embed Foundation Extensions */,
);
name = "Embed Foundation Extensions";
runOnlyForDeploymentPostprocessing = 0;
};
9705A1C41CF9048500538489 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
@ -73,19 +43,6 @@
1475293CB8660AC785DF56AB /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
296251242AE7410D00D574FF /* Colors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Colors.swift; sourceTree = "<group>"; };
2978ECDC2B62D00C00E36CE8 /* FlutterAssets.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlutterAssets.swift; sourceTree = "<group>"; };
297F6FC52AD06E0D00FF159E /* Wonderous WidgetExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; name = "Wonderous WidgetExtension.appex"; path = WonderousWidgetExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
297F6FC62AD06E0D00FF159E /* WidgetKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WidgetKit.framework; path = System/Library/Frameworks/WidgetKit.framework; sourceTree = SDKROOT; };
297F6FC82AD06E0D00FF159E /* SwiftUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftUI.framework; path = System/Library/Frameworks/SwiftUI.framework; sourceTree = SDKROOT; };
297F6FCB2AD06E0D00FF159E /* WonderousWidgetBundle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WonderousWidgetBundle.swift; sourceTree = "<group>"; };
297F6FCD2AD06E0D00FF159E /* WonderousWidget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WonderousWidget.swift; sourceTree = "<group>"; };
297F6FCF2AD06E0D00FF159E /* WonderousWidget.intentdefinition */ = {isa = PBXFileReference; lastKnownFileType = file.intentdefinition; path = WonderousWidget.intentdefinition; sourceTree = "<group>"; };
297F6FD02AD06E0F00FF159E /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
297F6FD22AD06E0F00FF159E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
297FD56C2ADF0DAB008D8BFE /* WonderousWidgetExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = WonderousWidgetExtension.entitlements; sourceTree = "<group>"; };
297FD5732AE18011008D8BFE /* WonderousWidgetView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WonderousWidgetView.swift; sourceTree = "<group>"; };
297FD5752AE19BD9008D8BFE /* WonderWidgetViewComponents.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WonderWidgetViewComponents.swift; sourceTree = "<group>"; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
4A44ACC5DE81A9C3E5BDA151 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
@ -105,15 +62,6 @@
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
297F6FC22AD06E0D00FF159E /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
297F6FC92AD06E0D00FF159E /* SwiftUI.framework in Frameworks */,
297F6FC72AD06E0D00FF159E /* WidgetKit.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
97C146EB1CF9000F007C117D /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
@ -132,28 +80,10 @@
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
297F6FCA2AD06E0D00FF159E /* WonderousWidget */ = {
isa = PBXGroup;
children = (
297F6FCB2AD06E0D00FF159E /* WonderousWidgetBundle.swift */,
297F6FCD2AD06E0D00FF159E /* WonderousWidget.swift */,
297F6FCF2AD06E0D00FF159E /* WonderousWidget.intentdefinition */,
297F6FD02AD06E0F00FF159E /* Assets.xcassets */,
297F6FD22AD06E0F00FF159E /* Info.plist */,
297FD5732AE18011008D8BFE /* WonderousWidgetView.swift */,
297FD5752AE19BD9008D8BFE /* WonderWidgetViewComponents.swift */,
296251242AE7410D00D574FF /* Colors.swift */,
2978ECDC2B62D00C00E36CE8 /* FlutterAssets.swift */,
);
path = WonderousWidget;
sourceTree = "<group>";
};
5073AC1D92C10773F20D12A2 /* Frameworks */ = {
isa = PBXGroup;
children = (
4A44ACC5DE81A9C3E5BDA151 /* Pods_Runner.framework */,
297F6FC62AD06E0D00FF159E /* WidgetKit.framework */,
297F6FC82AD06E0D00FF159E /* SwiftUI.framework */,
);
name = Frameworks;
sourceTree = "<group>";
@ -172,10 +102,8 @@
97C146E51CF9000F007C117D = {
isa = PBXGroup;
children = (
297FD56C2ADF0DAB008D8BFE /* WonderousWidgetExtension.entitlements */,
9740EEB11CF90186004384FC /* Flutter */,
97C146F01CF9000F007C117D /* Runner */,
297F6FCA2AD06E0D00FF159E /* WonderousWidget */,
97C146EF1CF9000F007C117D /* Products */,
5073AC1D92C10773F20D12A2 /* Frameworks */,
E090BB04291350D10AF9DE4E /* Pods */,
@ -187,7 +115,6 @@
children = (
97C146EE1CF9000F007C117D /* Runner.app */,
E214FC8227C5A18D005F78FB /* wondersUITests.xctest */,
297F6FC52AD06E0D00FF159E /* Wonderous WidgetExtension.appex */,
);
name = Products;
sourceTree = "<group>";
@ -221,23 +148,6 @@
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
297F6FC42AD06E0D00FF159E /* WonderousWidgetExtension */ = {
isa = PBXNativeTarget;
buildConfigurationList = 297F6FDC2AD06E0F00FF159E /* Build configuration list for PBXNativeTarget "WonderousWidgetExtension" */;
buildPhases = (
297F6FC12AD06E0D00FF159E /* Sources */,
297F6FC22AD06E0D00FF159E /* Frameworks */,
297F6FC32AD06E0D00FF159E /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = WonderousWidgetExtension;
productName = WonderousWidgetExtension;
productReference = 297F6FC52AD06E0D00FF159E /* Wonderous WidgetExtension.appex */;
productType = "com.apple.product-type.app-extension";
};
97C146ED1CF9000F007C117D /* Runner */ = {
isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
@ -247,7 +157,6 @@
97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */,
297F6FD82AD06E0F00FF159E /* Embed Foundation Extensions */,
9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
9DAF500633B345EE15CA82E0 /* [CP] Embed Pods Frameworks */,
@ -256,7 +165,6 @@
buildRules = (
);
dependencies = (
297F6FD62AD06E0F00FF159E /* PBXTargetDependency */,
);
name = Runner;
productName = Runner;
@ -290,13 +198,10 @@
KnownAssetTags = (
New,
);
LastSwiftUpdateCheck = 1430;
LastUpgradeCheck = 1430;
LastSwiftUpdateCheck = 1320;
LastUpgradeCheck = 1300;
ORGANIZATIONNAME = "";
TargetAttributes = {
297F6FC42AD06E0D00FF159E = {
CreatedOnToolsVersion = 14.3.1;
};
97C146ED1CF9000F007C117D = {
CreatedOnToolsVersion = 7.3.1;
LastSwiftMigration = 1100;
@ -322,20 +227,11 @@
targets = (
97C146ED1CF9000F007C117D /* Runner */,
E214FC8127C5A18D005F78FB /* wondersUITests */,
297F6FC42AD06E0D00FF159E /* WonderousWidgetExtension */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
297F6FC32AD06E0D00FF159E /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
297F6FD12AD06E0F00FF159E /* Assets.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
97C146EC1CF9000F007C117D /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
@ -386,7 +282,6 @@
files = (
);
inputPaths = (
"${TARGET_BUILD_DIR}/${INFOPLIST_PATH}",
);
name = "Thin Binary";
outputPaths = (
@ -447,25 +342,10 @@
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
297F6FC12AD06E0D00FF159E /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
297FD5762AE19BD9008D8BFE /* WonderWidgetViewComponents.swift in Sources */,
296251252AE7410D00D574FF /* Colors.swift in Sources */,
297F6FD32AD06E0F00FF159E /* WonderousWidget.intentdefinition in Sources */,
2978ECDD2B62D00C00E36CE8 /* FlutterAssets.swift in Sources */,
297FD5742AE18011008D8BFE /* WonderousWidgetView.swift in Sources */,
297F6FCE2AD06E0D00FF159E /* WonderousWidget.swift in Sources */,
297F6FCC2AD06E0D00FF159E /* WonderousWidgetBundle.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
97C146EA1CF9000F007C117D /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
297F6FD42AD06E0F00FF159E /* WonderousWidget.intentdefinition in Sources */,
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
);
@ -481,11 +361,6 @@
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
297F6FD62AD06E0F00FF159E /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 297F6FC42AD06E0D00FF159E /* WonderousWidgetExtension */;
targetProxy = 297F6FD52AD06E0F00FF159E /* PBXContainerItemProxy */;
};
E214FC8927C5A18E005F78FB /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 97C146ED1CF9000F007C117D /* Runner */;
@ -569,12 +444,9 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 4;
DEVELOPMENT_TEAM = S3TL5AY6Y3;
ENABLE_BITCODE = NO;
@ -586,7 +458,6 @@
);
PRODUCT_BUNDLE_IDENTIFIER = com.gskinner.flutter.wonders;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
@ -594,120 +465,6 @@
};
name = Profile;
};
297F6FD92AD06E0F00FF159E /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_ENTITLEMENTS = WonderousWidgetExtension.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = S3TL5AY6Y3;
GCC_C_LANGUAGE_STANDARD = gnu11;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = WonderousWidget/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = "Wonderous Widget";
INFOPLIST_KEY_NSHumanReadableCopyright = "";
IPHONEOS_DEPLOYMENT_TARGET = 16.4;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 1.0;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = "com.gskinner.flutter.wonders.Wonderous-Widget";
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
297F6FDA2AD06E0F00FF159E /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_ENTITLEMENTS = WonderousWidgetExtension.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = S3TL5AY6Y3;
GCC_C_LANGUAGE_STANDARD = gnu11;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = WonderousWidget/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = "Wonderous Widget";
INFOPLIST_KEY_NSHumanReadableCopyright = "";
IPHONEOS_DEPLOYMENT_TARGET = 16.4;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 1.0;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = "com.gskinner.flutter.wonders.Wonderous-Widget";
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
297F6FDB2AD06E0F00FF159E /* Profile */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_ENTITLEMENTS = "Wonderous WidgetExtension.entitlements";
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = S3TL5AY6Y3;
GCC_C_LANGUAGE_STANDARD = gnu11;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = "Wonderous Widget/Info.plist";
INFOPLIST_KEY_CFBundleDisplayName = "Wonderous Widget";
INFOPLIST_KEY_NSHumanReadableCopyright = "";
IPHONEOS_DEPLOYMENT_TARGET = 16.4;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 1.0;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = "com.gskinner.flutter.wonders.Wonderous-Widget";
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Profile;
};
97C147031CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
@ -823,12 +580,9 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 4;
DEVELOPMENT_TEAM = S3TL5AY6Y3;
ENABLE_BITCODE = NO;
@ -840,7 +594,6 @@
);
PRODUCT_BUNDLE_IDENTIFIER = com.gskinner.flutter.wonders;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
@ -853,7 +606,6 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
@ -962,16 +714,6 @@
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
297F6FDC2AD06E0F00FF159E /* Build configuration list for PBXNativeTarget "WonderousWidgetExtension" */ = {
isa = XCConfigurationList;
buildConfigurations = (
297F6FD92AD06E0F00FF159E /* Debug */,
297F6FDA2AD06E0F00FF159E /* Release */,
297F6FDB2AD06E0F00FF159E /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
isa = XCConfigurationList;
buildConfigurations = (

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1430"
LastUpgradeVersion = "1300"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"

View File

@ -1,122 +1,122 @@
{
"images": [
"images" : [
{
"filename": "Icon-App-20x20@2x.png",
"idiom": "iphone",
"scale": "2x",
"size": "20x20"
"size" : "20x20",
"idiom" : "iphone",
"filename" : "Icon-App-20x20@2x.png",
"scale" : "2x"
},
{
"filename": "Icon-App-20x20@3x.png",
"idiom": "iphone",
"scale": "3x",
"size": "20x20"
"size" : "20x20",
"idiom" : "iphone",
"filename" : "Icon-App-20x20@3x.png",
"scale" : "3x"
},
{
"filename": "Icon-App-29x29@1x.png",
"idiom": "iphone",
"scale": "1x",
"size": "29x29"
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@1x.png",
"scale" : "1x"
},
{
"filename": "Icon-App-29x29@2x.png",
"idiom": "iphone",
"scale": "2x",
"size": "29x29"
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@2x.png",
"scale" : "2x"
},
{
"filename": "Icon-App-29x29@3x.png",
"idiom": "iphone",
"scale": "3x",
"size": "29x29"
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@3x.png",
"scale" : "3x"
},
{
"filename": "Icon-App-40x40@2x.png",
"idiom": "iphone",
"scale": "2x",
"size": "40x40"
"size" : "40x40",
"idiom" : "iphone",
"filename" : "Icon-App-40x40@2x.png",
"scale" : "2x"
},
{
"filename": "Icon-App-40x40@3x.png",
"idiom": "iphone",
"scale": "3x",
"size": "40x40"
"size" : "40x40",
"idiom" : "iphone",
"filename" : "Icon-App-40x40@3x.png",
"scale" : "3x"
},
{
"filename": "Icon-App-60x60@2x.png",
"idiom": "iphone",
"scale": "2x",
"size": "60x60"
"size" : "60x60",
"idiom" : "iphone",
"filename" : "Icon-App-60x60@2x.png",
"scale" : "2x"
},
{
"filename": "Icon-App-60x60@3x.png",
"idiom": "iphone",
"scale": "3x",
"size": "60x60"
"size" : "60x60",
"idiom" : "iphone",
"filename" : "Icon-App-60x60@3x.png",
"scale" : "3x"
},
{
"filename": "Icon-App-20x20@1x.png",
"idiom": "ipad",
"scale": "1x",
"size": "20x20"
"size" : "20x20",
"idiom" : "ipad",
"filename" : "Icon-App-20x20@1x.png",
"scale" : "1x"
},
{
"filename": "Icon-App-20x20@2x.png",
"idiom": "ipad",
"scale": "2x",
"size": "20x20"
"size" : "20x20",
"idiom" : "ipad",
"filename" : "Icon-App-20x20@2x.png",
"scale" : "2x"
},
{
"filename": "Icon-App-29x29@1x.png",
"idiom": "ipad",
"scale": "1x",
"size": "29x29"
"size" : "29x29",
"idiom" : "ipad",
"filename" : "Icon-App-29x29@1x.png",
"scale" : "1x"
},
{
"filename": "Icon-App-29x29@2x.png",
"idiom": "ipad",
"scale": "2x",
"size": "29x29"
"size" : "29x29",
"idiom" : "ipad",
"filename" : "Icon-App-29x29@2x.png",
"scale" : "2x"
},
{
"filename": "Icon-App-40x40@1x.png",
"idiom": "ipad",
"scale": "1x",
"size": "40x40"
"size" : "40x40",
"idiom" : "ipad",
"filename" : "Icon-App-40x40@1x.png",
"scale" : "1x"
},
{
"filename": "Icon-App-40x40@2x.png",
"idiom": "ipad",
"scale": "2x",
"size": "40x40"
"size" : "40x40",
"idiom" : "ipad",
"filename" : "Icon-App-40x40@2x.png",
"scale" : "2x"
},
{
"filename": "Icon-App-76x76@1x.png",
"idiom": "ipad",
"scale": "1x",
"size": "76x76"
"size" : "76x76",
"idiom" : "ipad",
"filename" : "Icon-App-76x76@1x.png",
"scale" : "1x"
},
{
"filename": "Icon-App-76x76@2x.png",
"idiom": "ipad",
"scale": "2x",
"size": "76x76"
"size" : "76x76",
"idiom" : "ipad",
"filename" : "Icon-App-76x76@2x.png",
"scale" : "2x"
},
{
"filename": "Icon-App-83.5x83.5@2x.png",
"idiom": "ipad",
"scale": "2x",
"size": "83.5x83.5"
"size" : "83.5x83.5",
"idiom" : "ipad",
"filename" : "Icon-App-83.5x83.5@2x.png",
"scale" : "2x"
},
{
"filename": "Icon-App-1024x1024@1x.png",
"idiom": "ios-marketing",
"scale": "1x",
"size": "1024x1024"
"size" : "1024x1024",
"idiom" : "ios-marketing",
"filename" : "Icon-App-1024x1024@1x.png",
"scale" : "1x"
}
],
"info": {
"author": "icons_launcher",
"version": 1
"info" : {
"version" : 1,
"author" : "xcode"
}
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 452 KiB

After

Width:  |  Height:  |  Size: 500 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 632 B

After

Width:  |  Height:  |  Size: 700 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 973 B

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 B

After

Width:  |  Height:  |  Size: 70 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 42 KiB

View File

@ -1,60 +1,60 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>FlutterDeepLinkingEnabled</key>
<true/>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
<string>Wonderous</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleLocalizations</key>
<array>
<string>en</string>
<string>zh_CN</string>
</array>
<key>CFBundleName</key>
<string>wonders</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>$(FLUTTER_BUILD_NAME)</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(FLUTTER_BUILD_NUMBER)</string>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Show a google maps view.</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>Save wallpapers to the gallery!</string>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UIStatusBarHidden</key>
<false/>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
</dict>
<dict>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
<string>Wonderous</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleLocalizations</key>
<array>
<string>en</string>
<string>zh_CN</string>
</array>
<key>CFBundleName</key>
<string>wonders</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>$(FLUTTER_BUILD_NAME)</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(FLUTTER_BUILD_NUMBER)</string>
<key>FLTEnableImpeller</key>
<false/>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Show a google maps view.</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>Save wallpapers to the gallery!</string>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UIStatusBarHidden</key>
<false/>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
</dict>
</plist>

View File

@ -4,9 +4,5 @@
<dict>
<key>aps-environment</key>
<string>development</string>
<key>com.apple.security.application-groups</key>
<array>
<string>group.com.gskinner.flutter.wonders.widget</string>
</array>
</dict>
</plist>

View File

@ -1,13 +0,0 @@
{
"images" : [
{
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -1,6 +0,0 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -1,11 +0,0 @@
{
"colors" : [
{
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -1,11 +0,0 @@
import Foundation
import SwiftUI
/// Define some custom extensions on the Color class, so we can use the shorthand syntax `..myColor`
extension Color {
public static let accent = Color(red: 0.89, green: 0.58, blue: 0.36)
public static let offWhite = Color(red: 0.97, green: 0.92, blue: 0.9)
public static let mediumGrey = Color(red: 0.62, green: 0.6, blue: 0.58)
public static let darkGrey = Color(red: 0.15, green: 0.15, blue: 0.15)
public static let body = Color(red: 0.32, green: 0.31, blue: 0.3);
}

View File

@ -1,22 +0,0 @@
import Foundation
struct FlutterImages {
static let bgEmpty = getAssetPath("/assets/images/widget/background-empty.jpg")
static let icon = getAssetPath("/assets/images/widget/wonderous-icon.png")
}
func getAssetPath(_ path : String) -> String {
return assetBundleUrl.appending(path: path).path()
}
// Returns a file path to the location of the flutter assetBundle
var assetBundleUrl: URL {
let bundle = Bundle.main
if bundle.bundleURL.pathExtension == "appex" {
// Peel off two directory levels - MY_APP.app/PlugIns/MY_APP_EXTENSION.appex
var url = bundle.bundleURL.deletingLastPathComponent().deletingLastPathComponent()
url.append(component: "Frameworks/App.framework/flutter_assets")
return url
}
return bundle.bundleURL
}

View File

@ -1,11 +0,0 @@
//
// FlutterUtils.swift
// Wonderous WidgetExtension
//
// Created by Shawn on 2023-10-19.
//
import Foundation

View File

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSExtension</key>
<dict>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.widgetkit-extension</string>
</dict>
</dict>
</plist>

View File

@ -1,63 +0,0 @@
import Foundation
import SwiftUI
// Loads a default image from the flutter assets bundle,
// or displays a base64 encoded image that has been saved from the flutter application
struct BgImage : View {
var entry: WonderousTimelineEntry
var body: some View {
var uiImage:UIImage?;
// If there is no saved imageData, use the default bg image
if(entry.imageData.isEmpty){
uiImage = UIImage(contentsOfFile: FlutterImages.bgEmpty);
}
// Load a base64 encoded image that has been written by the flutter app
else {
uiImage = UIImage(data: Data(base64Encoded: entry.imageData)!)
}
if(uiImage != nil){
// Use geometry reader to prevent an oversized bg image from pushing the other content out of the widgets bounds (https://stackoverflow.com/questions/57593552/swiftui-prevent-image-from-expanding-view-rect-outside-of-screen-bounds)
let image = GeometryReader { geometry in
Image(uiImage: uiImage!)
.resizable()
.aspectRatio(contentMode: .fill)
.edgesIgnoringSafeArea(.all) // Ignore the safe area
.frame(maxWidth: geometry.size.width, maxHeight: geometry.size.height)
}
return AnyView(image)
}
debugPrint("The image file could not be loaded")
return AnyView(EmptyView())
}
}
// Declares a restyled version of the native ProgressView
struct GaugeProgressStyle: ProgressViewStyle {
func makeBody(configuration: Configuration) -> some View {
let fractionCompleted = configuration.fractionCompleted ?? 0
return ZStack {
Circle()
.stroke(Color.body, style: StrokeStyle(lineWidth: 2))
Circle()
.trim(from: 0, to: fractionCompleted)
.stroke(Color.accent, style: StrokeStyle(lineWidth: 4, lineCap: .round))
.rotationEffect(.degrees(90))
}
}
}
// Create an extension to support new containerBackground API on
// iOS 17 while still supporting iOS 16 and less (https://nemecek.be/blog/192/hotfixing-widgets-for-ios-17-containerbackground-padding)
extension View {
func widgetBackground(_ backgroundView: some View) -> some View {
if #available(iOSApplicationExtension 17.0, iOS 17.0, macOSApplicationExtension 14.0, *) {
return containerBackground(for: .widget) {
backgroundView
}
} else {
return background(backgroundView)
}
}
}

View File

@ -1,59 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>INEnums</key>
<array/>
<key>INIntentDefinitionModelVersion</key>
<string>1.2</string>
<key>INIntentDefinitionNamespace</key>
<string>88xZPY</string>
<key>INIntentDefinitionSystemVersion</key>
<string>20A294</string>
<key>INIntentDefinitionToolsBuildVersion</key>
<string>12A6144</string>
<key>INIntentDefinitionToolsVersion</key>
<string>12.0</string>
<key>INIntents</key>
<array>
<dict>
<key>INIntentCategory</key>
<string>information</string>
<key>INIntentDescriptionID</key>
<string>tVvJ9c</string>
<key>INIntentEligibleForWidgets</key>
<true/>
<key>INIntentIneligibleForSuggestions</key>
<true/>
<key>INIntentName</key>
<string>Configuration</string>
<key>INIntentResponse</key>
<dict>
<key>INIntentResponseCodes</key>
<array>
<dict>
<key>INIntentResponseCodeName</key>
<string>success</string>
<key>INIntentResponseCodeSuccess</key>
<true/>
</dict>
<dict>
<key>INIntentResponseCodeName</key>
<string>failure</string>
</dict>
</array>
</dict>
<key>INIntentTitle</key>
<string>Configuration</string>
<key>INIntentTitleID</key>
<string>gpCwrM</string>
<key>INIntentType</key>
<string>Custom</string>
<key>INIntentVerb</key>
<string>View</string>
</dict>
</array>
<key>INTypes</key>
<array/>
</dict>
</plist>

View File

@ -1,72 +0,0 @@
import WidgetKit
import SwiftUI
import Intents
/// Every home-widget requires a TimelineEntry. This is passed into the view and propvides any data it needs
struct WonderousTimelineEntry : TimelineEntry {
// Date is a mandatory field for all TimelineEntries
let date: Date
// Custom field for the wonderous view
let discoveredCount:Int;
var title:String = "";
var subTitle:String = "";
var imageData:String = "";
}
/// Widget, defines some high level configuration options as well as the primary view that will display the widget.
struct WonderousWidget: Widget {
let kind: String = "WonderousWidget"
var body: some WidgetConfiguration {
StaticConfiguration(kind: kind, provider: WonderousTimelineProvider()) { entry in
WonderousWidgetView(entry: entry)
}
.contentMarginsDisabled()
.configurationDisplayName("Wonderous Widget")
.description("Track your collected artifacts!")
.supportedFamilies([.systemSmall, .systemMedium, .systemLarge])
}
}
struct WonderousConfig {
let iosKey = "group.com.gskinner.flutter.wonders.widget"
let discoveredCountKey = "dicoveredCount"
}
/// TimelineProvider, returns various WonderousTimelineEntry configurations for different contexts
struct WonderousTimelineProvider: TimelineProvider {
// Provide an entry for a placeholder version of the widget
func placeholder(in context: Context) -> WonderousTimelineEntry {
WonderousTimelineEntry(date: Date(), discoveredCount: 0)
}
// Provide an entry for the current time and state of the widget
func getSnapshot(in context: Context, completion: @escaping (WonderousTimelineEntry) -> ()) {
let entry:WonderousTimelineEntry
let userDefaults = UserDefaults(suiteName: "group.com.gskinner.flutter.wonders.widget")
let discoveredCount = userDefaults?.integer(forKey: "discoveredCount") ?? 0
let title = userDefaults?.string(forKey: "lastDiscoveredTitle") ?? ""
let subTitle = userDefaults?.string(forKey: "lastDiscoveredSubTitle") ?? ""
let imageData = userDefaults?.string(forKey: "lastDiscoveredImageData") ?? ""
entry = WonderousTimelineEntry(
date: Date(),
discoveredCount:discoveredCount,
title: title,
subTitle: subTitle.prefix(1).capitalized + subTitle.dropFirst(),
imageData: imageData
)
completion(entry);
}
// Provide an array of entries for the current time and, optionally, any future times
func getTimeline(in context: Context, completion: @escaping (Timeline<WonderousTimelineEntry>) -> ()) {
getSnapshot(in: context) { (entry) in
let timeline = Timeline(entries: [entry], policy: .atEnd)
completion(timeline)
}
}
}

View File

@ -1,12 +0,0 @@
import WidgetKit
import SwiftUI
// WonderousWidgetBundle
// -> WonderousWidgetView
// -> WonderousWidgetViewComponents
@main
struct WonderousWidgetBundle: WidgetBundle {
var body: some Widget {
WonderousWidget()
}
}

View File

@ -1,76 +0,0 @@
import WidgetKit
import SwiftUI
import Intents
/// Defines the view / layout of the widget
struct WonderousWidgetView : View {
@Environment(\.widgetFamily) var family: WidgetFamily
var entry: WonderousTimelineProvider.Entry
var body: some View {
let showTitle = family == .systemLarge
let showIcon = family != .systemSmall
let showTitleAndDesc = family != .systemSmall
let progressPct = Double(entry.discoveredCount) / 24.0
let iconImage = FlutterImages.icon;
let title = entry.title.isEmpty ? "Wonderous" : entry.title;
let subTitle = entry.subTitle.isEmpty ? "Search for hidden artifacts" : entry.subTitle;
let content = VStack{
// Top row with optional Title and Icon
HStack {
if(showTitle) {
Text("Collection")
.font(.system(size: 15))
.foregroundColor(.offWhite)
}
Spacer();
if(showIcon) {
Image(uiImage: UIImage(contentsOfFile: iconImage)!)
.resizable()
.scaledToFit()
.frame(height: 24)
}
}
Spacer();
// Bottom hz row with title, desc and progress gauge
HStack {
if(showTitleAndDesc) {
VStack(alignment: .leading){
Text(title)
.font(.system(size: 22))
.foregroundColor(.white);
Text(subTitle)
.font(.system(size: 15))
.foregroundColor(.mediumGrey);
}
}
Spacer();
ZStack{
ProgressView(value: progressPct)
.progressViewStyle(GaugeProgressStyle())
.frame(width: 48, height: 48)
Text("\(Int((progressPct * 100).rounded()))%").font(.system(size: 13)).foregroundColor(.white)
}
}
}
// Stack content on top of the background image and a gradient
return ZStack{
BgImage(entry: entry).opacity(0.8)
LinearGradient(
gradient: Gradient(colors: [.black.opacity(0), .black]),
startPoint: .center,
endPoint: .bottom)
content.padding(16)
}
// Ios requires that widgets have a background color
.widgetBackground(Color.darkGrey)
// Deeplink into collections view when tapped
.widgetURL(URL(string: "wonderous:///home/collection"))
}
}

View File

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.application-groups</key>
<array>
<string>group.com.gskinner.flutter.wonders.widget</string>
</array>
</dict>
</plist>

View File

@ -1,174 +0,0 @@
import 'dart:convert';
import 'dart:io';
import 'package:http/http.dart';
import 'package:image/image.dart';
import 'package:path_provider/path_provider.dart';
import 'package:wonders/logic/data/collectible_data.dart';
import 'package:wonders/logic/data/highlight_data.dart';
import 'package:wonders/logic/data/wonders_data/chichen_itza_data.dart';
import 'package:wonders/logic/data/wonders_data/christ_redeemer_data.dart';
import 'package:wonders/logic/data/wonders_data/great_wall_data.dart';
import 'package:wonders/logic/data/wonders_data/machu_picchu_data.dart';
import 'package:wonders/logic/data/wonders_data/petra_data.dart';
import 'package:wonders/logic/data/wonders_data/pyramids_giza_data.dart';
import 'package:wonders/logic/data/wonders_data/taj_mahal_data.dart';
import 'package:wonders/logic/data/wonders_data/colosseum_data.dart';
import 'package:wonders/common_libs.dart';
class ArtifactDownloadHelper extends StatefulWidget {
const ArtifactDownloadHelper({super.key});
@override
State<ArtifactDownloadHelper> createState() => _ArtifactDownloadHelperState();
}
/// Using collectiblesData fetch the data for each artifact and download the image.
/// Resize all images to have multiple sizes (small, medium, large)
/// Save images using format [ID].jpg and [ID].json
/// OR modify CollectibleData_helper.html to include all data in the collectiblesData list so no JSON is required.
class _ArtifactDownloadHelperState extends State<ArtifactDownloadHelper> {
late String imagesDir;
final http = Client();
final List<String> missingIds = [];
@override
void initState() {
super.initState();
createDirectory();
}
Future<void> createDirectory() async {
final rootDir = await getApplicationDocumentsDirectory();
imagesDir = '${rootDir.path}/met_collectibles';
await Directory(imagesDir).create(recursive: true);
}
@override
Widget build(BuildContext context) {
return Center(
child: TextButton(
onPressed: downloadArtifacts,
child: Text('Download Artifacts'),
),
);
}
void downloadArtifacts() async {
missingIds.clear();
/// Download collectibles
for (var c in collectiblesData) {
if (await downloadImageAndJson(c.artifactId) == false) {
missingIds.add(c.artifactId);
}
}
/// Download Highights
for (var h in HighlightData.all) {
if (await downloadImageAndJson(h.artifactId) == false) {
missingIds.add(h.artifactId);
}
}
/// Download search artifacts
final searchData = ChichenItzaData().searchData +
ChristRedeemerData().searchData +
ColosseumData().searchData +
GreatWallData().searchData +
MachuPicchuData().searchData +
PetraData().searchData +
PyramidsGizaData().searchData +
TajMahalData().searchData;
for (var a in searchData) {
final id = a.id.toString();
if (await downloadImageAndJson(id) == false) {
missingIds.add(id);
}
final index = searchData.indexOf(a) + 1;
if (index % 100 == 0) {
debugPrint('$index/${searchData.length}');
}
}
debugPrint('Download complete :) Missing IDs: $missingIds');
}
Future<bool> downloadImageAndJson(String id) async {
File jsonFile = File('$imagesDir/$id.json');
late Map json;
if (jsonFile.existsSync()) {
json = jsonDecode(jsonFile.readAsStringSync()) as Map;
} else {
debugPrint('Downloading $id');
// Fetch JSON for id
Uri uri = Uri.parse('https://collectionapi.metmuseum.org/public/collection/v1/objects/$id');
final response = await http.get(uri);
json = jsonDecode(response.body) as Map;
}
// Check if primaryImage field is valid
if (!json.containsKey('primaryImage') || json['primaryImage'].isEmpty) {
return false;
}
// Download image
final url = json['primaryImage'] as String;
//bool isPublicDomain = json['isPublicDomain'] as bool;
File imgFile = File('$imagesDir/$id.jpg');
// If image does not already exist, download it
if (!imgFile.existsSync()) {
await downloadImage(id, url);
if (!imgFile.existsSync()) return false;
}
// Try to resize image
if (await resizeImage(id, [600, 2000]) == false) {
debugPrint('Failed to resize $id');
imgFile.deleteSync();
return false;
}
// Write JSON to file
if (!jsonFile.existsSync()) {
jsonFile.writeAsStringSync(jsonEncode(json));
debugPrint('json saved @ ${jsonFile.path}');
}
return true;
}
Future<bool> downloadImage(String id, String url) async {
//final sizes = [400, 800, 1600, 3000];
debugPrint('Downloading $url to $imagesDir');
final imgResponse = await get(Uri.parse(url));
// If the image is less than a KB, it's probably a 404 image.
if (imgResponse.bodyBytes.lengthInBytes < 2000) {
return false;
}
File file = File('$imagesDir/$id.jpg');
file.writeAsBytesSync(imgResponse.bodyBytes);
debugPrint('img saved @ ${file.path}');
return true;
}
Future<bool> resizeImage(String id, List<int> sizes) async {
final srcFile = File('$imagesDir/$id.jpg');
//debugPrint('Resizing $id...');
try {
final img = decodeJpg(srcFile.readAsBytesSync());
if (img != null) {
// Write various sizes to disk
for (var size in sizes) {
final resizedFile = File('$imagesDir/${id}_$size.jpg');
if (await resizedFile.exists()) continue;
final resizedImg = copyResize(img, width: size);
await resizedFile.writeAsBytes(encodeJpg(resizedImg, quality: 90));
debugPrint('Resized ${id}_$size');
}
return true;
}
} catch (e) {
debugPrint('Failed to resize $id');
debugPrint(e.toString());
}
return false;
}
}

View File

@ -16,7 +16,7 @@ final int maxYear = wondersLogic.timelineEndYear;
const int maxRequests = 32;
class ArtifactSearchHelper extends StatefulWidget {
const ArtifactSearchHelper({super.key});
const ArtifactSearchHelper({Key? key}) : super(key: key);
@override
State<ArtifactSearchHelper> createState() => _ArtifactSearchHelperState();
@ -161,19 +161,15 @@ class _ArtifactSearchHelperState extends State<ArtifactSearchHelper> {
//if (!json.containsKey('isPublicDomain') || !json['isPublicDomain']) return _logError(id, 'not public domain')
final int year = ((json['objectBeginDate'] as int) + (json['objectEndDate'] as int)) ~/ 2;
if (year < minYear || year > maxYear) {
return _logError(id, 'year is out of range');
}
if (year < minYear || year > maxYear) return _logError(id, 'year is out of range');
String? imageUrlSmall = json['primaryImageSmall'];
if (imageUrlSmall == null || imageUrlSmall.isEmpty) {
return _logError(id, 'no small image url');
if (imageUrlSmall == null) return _logError(id, 'no small image url');
if (!imageUrlSmall.startsWith(SearchData.baseImagePath)) {
return _logError(id, 'unexpected image uri: "$imageUrlSmall"');
}
// if (!imageUrlSmall.startsWith(SearchData.baseImagePath)) {
// return _logError(id, 'unexpected image uri: "$imageUrlSmall"');
// }
// String imageUrl = imageUrlSmall.substring(SearchData.baseImagePath.length);
// imageUrl = imageUrl.replaceFirst('/web-large/', '/mobile-large/');
String imagePath = imageUrlSmall.substring(SearchData.baseImagePath.length);
imagePath = imagePath.replaceFirst('/web-large/', '/mobile-large/');
double? aspectRatio = 0;
if (checkImages) aspectRatio = await _getAspectRatio(imageUrlSmall);
@ -184,6 +180,7 @@ class _ArtifactSearchHelperState extends State<ArtifactSearchHelper> {
id,
_escape(json['title']),
_getKeywords(json),
imagePath,
aspectRatio,
);
@ -232,22 +229,12 @@ class _ArtifactSearchHelperState extends State<ArtifactSearchHelper> {
String suggestions = _getSuggestions(entries);
const fileNames = {
WonderType.chichenItza: 'chichen_itza',
WonderType.christRedeemer: 'christ_redeemer',
WonderType.colosseum: 'colosseum',
WonderType.greatWall: 'great_wall',
WonderType.machuPicchu: 'machu_picchu',
WonderType.petra: 'petra',
WonderType.pyramidsGiza: 'pyramids_giza',
WonderType.tajMahal: 'taj_mahal',
};
Directory dir = await getApplicationDocumentsDirectory();
String name = '${fileNames[wonder!.type]}_search_data.dart';
String path = '${dir.path}/$name';
String type = wonder!.type.toString().split('.').last;
String path = '${dir.path}/$type.dart';
File file = File(path);
await file.writeAsString('$suggestions\n\n$output');
_log('- Wrote file: $name');
_log('- Wrote file: $type.dart');
debugPrint(path);
_nextWonder();
}

View File

@ -26,9 +26,9 @@ class ImagePaths {
static String textures = '$common/texture';
static String icons = '$common/icons';
static String roller1 = '$textures/roller-1-white.gif';
static String roller2 = '$textures/roller-2-white.gif';
static String speckles = '$textures/speckles-white.png';
static String roller1 = '$textures/roller-1-white.png';
static String roller2 = '$textures/roller-2-white.png';
static String appLogo = '$common/app-logo.png';
static String appLogoPlain = '$common/app-logo-plain.png';
@ -43,16 +43,24 @@ class SvgPaths {
/// For wonder specific assets, add an extension to [WonderType] for easy lookup
extension WonderAssetExtensions on WonderType {
String get assetPath {
return switch (this) {
WonderType.pyramidsGiza => '${ImagePaths.root}/pyramids',
WonderType.greatWall => '${ImagePaths.root}/great_wall_of_china',
WonderType.petra => '${ImagePaths.root}/petra',
WonderType.colosseum => '${ImagePaths.root}/colosseum',
WonderType.chichenItza => '${ImagePaths.root}/chichen_itza',
WonderType.machuPicchu => '${ImagePaths.root}/machu_picchu',
WonderType.tajMahal => '${ImagePaths.root}/taj_mahal',
WonderType.christRedeemer => '${ImagePaths.root}/christ_the_redeemer'
};
switch (this) {
case WonderType.pyramidsGiza:
return '${ImagePaths.root}/pyramids';
case WonderType.greatWall:
return '${ImagePaths.root}/great_wall_of_china';
case WonderType.petra:
return '${ImagePaths.root}/petra';
case WonderType.colosseum:
return '${ImagePaths.root}/colosseum';
case WonderType.chichenItza:
return '${ImagePaths.root}/chichen_itza';
case WonderType.machuPicchu:
return '${ImagePaths.root}/machu_picchu';
case WonderType.tajMahal:
return '${ImagePaths.root}/taj_mahal';
case WonderType.christRedeemer:
return '${ImagePaths.root}/christ_the_redeemer';
}
}
String get homeBtn => '$assetPath/wonder-button.png';

View File

@ -1,5 +1,4 @@
/// Consolidate imports that are common across the app.
library;
export 'dart:math';
@ -15,6 +14,7 @@ export 'package:get_it_mixin/get_it_mixin.dart';
export 'package:go_router/go_router.dart';
export 'package:provider/provider.dart';
export 'package:rnd/rnd.dart';
export 'package:simple_rich_text/simple_rich_text.dart';
export 'package:sized_context/sized_context.dart';
export 'package:wonders/assets.dart';
export 'package:wonders/logic/app_logic.dart';

View File

@ -145,7 +145,7 @@
"chichenItzaCallout2": "The city comprised an area of at least 1.9 sq miles (5 sq km) of densely clustered architecture.",
"chichenItzaVideoCaption": "“Ancient Maya 101 | National Geographic.” Youtube, uploaded by National Geographic.",
"chichenItzaMapCaption": "Map showing location of Chichen Itza in Yucatán State, Mexico.",
"chichenItzaHistoryInfo1": "Chichen Itza was a powerful regional capital controlling north and central Yucatán. The earliest hieroglyphic date discovered at Chichen Itza is equivalent to 832 CE, while the last known date was recorded in the Osario temple in 998 CE.\nDominating the North Platform of Chichen Itza is the famous Temple of Kukulcán. The temple was identified by the first Spaniards to see it, as El Castillo (\"the castle\"), and it regularly is referred to as such.",
"chichenItzaHistoryInfo1": "Chichen Itza was a powerful regional capital controlling north and central Yucatán. The earliest hieroglyphic date discovered at Chichen Itza is equivalent to 832 CE, while the last known date was recorded in the Osario temple in 998 CE.\nDominating the North Platform of Chichen Itza is the famous Temple of Kukulcán. The temple was identified by the first Spaniards to see it, as El Castillo (\"the castle\"), and it regularly is referred to as such. The temple was identified by the first Spaniards to see it, as El Castillo (\"the castle\"), and it regularly is referred to as such.",
"chichenItzaHistoryInfo2": "The city was thought to have the most diverse population in the Maya world, a factor that could have contributed to this architectural variety.",
"chichenItzaConstructionInfo1": "The structures of Chichen Itza were built from precisely chiseled limestone blocks that fit together perfectly without the mortar. Many of these stone buildings were originally painted in red, green, blue and purple colors depending on the availability of the pigments.\nThe stepped pyramid El Castillo stands about 98 feet (30 m) high and consists of a series of nine square terraces, each approximately 8.4 feet (2.57 m) high, with a 20 foot (6 m) high temple upon the summit.",
"chichenItzaConstructionInfo2": "It was built upon broken terrain, which was artificially leveled to support structures such as the Castillo pyramid. Important buildings within the center were connected by a dense network of paved roads called sacbeob.",
@ -427,7 +427,5 @@
"timelineEvent1969ce": "Apollo 11 mission lands on the moon",
"privacyPolicy": "Privacy Policy",
"privacyStatement": "As explained in our {privacyUrl} we do not collect any personal information.",
"@privacyStatement": {"placeholders": {"privacyUrl": {}}},
"pageNotFoundBackButton": "Back to civilization",
"pageNotFoundMessage": "The page you are looking for does not exist."
"@privacyStatement": {"placeholders": {"privacyUrl": {}}}
}

View File

@ -405,7 +405,5 @@
"timelineEvent1957ce": "苏联发射斯普特尼克1号",
"timelineEvent1969ce": "阿波罗11号在月球着陆",
"privacyPolicy": "隐私政策",
"privacyStatement": "gskinner 非常重视对用户隐私的保护,正如{privacyUrl}里所诉gskinner 不会收集您的个人信息。",
"pageNotFoundBackButton": "回到文明",
"pageNotFoundMessage": "您正在寻找的页面不存在"
"privacyStatement": "gskinner 非常重视对用户隐私的保护,正如{privacyUrl}里所诉gskinner 不会收集您的个人信息。"
}

View File

@ -1,54 +1,45 @@
import 'dart:async';
import 'dart:ui';
import 'package:flutter/foundation.dart';
import 'package:desktop_window/desktop_window.dart';
import 'package:flutter_displaymode/flutter_displaymode.dart';
import 'package:wonders/common_libs.dart';
import 'package:wonders/logic/common/platform_info.dart';
import 'package:wonders/ui/common/modals/fullscreen_video_viewer.dart';
import 'package:wonders/ui/common/utils/page_routes.dart';
class AppLogic {
Size _appSize = Size.zero;
/// Indicates to the rest of the app that bootstrap has not completed.
/// The router will use this to prevent redirects while bootstrapping.
bool isBootstrapComplete = false;
/// Indicates which orientations the app will allow be default. Affects Android/iOS devices only.
/// Defaults to both landscape (hz) and portrait (vt)
List<Axis> supportedOrientations = [Axis.vertical, Axis.horizontal];
bool get isLandscapeEnabled => PlatformInfo.isDesktopOrWeb || deviceSize.shortestSide > 500;
/// Allow a view to override the currently supported orientations. For example, [FullscreenVideoViewer] always wants to enable both landscape and portrait.
/// If a view sets this override, they are responsible for setting it back to null when finished.
List<Axis>? _supportedOrientationsOverride;
set supportedOrientationsOverride(List<Axis>? value) {
if (_supportedOrientationsOverride != value) {
_supportedOrientationsOverride = value;
_updateSystemOrientation();
}
/// Support portrait and landscape on desktop, web and tablets. Stick to portrait for phones.
/// A return value of null indicated both orientations are supported.
Axis? get supportedOrientations => isLandscapeEnabled ? null : Axis.vertical;
Size get deviceSize {
final w = WidgetsBinding.instance.platformDispatcher.views.first;
return w.physicalSize / w.devicePixelRatio;
}
/// Initialize the app and all main actors.
/// Loads settings, sets up services etc.
Future<void> bootstrap() async {
debugPrint('bootstrap start...');
debugPrint('bootstrap app, deviceSize: $deviceSize, isTablet: $isLandscapeEnabled');
if (kIsWeb) {
// SB: This is intentionally not a debugPrint, as it's a message for users who open the console on web.
print(
'''Thanks for checking out Wonderous on the web!
If you encounter any issues please report them at https://github.com/gskinnerTeam/flutter-wonderous-app/issues.''',
);
// Required on web to automatically enable accessibility features
WidgetsFlutterBinding.ensureInitialized().ensureSemantics();
// Set min-sizes for desktop apps
if (PlatformInfo.isDesktop) {
await DesktopWindow.setMinWindowSize($styles.sizes.minAppSize);
}
// Load any bitmaps the views might need
await AppBitmaps.init();
// Set the initial supported orientations
setDeviceOrientation(supportedOrientations);
// Set preferred refresh rate to the max possible (the OS may ignore this)
if (!kIsWeb && PlatformInfo.isAndroid) {
if (PlatformInfo.isAndroid) {
await FlutterDisplayMode.setHighRefreshRate();
}
@ -65,7 +56,6 @@ class AppLogic {
timelineLogic.init();
// Collectibles
collectiblesLogic.init();
await collectiblesLogic.load();
// Flag bootStrap as complete
@ -76,40 +66,19 @@ class AppLogic {
if (showIntro) {
appRouter.go(ScreenPaths.intro);
} else {
appRouter.go(initialDeeplink ?? ScreenPaths.home);
appRouter.go(ScreenPaths.home);
}
}
Future<T?> showFullscreenDialogRoute<T>(BuildContext context, Widget child, {bool transparent = false}) async {
return await Navigator.of(context).push<T>(
PageRoutes.dialog<T>(child, duration: $styles.times.pageTransition),
);
}
/// Called from the UI layer once a MediaQuery has been obtained
void handleAppSizeChanged(Size appSize) {
/// Disable landscape layout on smaller form factors
bool isSmall = display.size.shortestSide / display.devicePixelRatio < 600;
supportedOrientations = isSmall ? [Axis.vertical] : [Axis.vertical, Axis.horizontal];
_updateSystemOrientation();
_appSize = appSize;
}
Display get display => PlatformDispatcher.instance.displays.first;
bool shouldUseNavRail() => _appSize.width > _appSize.height && _appSize.height > 250;
void _updateSystemOrientation() {
final axisList = _supportedOrientationsOverride ?? supportedOrientations;
//debugPrint('updateDeviceOrientation, supportedAxis: $axisList');
void setDeviceOrientation(Axis? axis) {
final orientations = <DeviceOrientation>[];
if (axisList.contains(Axis.vertical)) {
if (axis == null || axis == Axis.vertical) {
orientations.addAll([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]);
}
if (axisList.contains(Axis.horizontal)) {
if (axis == null || axis == Axis.horizontal) {
orientations.addAll([
DeviceOrientation.landscapeLeft,
DeviceOrientation.landscapeRight,
@ -117,12 +86,10 @@ class AppLogic {
}
SystemChrome.setPreferredOrientations(orientations);
}
}
class AppImageCache extends WidgetsFlutterBinding {
@override
ImageCache createImageCache() {
this.imageCache.maximumSizeBytes = 250 << 20; // 250mb
return super.createImageCache();
Future<T?> showFullscreenDialogRoute<T>(BuildContext context, Widget child, {bool transparent = false}) async {
return await Navigator.of(context).push<T>(
PageRoutes.dialog<T>(child, duration: $styles.times.pageTransition),
);
}
}

View File

@ -1,10 +1,6 @@
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:wonders/common_libs.dart';
import 'package:wonders/logic/common/save_load_mixin.dart';
import 'package:wonders/logic/data/collectible_data.dart';
import 'package:wonders/logic/native_widget_service.dart';
class CollectiblesLogic with ThrottledSaveLoadMixin {
@override
@ -17,17 +13,11 @@ class CollectiblesLogic with ThrottledSaveLoadMixin {
late final statesById = ValueNotifier<Map<String, int>>({})..addListener(_updateCounts);
int _discoveredCount = 0;
int get discoveredCount => _discoveredCount;
int _exploredCount = 0;
int get exploredCount => _exploredCount;
late final _nativeWidget = GetIt.I<NativeWidgetService>();
void init() => _nativeWidget.init();
CollectibleData? fromId(String? id) => id == null ? null : all.firstWhereOrNull((o) => o.id == id);
List<CollectibleData> forWonder(WonderType wonder) {
@ -38,14 +28,6 @@ class CollectiblesLogic with ThrottledSaveLoadMixin {
Map<String, int> states = Map.of(statesById.value);
states[id] = state;
statesById.value = states;
if (state == CollectibleState.discovered) {
final data = fromId(id)!;
_updateNativeHomeWidgetData(
title: data.title,
id: data.id,
imageUrl: data.imageUrlSmall,
);
}
scheduleSave();
}
@ -55,12 +37,6 @@ class CollectiblesLogic with ThrottledSaveLoadMixin {
if (state == CollectibleState.discovered) _discoveredCount++;
if (state == CollectibleState.explored) _exploredCount++;
});
final foundCount = discoveredCount + exploredCount;
_nativeWidget.save<int>('discoveredCount', foundCount).then((value) {
_nativeWidget.markDirty();
});
debugPrint('setting discoveredCount for home widget $foundCount');
}
/// Get a discovered item, sorted by the order of wondersLogic.all
@ -91,35 +67,11 @@ class CollectiblesLogic with ThrottledSaveLoadMixin {
for (int i = 0; i < all.length; i++) {
states[all[i].id] = CollectibleState.lost;
}
_updateNativeHomeWidgetData(); // clear home widget data
statesById.value = states;
debugPrint('collection reset');
scheduleSave();
}
Future<void> _updateNativeHomeWidgetData({String title = '', String id = '', String imageUrl = ''}) async {
if (!_nativeWidget.isSupported) return;
// Save title
await _nativeWidget.save<String>('lastDiscoveredTitle', title);
// Subtitle
String subTitle = '';
if (id.isNotEmpty) {
final artifactData = await artifactLogic.getArtifactByID(id);
subTitle = artifactData?.date ?? '';
}
await _nativeWidget.save<String>('lastDiscoveredSubTitle', subTitle);
// Image,
// Download, convert to base64 string and write to shared widget data
String imageBase64 = '';
if (imageUrl.isNotEmpty) {
var bytes = await http.readBytes(Uri.parse(imageUrl));
imageBase64 = base64Encode(bytes);
debugPrint('Saving base64 bytes for homeWidget');
}
await _nativeWidget.save<String>('lastDiscoveredImageData', imageBase64);
await _nativeWidget.markDirty();
}
@override
void copyFromJson(Map<String, dynamic> value) {
Map<String, int> states = {};

View File

@ -94,7 +94,7 @@ class ServiceResult<R> {
ServiceResult(this.response, R Function(Map<String, dynamic>) parser) {
if (StringUtils.isNotEmpty(response.body) && response.success) {
try {
content = parser.call(jsonDecode(utf8.decode(response.raw!.bodyBytes)));
content = parser.call(jsonDecode(response.body!));
} on FormatException catch (e) {
dev.log('ParseError: ${e.message}');
}

View File

@ -12,7 +12,7 @@ class PlatformInfo {
static bool get isDesktopOrWeb => isDesktop || kIsWeb;
static bool get isMobile => _mobilePlatforms.contains(defaultTargetPlatform) && !kIsWeb;
static double get pixelRatio => WidgetsBinding.instance.platformDispatcher.views.first.devicePixelRatio;
static double get pixelRatio => WidgetsBinding.instance.window.devicePixelRatio;
static bool get isWindows => defaultTargetPlatform == TargetPlatform.windows;
static bool get isLinux => defaultTargetPlatform == TargetPlatform.linux;

View File

@ -49,10 +49,9 @@ class RetryImage extends ImageProvider<Object> {
return completer.future;
}
@override
ImageStreamCompleter loadImage(Object key, ImageDecoderCallback decode) {
ImageStreamCompleter _commonLoad(ImageStreamCompleter Function() loader) {
final _DelegatingImageStreamCompleter completer = _DelegatingImageStreamCompleter();
ImageStreamCompleter completerToWrap = imageProvider.loadImage(key, decode);
ImageStreamCompleter completerToWrap = loader();
late ImageStreamListener listener;
Duration duration = const Duration(milliseconds: 250);
@ -70,7 +69,7 @@ class RetryImage extends ImageProvider<Object> {
}
Future<void>.delayed(duration).then((void v) {
duration *= 2;
completerToWrap = imageProvider.loadImage(key, decode);
completerToWrap = loader();
count += 1;
completerToWrap.addListener(listener);
});
@ -85,12 +84,24 @@ class RetryImage extends ImageProvider<Object> {
return completer;
}
@override
// ignore: deprecated_member_use
ImageStreamCompleter load(Object key, DecoderCallback decode) {
// ignore: deprecated_member_use
return _commonLoad(() => imageProvider.load(key, decode));
}
@override
ImageStreamCompleter loadBuffer(Object key, DecoderBufferCallback decode) {
return _commonLoad(() => imageProvider.loadBuffer(key, decode));
}
@override
bool operator ==(Object other) {
if (other.runtimeType != runtimeType) {
return false;
}
return other is RetryImage && other.imageProvider == imageProvider && other.scale == scale;
return other is RetryImage && other.imageProvider == other.imageProvider && other.scale == scale;
}
@override

View File

@ -16,7 +16,7 @@ mixin ThrottledSaveLoadMixin {
}
Future<void> save() async {
if (!kIsWeb) debugPrint('Saving...');
debugPrint('Saving...');
try {
await _file.save(toJson());
} on Exception catch (e) {

View File

@ -25,7 +25,6 @@ class Throttler {
void _callAction() {
_action?.call(); // If we have an action queued up, complete it.
_action = null; // Once an action is called, do not call the same action again unless another action is queued.
_timer = null;
}

Some files were not shown because too many files have changed in this diff Show More