Compare commits
No commits in common. "main" and "master" have entirely different histories.
1
.gitignore
vendored
@ -33,6 +33,7 @@ desktop.ini
|
||||
/build/
|
||||
|
||||
# Web related
|
||||
lib/generated_plugin_registrant.dart
|
||||
|
||||
# Symbolication related
|
||||
app.*.symbols
|
||||
|
29
.metadata
@ -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
|
||||
|
||||
|
25
README.md
@ -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!
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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"
|
||||
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 16 KiB |
BIN
android/app/src/main/res/drawable-hdpi/branding.png
Normal file
After Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 8.1 KiB After Width: | Height: | Size: 8.1 KiB |
BIN
android/app/src/main/res/drawable-mdpi/branding.png
Normal file
After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 8.1 KiB |
Before Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 46 KiB |
Before Width: | Height: | Size: 56 KiB |
Before Width: | Height: | Size: 69 B After Width: | Height: | Size: 70 B |
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
BIN
android/app/src/main/res/drawable-xhdpi/branding.png
Normal file
After Width: | Height: | Size: 38 KiB |
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 42 KiB |
BIN
android/app/src/main/res/drawable-xxhdpi/branding.png
Normal file
After Width: | Height: | Size: 67 KiB |
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 42 KiB |
Before Width: | Height: | Size: 123 KiB After Width: | Height: | Size: 123 KiB |
Before Width: | Height: | Size: 69 B After Width: | Height: | Size: 70 B |
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 4.1 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 6.1 KiB |
Before Width: | Height: | Size: 9.3 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 15 KiB |
@ -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>
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
}
|
||||
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 170 KiB |
Before Width: | Height: | Size: 285 KiB |
Before Width: | Height: | Size: 565 KiB |
Before Width: | Height: | Size: 954 KiB |
BIN
assets/images/_common/texture/roller-1-black.png
Normal file
After Width: | Height: | Size: 795 KiB |
Before Width: | Height: | Size: 42 KiB |
BIN
assets/images/_common/texture/roller-1-white.png
Normal file
After Width: | Height: | Size: 795 KiB |
BIN
assets/images/_common/texture/roller-2-black.png
Normal file
After Width: | Height: | Size: 1.3 MiB |
Before Width: | Height: | Size: 71 KiB |
BIN
assets/images/_common/texture/roller-2-white.png
Normal file
After Width: | Height: | Size: 1.3 MiB |
Before Width: | Height: | Size: 91 KiB After Width: | Height: | Size: 46 KiB |
Before Width: | Height: | Size: 168 KiB After Width: | Height: | Size: 82 KiB |
Before Width: | Height: | Size: 262 KiB After Width: | Height: | Size: 127 KiB |
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 217 KiB |
Before Width: | Height: | Size: 1.7 KiB |
@ -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
|
||||
|
@ -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 = (
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1430"
|
||||
LastUpgradeVersion = "1300"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 452 KiB After Width: | Height: | Size: 500 KiB |
Before Width: | Height: | Size: 632 B After Width: | Height: | Size: 700 B |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 973 B After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.5 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 4.1 KiB |
Before Width: | Height: | Size: 6.5 KiB After Width: | Height: | Size: 7.4 KiB |
Before Width: | Height: | Size: 6.5 KiB After Width: | Height: | Size: 7.4 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.9 KiB |
Before Width: | Height: | Size: 8.7 KiB After Width: | Height: | Size: 9.9 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 69 B After Width: | Height: | Size: 70 B |
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 42 KiB |
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -1,13 +0,0 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"platform" : "ios",
|
||||
"size" : "1024x1024"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
{
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
{
|
||||
"colors" : [
|
||||
{
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
@ -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
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
//
|
||||
// FlutterUtils.swift
|
||||
// Wonderous WidgetExtension
|
||||
//
|
||||
// Created by Shawn on 2023-10-19.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
|
||||
|
@ -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>
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
@ -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>
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,12 +0,0 @@
|
||||
import WidgetKit
|
||||
import SwiftUI
|
||||
|
||||
// WonderousWidgetBundle
|
||||
// -> WonderousWidgetView
|
||||
// -> WonderousWidgetViewComponents
|
||||
@main
|
||||
struct WonderousWidgetBundle: WidgetBundle {
|
||||
var body: some Widget {
|
||||
WonderousWidget()
|
||||
}
|
||||
}
|
@ -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"))
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -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>
|
@ -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;
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
@ -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';
|
||||
|
@ -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';
|
||||
|
@ -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": {}}}
|
||||
}
|
@ -405,7 +405,5 @@
|
||||
"timelineEvent1957ce": "苏联发射斯普特尼克1号",
|
||||
"timelineEvent1969ce": "阿波罗11号在月球着陆",
|
||||
"privacyPolicy": "隐私政策",
|
||||
"privacyStatement": "gskinner 非常重视对用户隐私的保护,正如{privacyUrl}里所诉,gskinner 不会收集您的个人信息。",
|
||||
"pageNotFoundBackButton": "回到文明",
|
||||
"pageNotFoundMessage": "您正在寻找的页面不存在"
|
||||
"privacyStatement": "gskinner 非常重视对用户隐私的保护,正如{privacyUrl}里所诉,gskinner 不会收集您的个人信息。"
|
||||
}
|
@ -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),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -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 = {};
|
||||
|
@ -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}');
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|