diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 60ae787..1e281a5 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -2,34 +2,68 @@ "version": "2.0.0", "tasks": [ { - "label": "dart:dependencies", + "label": "dart:pub:get", + "detail": "Get dependencies for the project", + "icon": { + "color": "terminal.ansiGreen", + "id": "cloud-download" + }, + "dependsOn": [], "type": "shell", - "command": [ - "dart pub get" - ], + "command": "dart pub get", + "args": [], "group": { "kind": "none", "isDefault": true }, - "problemMatcher": [] + "problemMatcher": [], + "options": { + "cwd": "${workspaceFolder}" + }, + "isBackground": false, + "presentation": { + "reveal": "silent", + "focus": false, + "panel": "shared", + "showReuseMessage": false, + "clear": false, + } }, { "label": "dart:get-protoc-plugin", "detail": "Get protoc plugin", + "icon": { + "color": "terminal.ansiGreen", + "id": "cloud-download" + }, "type": "shell", - "command": [ - "dart pub global activate protoc_plugin" - ], + "command": "dart pub global activate protoc_plugin", "dependsOn": [], + "args": [], "group": { "kind": "none", "isDefault": true }, - "problemMatcher": [] + "problemMatcher": [], + "options": { + "cwd": "${workspaceFolder}" + }, + "isBackground": false, + "presentation": { + "reveal": "silent", + "focus": false, + "panel": "shared", + "showReuseMessage": false, + "clear": false, + } }, { "label": "dart:generate-protobuf", "detail": "Generate protobuf files", + "icon": { + "color": "terminal.ansiGreen", + "id": "code" + }, "type": "shell", "command": [ "protoc", @@ -39,45 +73,124 @@ "dependsOn": [ "dart:get-protoc-plugin" ], + "args": [], "group": { "kind": "none", "isDefault": true }, - "problemMatcher": [] + "problemMatcher": [], + "options": { + "cwd": "${workspaceFolder}" + }, + "isBackground": false, + "presentation": { + "reveal": "silent", + "focus": false, + "panel": "shared", + "showReuseMessage": false, + "clear": false, + } }, { - "label": "dart:codegenerate", + "label": "dart:build_runner:all", "detail": "Generate code for the project", + "icon": { + "color": "terminal.ansiGreen", + "id": "code" + }, "type": "shell", "command": [ - "dart run build_runner build --delete-conflicting-outputs" + "dart run build_runner build --delete-conflicting-outputs", + "&& dart format --fix -l 80 lib test tool example" ], "dependsOn": [ "dart:dependencies", "dart:generate-protobuf" ], + "args": [], "group": { "kind": "none", "isDefault": true }, - "problemMatcher": [] + "problemMatcher": [], + "options": { + "cwd": "${workspaceFolder}" + }, + "isBackground": false, + "presentation": { + "reveal": "silent", + "focus": false, + "panel": "shared", + "showReuseMessage": false, + "clear": false, + } + }, + { + "label": "dart:build_runner:dir", + "detail": "Generate code for the directory", + "type": "shell", + "icon": { + "color": "terminal.ansiGreen", + "id": "code" + }, + "command": [ + "dart run build_runner build --build-filter '${fileDirname}/*.dart'", + "&& dart format --fix -l 80 '${fileDirname}'" + ], + "group": { + "kind": "none", + "isDefault": true + }, + "problemMatcher": [], + "dependsOn": [ + "dart:pub:get" + ], + "isBackground": false, + "presentation": { + "reveal": "silent", + "focus": false, + "panel": "shared", + "showReuseMessage": false, + "clear": false, + } }, { "label": "dart:format", "detail": "Format all files in the project", + "icon": { + "color": "terminal.ansiGreen", + "id": "lightbulb-autofix" + }, "type": "shell", "command": [ "dart format --fix -l 80 lib test tool example" ], + "dependsOn": [], + "args": [], "group": { "kind": "none", "isDefault": true }, - "problemMatcher": [] + "problemMatcher": [], + "options": { + "cwd": "${workspaceFolder}" + }, + "isBackground": false, + "presentation": { + "reveal": "silent", + "focus": false, + "panel": "shared", + "showReuseMessage": false, + "clear": false, + } }, { "label": "centrifugo:start", "detail": "Start centrifugo server", + "icon": { + "color": "terminal.ansiBlue", + "id": "server" + }, "type": "shell", "windows": { "command": "docker", @@ -133,38 +246,63 @@ "--log_level=debug" ] }, + "dependsOn": [], + "args": [], "group": { "kind": "none", "isDefault": true }, "problemMatcher": [], + "options": { + "cwd": "${workspaceFolder}" + }, + "isBackground": false, "presentation": { - "reveal": "always", - "panel": "shared" + "reveal": "silent", + "focus": false, + "panel": "shared", + "showReuseMessage": false, + "clear": false, } }, { "label": "centrifugo:stop", "detail": "Stop centrifugo server", + "icon": { + "color": "terminal.ansiRed", + "id": "server" + }, "type": "shell", "command": "docker", "args": [ "stop", "centrifugo" ], + "dependsOn": [], "group": { "kind": "none", "isDefault": true }, "problemMatcher": [], + "options": { + "cwd": "${workspaceFolder}" + }, + "isBackground": false, "presentation": { - "reveal": "always", - "panel": "shared" + "reveal": "silent", + "focus": false, + "panel": "shared", + "showReuseMessage": false, + "clear": false, } }, { "label": "centrifugo:gentoken", "detail": "Generate new user token for centrifugo server", + "icon": { + "color": "terminal.ansiCyan", + "id": "key" + }, "type": "shell", "command": "docker", "args": [ @@ -179,21 +317,33 @@ "--user=dart", "--ttl=604800" ], + "dependsOn": [], "group": { "kind": "none", "isDefault": true }, "problemMatcher": [], + "options": { + "cwd": "${workspaceFolder}" + }, + "isBackground": false, "presentation": { - "reveal": "always", - "panel": "shared" + "reveal": "silent", + "focus": false, + "panel": "shared", + "showReuseMessage": false, + "clear": false, } }, { "label": "echo-server:start", + "detail": "Start echo server", + "icon": { + "color": "terminal.ansiBlue", + "id": "server" + }, "type": "shell", "command": "dart", - "detail": "Start echo server", "isBackground": false, "options": { "cwd": "${workspaceFolder}/tool", @@ -209,18 +359,26 @@ }, "problemMatcher": [], "presentation": { - "reveal": "never", - "panel": "shared" + "reveal": "silent", + "focus": false, + "panel": "shared", + "showReuseMessage": false, + "clear": false, } }, { "label": "echo-server:stop", + "detail": "Stop echo server", + "icon": { + "color": "terminal.ansiRed", + "id": "server" + }, "type": "shell", "command": "dart", - "detail": "Stop echo server", "options": { "cwd": "${workspaceFolder}/tool", }, + "dependsOn": [], "args": [ "run", "echo_down.dart" @@ -230,14 +388,22 @@ "isDefault": true }, "problemMatcher": [], + "isBackground": false, "presentation": { - "reveal": "never", - "panel": "shared" + "reveal": "silent", + "focus": false, + "panel": "shared", + "showReuseMessage": false, + "clear": false, } }, { "label": "go:run:echo", "detail": "Start echo server with Go", + "icon": { + "color": "terminal.ansiGreen", + "id": "server" + }, "options": { "cwd": "${workspaceFolder}/tool/echo", "env": {} @@ -256,8 +422,11 @@ "problemMatcher": [], "presentation": { "reveal": "always", - "panel": "dedicated" + "panel": "dedicated", + "focus": true, + "clear": true, + "group": "echo" } - } + }, ] } \ No newline at end of file diff --git a/example/.fvm/fvm_config.json b/example/.fvm/fvm_config.json deleted file mode 100644 index 41959e9..0000000 --- a/example/.fvm/fvm_config.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "flutterSdkVersion": "stable", - "flavors": {} -} diff --git a/example/.gitignore b/example/.gitignore deleted file mode 100644 index 9e45942..0000000 --- a/example/.gitignore +++ /dev/null @@ -1,79 +0,0 @@ -# Miscellaneous -*.class -*.log -*.pyc -*.swp -.DS_Store -.atom/ -.buildlog/ -.history -.svn/ -migrate_working_dir/ - -# IntelliJ related -*.iml -*.ipr -*.iws -.idea/ - -# The .vscode folder contains launch configuration and tasks you configure in -# VS Code which you may wish to be included in version control, so this line -# is commented out by default. -#.vscode/ - -# Flutter/Dart/Pub related -**/doc/api/ -**/ios/Flutter/.last_build_id -.dart_tool/ -.flutter-plugins -.flutter-plugins-dependencies -.packages -.pub-cache/ -.pub/ -/build/ - -# Symbolication related -app.*.symbols - -# Obfuscation related -app.*.map.json - -# Android Studio will place build artifacts here -/android/app/debug -/android/app/profile -/android/app/release - -# Databases -.sqlite -.db -.lock - -# Logs -log.txt - -# Emulator -emulator/ - -# Temporary files -temp/ -.temp/ - -# Env -.env* - -# Test -coverage/ - -# Flutter Version Manager -.fvm/flutter_sdk - -# Generated files - -# Screenshots -integration_test/screenshots/ - -# Firebase -.firebase/ - -# Config -config/local.json \ No newline at end of file diff --git a/example/.metadata b/example/.metadata deleted file mode 100644 index bd61a63..0000000 --- a/example/.metadata +++ /dev/null @@ -1,45 +0,0 @@ -# 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. - -version: - revision: 74e4b092e5212ebf8292dde2a48d3da960c0920b - channel: beta - -project_type: app - -# Tracks metadata for the flutter migrate command -migration: - platforms: - - platform: root - create_revision: 74e4b092e5212ebf8292dde2a48d3da960c0920b - base_revision: 74e4b092e5212ebf8292dde2a48d3da960c0920b - - platform: android - create_revision: 74e4b092e5212ebf8292dde2a48d3da960c0920b - base_revision: 74e4b092e5212ebf8292dde2a48d3da960c0920b - - platform: ios - create_revision: 74e4b092e5212ebf8292dde2a48d3da960c0920b - base_revision: 74e4b092e5212ebf8292dde2a48d3da960c0920b - - platform: linux - create_revision: 74e4b092e5212ebf8292dde2a48d3da960c0920b - base_revision: 74e4b092e5212ebf8292dde2a48d3da960c0920b - - platform: macos - create_revision: 74e4b092e5212ebf8292dde2a48d3da960c0920b - base_revision: 74e4b092e5212ebf8292dde2a48d3da960c0920b - - platform: web - create_revision: 74e4b092e5212ebf8292dde2a48d3da960c0920b - base_revision: 74e4b092e5212ebf8292dde2a48d3da960c0920b - - platform: windows - create_revision: 74e4b092e5212ebf8292dde2a48d3da960c0920b - base_revision: 74e4b092e5212ebf8292dde2a48d3da960c0920b - - # User provided section - - # List of Local paths (relative to this file) that should be - # ignored by the migrate tool. - # - # Files that are not part of the templates will be ignored by default. - unmanaged_files: - - 'lib/main.dart' - - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/example/README.md b/example/README.md deleted file mode 100644 index 436f3fd..0000000 --- a/example/README.md +++ /dev/null @@ -1,24 +0,0 @@ -# spinifyapp - -Spinify App Example - -## Code generation - -```bash -$ make codegen -``` - -## Localization - -```bash -$ code lib/src/common/localization/intl_en.arb -$ make intl -``` - -## Recreating the project - -**! Warning: This will overwrite all files in the current directory.** - -```bash -fvm spawn beta create --overwrite -t app --project-name "spinifyapp" --org "dev.plugfox.spinify" --description "Spinify App Example" --platforms ios,android,windows,linux,macos,web . -``` diff --git a/example/analysis_options.yaml b/example/analysis_options.yaml deleted file mode 100644 index 9c84a6e..0000000 --- a/example/analysis_options.yaml +++ /dev/null @@ -1,100 +0,0 @@ -include: package:flutter_lints/flutter.yaml - -# Analyzer options -analyzer: - # Exclude files from analysis. Must be relative to the root of the package. - exclude: - # Build - - "build/**" - # Tests - - "test/**.mocks.dart" - - ".test_coverage.dart" - - "coverage/**" - # Assets - - "assets/**" - # Generated - - "lib/src/common/localization/generated/**" - - "lib/src/common/constants/pubspec.yaml.g.dart" - - "lib/src/common/model/generated/**" - - "**.g.dart" - - "**.gql.dart" - - "**.freezed.dart" - - "**.config.dart" - - "**.mocks.dart" - - "**.gen.dart" - - "**.pb.dart" - - "**.pbenum.dart" - - "**.pbjson.dart" - # Flutter Version Manager - - ".fvm/**" - # Tools - #- "tool/**" - - "scripts/**" - - ".dart_tool/**" - # Platform - - "ios/**" - - "android/**" - - "web/**" - - "macos/**" - - "windows/**" - - "linux/**" - - - # Enable the following options to enable strong mode. - language: - strict-casts: true - strict-raw-types: true - strict-inference: true - - # Enable the following options to enable new language features. - #enable-experiment: - # - patterns - # - sealed-class - # - records - # - class-modifiers - # - macros - # - const-functions - # - extension-types - # - inference-update-2 - # - inline-class - # - value-class - # - variance - - # Set the following options to true to enable additional analysis. - errors: - # Info - directives_ordering: info - always_declare_return_types: info - - # Warning - unsafe_html: warning - no_logic_in_create_state: warning - empty_catches: warning - close_sinks: warning - - # Error - always_use_package_imports: error - avoid_relative_lib_imports: error - avoid_slow_async_io: error - avoid_types_as_parameter_names: error - cancel_subscriptions: error - valid_regexps: error - always_require_non_null_named_parameters: error - - # Disable rules - -# Lint rules -linter: - rules: - # Public packages - public_member_api_docs: false - lines_longer_than_80_chars: false - - # Enabling rules - always_use_package_imports: true - avoid_relative_lib_imports: true - - # Disable rules - sort_pub_dependencies: false - prefer_relative_imports: false - curly_braces_in_flow_control_structures: false \ No newline at end of file diff --git a/example/android/.gitignore b/example/android/.gitignore deleted file mode 100644 index 6f56801..0000000 --- a/example/android/.gitignore +++ /dev/null @@ -1,13 +0,0 @@ -gradle-wrapper.jar -/.gradle -/captures/ -/gradlew -/gradlew.bat -/local.properties -GeneratedPluginRegistrant.java - -# Remember to never publicly share your keystore. -# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app -key.properties -**/*.keystore -**/*.jks diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle deleted file mode 100644 index 609c4f8..0000000 --- a/example/android/app/build.gradle +++ /dev/null @@ -1,69 +0,0 @@ -plugins { - id "com.android.application" - id "kotlin-android" - id "dev.flutter.flutter-gradle-plugin" -} - -def localProperties = new Properties() -def localPropertiesFile = rootProject.file('local.properties') -if (localPropertiesFile.exists()) { - localPropertiesFile.withReader('UTF-8') { reader -> - localProperties.load(reader) - } -} - -def flutterVersionCode = localProperties.getProperty('flutter.versionCode') -if (flutterVersionCode == null) { - flutterVersionCode = '1' -} - -def flutterVersionName = localProperties.getProperty('flutter.versionName') -if (flutterVersionName == null) { - flutterVersionName = '1.0' -} - -android { - namespace "dev.plugfox.spinify.spinifyapp" - compileSdkVersion flutter.compileSdkVersion - ndkVersion flutter.ndkVersion - - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - } - - kotlinOptions { - jvmTarget = '1.8' - } - - sourceSets { - main.java.srcDirs += 'src/main/kotlin' - } - - defaultConfig { - // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). - applicationId "dev.plugfox.spinify.spinifyapp" - // You can update the following values to match your application needs. - // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. - minSdkVersion flutter.minSdkVersion - targetSdkVersion flutter.targetSdkVersion - versionCode flutterVersionCode.toInteger() - versionName flutterVersionName - } - - buildTypes { - release { - // TODO: Add your own signing config for the release build. - // Signing with the debug keys for now, so `flutter run --release` works. - signingConfig signingConfigs.debug - } - } -} - -flutter { - source '../..' -} - -dependencies { - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" -} diff --git a/example/android/app/src/debug/AndroidManifest.xml b/example/android/app/src/debug/AndroidManifest.xml deleted file mode 100644 index 399f698..0000000 --- a/example/android/app/src/debug/AndroidManifest.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml deleted file mode 100644 index 712541d..0000000 --- a/example/android/app/src/main/AndroidManifest.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - - - - - diff --git a/example/android/app/src/main/kotlin/dev/plugfox/spinify/spinifyapp/MainActivity.kt b/example/android/app/src/main/kotlin/dev/plugfox/spinify/spinifyapp/MainActivity.kt deleted file mode 100644 index 3bae9b8..0000000 --- a/example/android/app/src/main/kotlin/dev/plugfox/spinify/spinifyapp/MainActivity.kt +++ /dev/null @@ -1,6 +0,0 @@ -package dev.plugfox.spinify.spinifyapp - -import io.flutter.embedding.android.FlutterActivity - -class MainActivity: FlutterActivity() { -} diff --git a/example/android/app/src/main/res/drawable-v21/launch_background.xml b/example/android/app/src/main/res/drawable-v21/launch_background.xml deleted file mode 100644 index f74085f..0000000 --- a/example/android/app/src/main/res/drawable-v21/launch_background.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - diff --git a/example/android/app/src/main/res/drawable/launch_background.xml b/example/android/app/src/main/res/drawable/launch_background.xml deleted file mode 100644 index 304732f..0000000 --- a/example/android/app/src/main/res/drawable/launch_background.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - diff --git a/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index db77bb4..0000000 Binary files a/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png and /dev/null differ diff --git a/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index 17987b7..0000000 Binary files a/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png and /dev/null differ diff --git a/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png deleted file mode 100644 index 09d4391..0000000 Binary files a/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ diff --git a/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index d5f1c8d..0000000 Binary files a/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png deleted file mode 100644 index 4d6372e..0000000 Binary files a/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ diff --git a/example/android/app/src/main/res/values-night/styles.xml b/example/android/app/src/main/res/values-night/styles.xml deleted file mode 100644 index 06952be..0000000 --- a/example/android/app/src/main/res/values-night/styles.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - diff --git a/example/android/app/src/main/res/values/styles.xml b/example/android/app/src/main/res/values/styles.xml deleted file mode 100644 index cb1ef88..0000000 --- a/example/android/app/src/main/res/values/styles.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - diff --git a/example/android/app/src/profile/AndroidManifest.xml b/example/android/app/src/profile/AndroidManifest.xml deleted file mode 100644 index 399f698..0000000 --- a/example/android/app/src/profile/AndroidManifest.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - diff --git a/example/android/build.gradle b/example/android/build.gradle deleted file mode 100644 index f7eb7f6..0000000 --- a/example/android/build.gradle +++ /dev/null @@ -1,31 +0,0 @@ -buildscript { - ext.kotlin_version = '1.7.10' - repositories { - google() - mavenCentral() - } - - dependencies { - classpath 'com.android.tools.build:gradle:7.3.0' - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - } -} - -allprojects { - repositories { - google() - mavenCentral() - } -} - -rootProject.buildDir = '../build' -subprojects { - project.buildDir = "${rootProject.buildDir}/${project.name}" -} -subprojects { - project.evaluationDependsOn(':app') -} - -tasks.register("clean", Delete) { - delete rootProject.buildDir -} diff --git a/example/android/gradle.properties b/example/android/gradle.properties deleted file mode 100644 index 94adc3a..0000000 --- a/example/android/gradle.properties +++ /dev/null @@ -1,3 +0,0 @@ -org.gradle.jvmargs=-Xmx1536M -android.useAndroidX=true -android.enableJetifier=true diff --git a/example/android/gradle/wrapper/gradle-wrapper.properties b/example/android/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 3c472b9..0000000 --- a/example/android/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,5 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip diff --git a/example/android/settings.gradle b/example/android/settings.gradle deleted file mode 100644 index 55c4ca8..0000000 --- a/example/android/settings.gradle +++ /dev/null @@ -1,20 +0,0 @@ -pluginManagement { - def flutterSdkPath = { - def properties = new Properties() - file("local.properties").withInputStream { properties.load(it) } - def flutterSdkPath = properties.getProperty("flutter.sdk") - assert flutterSdkPath != null, "flutter.sdk not set in local.properties" - return flutterSdkPath - } - settings.ext.flutterSdkPath = flutterSdkPath() - - includeBuild("${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle") - - plugins { - id "dev.flutter.flutter-gradle-plugin" version "1.0.0" apply false - } -} - -include ":app" - -apply from: "${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle/app_plugin_loader.gradle" diff --git a/example/build.yaml b/example/build.yaml deleted file mode 100644 index 785f9a0..0000000 --- a/example/build.yaml +++ /dev/null @@ -1,11 +0,0 @@ -targets: - $default: - sources: - - $package$ - - lib/** - - pubspec.yaml - - test/** - builders: - pubspec_generator: - options: - output: lib/src/common/constant/pubspec.yaml.g.dart diff --git a/example/config/development.json b/example/config/development.json deleted file mode 100644 index 9cbc255..0000000 --- a/example/config/development.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "ENVIRONMENT": "development", - "CENTRIFUGE_BASE_URL": "http://localhost:8000", - "CENTRIFUGE_CHANNEL": "chat", - "CENTRIFUGE_TIMEOUT": 8000 -} diff --git a/example/ios/.gitignore b/example/ios/.gitignore deleted file mode 100644 index 7a7f987..0000000 --- a/example/ios/.gitignore +++ /dev/null @@ -1,34 +0,0 @@ -**/dgph -*.mode1v3 -*.mode2v3 -*.moved-aside -*.pbxuser -*.perspectivev3 -**/*sync/ -.sconsign.dblite -.tags* -**/.vagrant/ -**/DerivedData/ -Icon? -**/Pods/ -**/.symlinks/ -profile -xcuserdata -**/.generated/ -Flutter/App.framework -Flutter/Flutter.framework -Flutter/Flutter.podspec -Flutter/Generated.xcconfig -Flutter/ephemeral/ -Flutter/app.flx -Flutter/app.zip -Flutter/flutter_assets/ -Flutter/flutter_export_environment.sh -ServiceDefinitions.json -Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!default.mode1v3 -!default.mode2v3 -!default.pbxuser -!default.perspectivev3 diff --git a/example/ios/Flutter/AppFrameworkInfo.plist b/example/ios/Flutter/AppFrameworkInfo.plist deleted file mode 100644 index 9625e10..0000000 --- a/example/ios/Flutter/AppFrameworkInfo.plist +++ /dev/null @@ -1,26 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - App - CFBundleIdentifier - io.flutter.flutter.app - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - App - CFBundlePackageType - FMWK - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1.0 - MinimumOSVersion - 11.0 - - diff --git a/example/ios/Flutter/Debug.xcconfig b/example/ios/Flutter/Debug.xcconfig deleted file mode 100644 index ec97fc6..0000000 --- a/example/ios/Flutter/Debug.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" -#include "Generated.xcconfig" diff --git a/example/ios/Flutter/Release.xcconfig b/example/ios/Flutter/Release.xcconfig deleted file mode 100644 index c4855bf..0000000 --- a/example/ios/Flutter/Release.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" -#include "Generated.xcconfig" diff --git a/example/ios/Podfile b/example/ios/Podfile deleted file mode 100644 index d97f17e..0000000 --- a/example/ios/Podfile +++ /dev/null @@ -1,44 +0,0 @@ -# Uncomment this line to define a global platform for your project -# platform :ios, '12.0' - -# CocoaPods analytics sends network stats synchronously affecting flutter build latency. -ENV['COCOAPODS_DISABLE_STATS'] = 'true' - -project 'Runner', { - 'Debug' => :debug, - 'Profile' => :release, - 'Release' => :release, -} - -def flutter_root - generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) - unless File.exist?(generated_xcode_build_settings_path) - raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" - end - - File.foreach(generated_xcode_build_settings_path) do |line| - matches = line.match(/FLUTTER_ROOT\=(.*)/) - return matches[1].strip if matches - end - raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" -end - -require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) - -flutter_ios_podfile_setup - -target 'Runner' do - use_frameworks! - use_modular_headers! - - flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) - target 'RunnerTests' do - inherit! :search_paths - end -end - -post_install do |installer| - installer.pods_project.targets.each do |target| - flutter_additional_ios_build_settings(target) - end -end diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj deleted file mode 100644 index be18bd5..0000000 --- a/example/ios/Runner.xcodeproj/project.pbxproj +++ /dev/null @@ -1,614 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 54; - objects = { - -/* Begin PBXBuildFile section */ - 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; - 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; - 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; - 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; - 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; - 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; - 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - 331C8085294A63A400263BE5 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 97C146E61CF9000F007C117D /* Project object */; - proxyType = 1; - remoteGlobalIDString = 97C146ED1CF9000F007C117D; - remoteInfo = Runner; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 9705A1C41CF9048500538489 /* Embed Frameworks */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - ); - name = "Embed Frameworks"; - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; - 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; - 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; - 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; - 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; - 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; - 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; - 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; - 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; - 331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 97C146EB1CF9000F007C117D /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 9740EEB11CF90186004384FC /* Flutter */ = { - isa = PBXGroup; - children = ( - 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, - 9740EEB21CF90195004384FC /* Debug.xcconfig */, - 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, - 9740EEB31CF90195004384FC /* Generated.xcconfig */, - ); - name = Flutter; - sourceTree = ""; - }; - 331C8082294A63A400263BE5 /* RunnerTests */ = { - isa = PBXGroup; - children = ( - 331C807B294A618700263BE5 /* RunnerTests.swift */, - ); - path = RunnerTests; - sourceTree = ""; - }; - 97C146E51CF9000F007C117D = { - isa = PBXGroup; - children = ( - 9740EEB11CF90186004384FC /* Flutter */, - 97C146F01CF9000F007C117D /* Runner */, - 97C146EF1CF9000F007C117D /* Products */, - 331C8082294A63A400263BE5 /* RunnerTests */, - ); - sourceTree = ""; - }; - 97C146EF1CF9000F007C117D /* Products */ = { - isa = PBXGroup; - children = ( - 97C146EE1CF9000F007C117D /* Runner.app */, - 331C8081294A63A400263BE5 /* RunnerTests.xctest */, - ); - name = Products; - sourceTree = ""; - }; - 97C146F01CF9000F007C117D /* Runner */ = { - isa = PBXGroup; - children = ( - 97C146FA1CF9000F007C117D /* Main.storyboard */, - 97C146FD1CF9000F007C117D /* Assets.xcassets */, - 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, - 97C147021CF9000F007C117D /* Info.plist */, - 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, - 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, - 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, - 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, - ); - path = Runner; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 331C8080294A63A400263BE5 /* RunnerTests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; - buildPhases = ( - 331C807D294A63A400263BE5 /* Sources */, - 331C807E294A63A400263BE5 /* Frameworks */, - 331C807F294A63A400263BE5 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - 331C8086294A63A400263BE5 /* PBXTargetDependency */, - ); - name = RunnerTests; - productName = RunnerTests; - productReference = 331C8081294A63A400263BE5 /* RunnerTests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; - 97C146ED1CF9000F007C117D /* Runner */ = { - isa = PBXNativeTarget; - buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; - buildPhases = ( - 9740EEB61CF901F6004384FC /* Run Script */, - 97C146EA1CF9000F007C117D /* Sources */, - 97C146EB1CF9000F007C117D /* Frameworks */, - 97C146EC1CF9000F007C117D /* Resources */, - 9705A1C41CF9048500538489 /* Embed Frameworks */, - 3B06AD1E1E4923F5004D2608 /* Thin Binary */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = Runner; - productName = Runner; - productReference = 97C146EE1CF9000F007C117D /* Runner.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 97C146E61CF9000F007C117D /* Project object */ = { - isa = PBXProject; - attributes = { - BuildIndependentTargetsInParallel = YES; - LastUpgradeCheck = 1430; - ORGANIZATIONNAME = ""; - TargetAttributes = { - 331C8080294A63A400263BE5 = { - CreatedOnToolsVersion = 14.0; - TestTargetID = 97C146ED1CF9000F007C117D; - }; - 97C146ED1CF9000F007C117D = { - CreatedOnToolsVersion = 7.3.1; - LastSwiftMigration = 1100; - }; - }; - }; - buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; - compatibilityVersion = "Xcode 9.3"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 97C146E51CF9000F007C117D; - productRefGroup = 97C146EF1CF9000F007C117D /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 97C146ED1CF9000F007C117D /* Runner */, - 331C8080294A63A400263BE5 /* RunnerTests */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 331C807F294A63A400263BE5 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 97C146EC1CF9000F007C117D /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, - 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, - 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, - 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { - isa = PBXShellScriptBuildPhase; - alwaysOutOfDate = 1; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", - ); - name = "Thin Binary"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; - }; - 9740EEB61CF901F6004384FC /* Run Script */ = { - isa = PBXShellScriptBuildPhase; - alwaysOutOfDate = 1; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Run Script"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 331C807D294A63A400263BE5 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 97C146EA1CF9000F007C117D /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, - 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - 331C8086294A63A400263BE5 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 97C146ED1CF9000F007C117D /* Runner */; - targetProxy = 331C8085294A63A400263BE5 /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin PBXVariantGroup section */ - 97C146FA1CF9000F007C117D /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 97C146FB1CF9000F007C117D /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 97C147001CF9000F007C117D /* Base */, - ); - name = LaunchScreen.storyboard; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 249021D3217E4FDB00AE95B9 /* Profile */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - SUPPORTED_PLATFORMS = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Profile; - }; - 249021D4217E4FDB00AE95B9 /* Profile */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - ENABLE_BITCODE = NO; - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = dev.plugfox.spinify.spinifyapp; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; - SWIFT_VERSION = 5.0; - VERSIONING_SYSTEM = "apple-generic"; - }; - name = Profile; - }; - 331C8088294A63A400263BE5 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = AE0B7B92F70575B8D7E0D07E /* Pods-RunnerTests.debug.xcconfig */; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = dev.plugfox.spinify.spinifyapp.RunnerTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.0; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; - }; - name = Debug; - }; - 331C8089294A63A400263BE5 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 89B67EB44CE7B6631473024E /* Pods-RunnerTests.release.xcconfig */; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = dev.plugfox.spinify.spinifyapp.RunnerTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 5.0; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; - }; - name = Release; - }; - 331C808A294A63A400263BE5 /* Profile */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 640959BDD8F10B91D80A66BE /* Pods-RunnerTests.profile.xcconfig */; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = dev.plugfox.spinify.spinifyapp.RunnerTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 5.0; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; - }; - name = Profile; - }; - 97C147031CF9000F007C117D /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 97C147041CF9000F007C117D /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - SUPPORTED_PLATFORMS = iphoneos; - SWIFT_COMPILATION_MODE = wholemodule; - SWIFT_OPTIMIZATION_LEVEL = "-O"; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 97C147061CF9000F007C117D /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - ENABLE_BITCODE = NO; - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = dev.plugfox.spinify.spinifyapp; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.0; - VERSIONING_SYSTEM = "apple-generic"; - }; - name = Debug; - }; - 97C147071CF9000F007C117D /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - ENABLE_BITCODE = NO; - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = dev.plugfox.spinify.spinifyapp; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; - SWIFT_VERSION = 5.0; - VERSIONING_SYSTEM = "apple-generic"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 331C8088294A63A400263BE5 /* Debug */, - 331C8089294A63A400263BE5 /* Release */, - 331C808A294A63A400263BE5 /* Profile */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 97C147031CF9000F007C117D /* Debug */, - 97C147041CF9000F007C117D /* Release */, - 249021D3217E4FDB00AE95B9 /* Profile */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 97C147061CF9000F007C117D /* Debug */, - 97C147071CF9000F007C117D /* Release */, - 249021D4217E4FDB00AE95B9 /* Profile */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 97C146E61CF9000F007C117D /* Project object */; -} diff --git a/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 919434a..0000000 --- a/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d9810..0000000 --- a/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings deleted file mode 100644 index f9b0d7c..0000000 --- a/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +++ /dev/null @@ -1,8 +0,0 @@ - - - - - PreviewsEnabled - - - diff --git a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme deleted file mode 100644 index 87131a0..0000000 --- a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ /dev/null @@ -1,98 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/example/ios/Runner.xcworkspace/contents.xcworkspacedata b/example/ios/Runner.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 1d526a1..0000000 --- a/example/ios/Runner.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d9810..0000000 --- a/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings deleted file mode 100644 index f9b0d7c..0000000 --- a/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +++ /dev/null @@ -1,8 +0,0 @@ - - - - - PreviewsEnabled - - - diff --git a/example/ios/Runner/AppDelegate.swift b/example/ios/Runner/AppDelegate.swift deleted file mode 100644 index 70693e4..0000000 --- a/example/ios/Runner/AppDelegate.swift +++ /dev/null @@ -1,13 +0,0 @@ -import UIKit -import Flutter - -@UIApplicationMain -@objc class AppDelegate: FlutterAppDelegate { - override func application( - _ application: UIApplication, - didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? - ) -> Bool { - GeneratedPluginRegistrant.register(with: self) - return super.application(application, didFinishLaunchingWithOptions: launchOptions) - } -} diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index d36b1fa..0000000 --- a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,122 +0,0 @@ -{ - "images" : [ - { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "Icon-App-20x20@2x.png", - "scale" : "2x" - }, - { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "Icon-App-20x20@3x.png", - "scale" : "3x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@1x.png", - "scale" : "1x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@2x.png", - "scale" : "2x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@3x.png", - "scale" : "3x" - }, - { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "Icon-App-40x40@2x.png", - "scale" : "2x" - }, - { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "Icon-App-40x40@3x.png", - "scale" : "3x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "Icon-App-60x60@2x.png", - "scale" : "2x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "Icon-App-60x60@3x.png", - "scale" : "3x" - }, - { - "size" : "20x20", - "idiom" : "ipad", - "filename" : "Icon-App-20x20@1x.png", - "scale" : "1x" - }, - { - "size" : "20x20", - "idiom" : "ipad", - "filename" : "Icon-App-20x20@2x.png", - "scale" : "2x" - }, - { - "size" : "29x29", - "idiom" : "ipad", - "filename" : "Icon-App-29x29@1x.png", - "scale" : "1x" - }, - { - "size" : "29x29", - "idiom" : "ipad", - "filename" : "Icon-App-29x29@2x.png", - "scale" : "2x" - }, - { - "size" : "40x40", - "idiom" : "ipad", - "filename" : "Icon-App-40x40@1x.png", - "scale" : "1x" - }, - { - "size" : "40x40", - "idiom" : "ipad", - "filename" : "Icon-App-40x40@2x.png", - "scale" : "2x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "Icon-App-76x76@1x.png", - "scale" : "1x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "Icon-App-76x76@2x.png", - "scale" : "2x" - }, - { - "size" : "83.5x83.5", - "idiom" : "ipad", - "filename" : "Icon-App-83.5x83.5@2x.png", - "scale" : "2x" - }, - { - "size" : "1024x1024", - "idiom" : "ios-marketing", - "filename" : "Icon-App-1024x1024@1x.png", - "scale" : "1x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png deleted file mode 100644 index dc9ada4..0000000 Binary files a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png and /dev/null differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png deleted file mode 100644 index 7353c41..0000000 Binary files a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png and /dev/null differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png deleted file mode 100644 index 797d452..0000000 Binary files a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png and /dev/null differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png deleted file mode 100644 index 6ed2d93..0000000 Binary files a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png and /dev/null differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png deleted file mode 100644 index 4cd7b00..0000000 Binary files a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png and /dev/null differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png deleted file mode 100644 index fe73094..0000000 Binary files a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png and /dev/null differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png deleted file mode 100644 index 321773c..0000000 Binary files a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png and /dev/null differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png deleted file mode 100644 index 797d452..0000000 Binary files a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png and /dev/null differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png deleted file mode 100644 index 502f463..0000000 Binary files a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png and /dev/null differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png deleted file mode 100644 index 0ec3034..0000000 Binary files a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png and /dev/null differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png deleted file mode 100644 index 0ec3034..0000000 Binary files a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png and /dev/null differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png deleted file mode 100644 index e9f5fea..0000000 Binary files a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png and /dev/null differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png deleted file mode 100644 index 84ac32a..0000000 Binary files a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png and /dev/null differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png deleted file mode 100644 index 8953cba..0000000 Binary files a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png and /dev/null differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png deleted file mode 100644 index 0467bf1..0000000 Binary files a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png and /dev/null differ diff --git a/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json deleted file mode 100644 index 0bedcf2..0000000 --- a/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "filename" : "LaunchImage.png", - "scale" : "1x" - }, - { - "idiom" : "universal", - "filename" : "LaunchImage@2x.png", - "scale" : "2x" - }, - { - "idiom" : "universal", - "filename" : "LaunchImage@3x.png", - "scale" : "3x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} diff --git a/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png deleted file mode 100644 index 9da19ea..0000000 Binary files a/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png and /dev/null differ diff --git a/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png deleted file mode 100644 index 9da19ea..0000000 Binary files a/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png and /dev/null differ diff --git a/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png deleted file mode 100644 index 9da19ea..0000000 Binary files a/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png and /dev/null differ diff --git a/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md deleted file mode 100644 index 89c2725..0000000 --- a/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Launch Screen Assets - -You can customize the launch screen with your own desired assets by replacing the image files in this directory. - -You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. \ No newline at end of file diff --git a/example/ios/Runner/Base.lproj/LaunchScreen.storyboard b/example/ios/Runner/Base.lproj/LaunchScreen.storyboard deleted file mode 100644 index f2e259c..0000000 --- a/example/ios/Runner/Base.lproj/LaunchScreen.storyboard +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/example/ios/Runner/Base.lproj/Main.storyboard b/example/ios/Runner/Base.lproj/Main.storyboard deleted file mode 100644 index f3c2851..0000000 --- a/example/ios/Runner/Base.lproj/Main.storyboard +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/example/ios/Runner/Info.plist b/example/ios/Runner/Info.plist deleted file mode 100644 index c1c8f38..0000000 --- a/example/ios/Runner/Info.plist +++ /dev/null @@ -1,51 +0,0 @@ - - - - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleDisplayName - Spinify App - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - spinifyapp - CFBundlePackageType - APPL - CFBundleShortVersionString - $(FLUTTER_BUILD_NAME) - CFBundleSignature - ???? - CFBundleVersion - $(FLUTTER_BUILD_NUMBER) - LSRequiresIPhoneOS - - UILaunchStoryboardName - LaunchScreen - UIMainStoryboardFile - Main - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UIViewControllerBasedStatusBarAppearance - - CADisableMinimumFrameDurationOnPhone - - UIApplicationSupportsIndirectInputEvents - - - diff --git a/example/ios/Runner/Runner-Bridging-Header.h b/example/ios/Runner/Runner-Bridging-Header.h deleted file mode 100644 index 308a2a5..0000000 --- a/example/ios/Runner/Runner-Bridging-Header.h +++ /dev/null @@ -1 +0,0 @@ -#import "GeneratedPluginRegistrant.h" diff --git a/example/ios/RunnerTests/RunnerTests.swift b/example/ios/RunnerTests/RunnerTests.swift deleted file mode 100644 index 86a7c3b..0000000 --- a/example/ios/RunnerTests/RunnerTests.swift +++ /dev/null @@ -1,12 +0,0 @@ -import Flutter -import UIKit -import XCTest - -class RunnerTests: XCTestCase { - - func testExample() { - // If you add code to the Runner application, consider adding tests here. - // See https://developer.apple.com/documentation/xctest for more information about using XCTest. - } - -} diff --git a/example/lib/main.dart b/example/lib/main.dart deleted file mode 100644 index f532f7c..0000000 --- a/example/lib/main.dart +++ /dev/null @@ -1,33 +0,0 @@ -import 'dart:async'; - -import 'package:flutter/material.dart'; -import 'package:l/l.dart'; -import 'package:spinifyapp/src/common/util/logger_util.dart'; -import 'package:spinifyapp/src/common/widget/app.dart'; -import 'package:spinifyapp/src/feature/dependencies/initialization/initialization.dart'; -import 'package:spinifyapp/src/feature/dependencies/widget/dependencies_scope.dart'; -import 'package:spinifyapp/src/feature/dependencies/widget/initialization_splash_screen.dart'; - -void main() => l.capture( - () => runZonedGuarded( - () { - final initialization = InitializationExecutor(); - runApp( - DependenciesScope( - initialization: initialization(), - splashScreen: InitializationSplashScreen( - progress: initialization, - ), - child: const App(), - ), - ); - }, - l.e, - ), - const LogOptions( - handlePrint: true, - messageFormatting: LoggerUtil.messageFormatting, - outputInRelease: false, - printColors: true, - ), - ); diff --git a/example/lib/src/common/constant/config.dart b/example/lib/src/common/constant/config.dart deleted file mode 100644 index 972977d..0000000 --- a/example/lib/src/common/constant/config.dart +++ /dev/null @@ -1,79 +0,0 @@ -/// Config for app. -abstract final class Config { - /// Environment flavor. - /// e.g. development, staging, production - static final EnvironmentFlavor environment = EnvironmentFlavor.from( - const String.fromEnvironment('ENVIRONMENT', defaultValue: 'development')); - - // --- Centrifuge --- // - - /// Centrifuge url. - /// e.g. https://domain.tld - static const String centrifugeBaseUrl = String.fromEnvironment( - 'CENTRIFUGE_BASE_URL', - defaultValue: 'http://127.0.0.1:8000'); - - /// Centrifuge timeout in milliseconds. - /// e.g. 15000 ms - static const Duration centrifugeTimeout = Duration( - milliseconds: - int.fromEnvironment('CENTRIFUGE_TIMEOUT', defaultValue: 15000)); - - /// Secret for HMAC token. - static const String centrifugeToken = - String.fromEnvironment('CENTRIFUGE_TOKEN_HMAC_SECRET'); - - /// Channel by default. - static const String centrifugeChannel = - String.fromEnvironment('CENTRIFUGE_CHANNEL'); - - /// Username by default. - static const String centrifugeUsername = - String.fromEnvironment('CENTRIFUGE_USERNAME'); - // --- Layout --- // - - /// Maximum screen layout width for screen with list view. - static const int maxScreenLayoutWidth = - int.fromEnvironment('MAX_LAYOUT_WIDTH', defaultValue: 768); -} - -/// Environment flavor. -/// e.g. development, staging, production -enum EnvironmentFlavor { - /// Local - local('local'), - - /// Development - development('development'), - - /// Staging - staging('staging'), - - /// Production - production('production'); - - const EnvironmentFlavor(this.value); - - factory EnvironmentFlavor.from(String? value) => - switch (value?.trim().toLowerCase()) { - 'local' || 'loc' || 'lcl' || 'l' => development, - 'development' || 'debug' || 'develop' || 'dev' || 'd' => development, - 'staging' || 'profile' || 'stage' || 'stg' || 's' => staging, - 'production' || 'release' || 'prod' || 'prd' || 'p' => production, - _ => const bool.fromEnvironment('dart.vm.product') - ? production - : development, - }; - - /// development, staging, production - final String value; - - /// Whether the environment is development. - bool get isDevelopment => this == development; - - /// Whether the environment is staging. - bool get isStaging => this == staging; - - /// Whether the environment is production. - bool get isProduction => this == production; -} diff --git a/example/lib/src/common/constant/pubspec.yaml.g.dart b/example/lib/src/common/constant/pubspec.yaml.g.dart deleted file mode 100644 index 8b1243b..0000000 --- a/example/lib/src/common/constant/pubspec.yaml.g.dart +++ /dev/null @@ -1,527 +0,0 @@ -// ignore_for_file: lines_longer_than_80_chars, unnecessary_raw_strings -// ignore_for_file: use_raw_strings, avoid_classes_with_only_static_members -// ignore_for_file: avoid_escaping_inner_quotes, prefer_single_quotes - -/// GENERATED CODE - DO NOT MODIFY BY HAND - -library pubspec; - -// ***************************************************************************** -// * pubspec_generator * -// ***************************************************************************** - -/* - - MIT License - - Copyright (c) 2023 Plague Fox - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - */ - -/// Given a version number MAJOR.MINOR.PATCH, increment the: -/// -/// 1. MAJOR version when you make incompatible API changes -/// 2. MINOR version when you add functionality in a backward compatible manner -/// 3. PATCH version when you make backward compatible bug fixes -/// -/// Additional labels for pre-release and build metadata are available -/// as extensions to the MAJOR.MINOR.PATCH format. -typedef PubspecVersion = ({ - String representation, - String canonical, - int major, - int minor, - int patch, - List preRelease, - List build -}); - -/// # The pubspec file -/// -/// Code generated pubspec.yaml.g.dart from pubspec.yaml -/// This class is generated from pubspec.yaml, do not edit directly. -/// -/// Every pub package needs some metadata so it can specify its dependencies. -/// Pub packages that are shared with others also need to provide some other -/// information so users can discover them. All of this metadata goes -/// in the package’s pubspec: -/// a file named pubspec.yaml that’s written in the YAML language. -/// -/// Read more: -/// - https://pub.dev/packages/pubspec_generator -/// - https://dart.dev/tools/pub/pubspec -sealed class Pubspec { - /// Version - /// - /// Current app [version] - /// - /// Every package has a version. - /// A version number is required to host your package on the pub.dev site, - /// but can be omitted for local-only packages. - /// If you omit it, your package is implicitly versioned 0.0.0. - /// - /// Versioning is necessary for reusing code while letting it evolve quickly. - /// A version number is three numbers separated by dots, like 0.2.43. - /// It can also optionally have a build ( +1, +2, +hotfix.oopsie) - /// or prerelease (-dev.4, -alpha.12, -beta.7, -rc.5) suffix. - /// - /// Each time you publish your package, you publish it at a specific version. - /// Once that’s been done, consider it hermetically sealed: - /// you can’t touch it anymore. To make more changes, - /// you’ll need a new version. - /// - /// When you select a version, - /// follow [semantic versioning](https://semver.org/). - static const PubspecVersion version = ( - /// Non-canonical string representation of the version as provided - /// in the pubspec.yaml file. - representation: r'1.0.0+1', - - /// Returns a 'canonicalized' representation - /// of the application version. - /// This represents the version string in accordance with - /// Semantic Versioning (SemVer) standards. - canonical: r'1.0.0+1', - - /// MAJOR version when you make incompatible API changes. - /// The major version number: 1 in "1.2.3". - major: 1, - - /// MINOR version when you add functionality - /// in a backward compatible manner. - /// The minor version number: 2 in "1.2.3". - minor: 0, - - /// PATCH version when you make backward compatible bug fixes. - /// The patch version number: 3 in "1.2.3". - patch: 0, - - /// The pre-release identifier: "foo" in "1.2.3-foo". - preRelease: [], - - /// The build identifier: "foo" in "1.2.3+foo". - build: [r'1'], - ); - - /// Build date and time (UTC) - static final DateTime timestamp = DateTime.utc( - 2023, - 8, - 4, - 9, - 6, - 50, - 841, - 552, - ); - - /// Name - /// - /// Current app [name] - /// - /// Every package needs a name. - /// It’s how other packages refer to yours, and how it appears to the world, - /// should you publish it. - /// - /// The name should be all lowercase, with underscores to separate words, - /// just_like_this. Use only basic Latin letters and Arabic digits: - /// [a-z0-9_]. Also, make sure the name is a valid Dart identifier—that - /// it doesn’t start with digits - /// and isn’t a [reserved word](https://dart.dev/language/keywords). - /// - /// Try to pick a name that is clear, terse, and not already in use. - /// A quick search of packages on the [pub.dev site](https://pub.dev/packages) - /// to make sure that nothing else is using your name is recommended. - static const String name = r'spinifyapp'; - - /// Description - /// - /// Current app [description] - /// - /// This is optional for your own personal packages, - /// but if you intend to publish your package you must provide a description, - /// which should be in English. - /// The description should be relatively short, from 60 to 180 characters - /// and tell a casual reader what they might want to know about your package. - /// - /// Think of the description as the sales pitch for your package. - /// Users see it when they [browse for packages](https://pub.dev/packages). - /// The description is plain text: no markdown or HTML. - static const String description = r'Spinify App Example'; - - /// Homepage - /// - /// Current app [homepage] - /// - /// This should be a URL pointing to the website for your package. - /// For [hosted packages](https://dart.dev/tools/pub/dependencies#hosted-packages), - /// this URL is linked from the package’s page. - /// While providing a homepage is optional, - /// please provide it or repository (or both). - /// It helps users understand where your package is coming from. - static const String homepage = r'https://centrifugal.dev'; - - /// Repository - /// - /// Current app [repository] - /// - /// Repository - /// The optional repository field should contain the URL for your package’s - /// source code repository—for example, - /// https://github.com//. - /// If you publish your package to the pub.dev site, - /// then your package’s page displays the repository URL. - /// While providing a repository is optional, - /// please provide it or homepage (or both). - /// It helps users understand where your package is coming from. - static const String repository = r'https://github.com/PlugFox/spinify'; - - /// Issue tracker - /// - /// Current app [issueTracker] - /// - /// The optional issue_tracker field should contain a URL for the package’s - /// issue tracker, where existing bugs can be viewed and new bugs can be filed. - /// The pub.dev site attempts to display a link - /// to each package’s issue tracker, using the value of this field. - /// If issue_tracker is missing but repository is present and points to GitHub, - /// then the pub.dev site uses the default issue tracker - /// (https://github.com///issues). - static const String issueTracker = - r'https://github.com/PlugFox/spinify/issues'; - - /// Documentation - /// - /// Current app [documentation] - /// - /// Some packages have a site that hosts documentation, - /// separate from the main homepage and from the Pub-generated API reference. - /// If your package has additional documentation, add a documentation: - /// field with that URL; pub shows a link to this documentation - /// on your package’s page. - static const String documentation = r''; - - /// Publish_to - /// - /// Current app [publishTo] - /// - /// The default uses the [pub.dev](https://pub.dev/) site. - /// Specify none to prevent a package from being published. - /// This setting can be used to specify a custom pub package server to publish. - /// - /// ```yaml - /// publish_to: none - /// ``` - static const String publishTo = r'none'; - - /// Funding - /// - /// Current app [funding] - /// - /// Package authors can use the funding property to specify - /// a list of URLs that provide information on how users - /// can help fund the development of the package. For example: - /// - /// ```yaml - /// funding: - /// - https://www.buymeacoffee.com/example_user - /// - https://www.patreon.com/some-account - /// ``` - /// - /// If published to [pub.dev](https://pub.dev/) the links are displayed on the package page. - /// This aims to help users fund the development of their dependencies. - static const List funding = [ - r'https://www.buymeacoffee.com/plugfox', - r'https://www.patreon.com/plugfox', - r'https://boosty.to/plugfox', - ]; - - /// False_secrets - /// - /// Current app [falseSecrets] - /// - /// When you try to publish a package, - /// pub conducts a search for potential leaks of secret credentials, - /// API keys, or cryptographic keys. - /// If pub detects a potential leak in a file that would be published, - /// then pub warns you and refuses to publish the package. - /// - /// Leak detection isn’t perfect. To avoid false positives, - /// you can tell pub not to search for leaks in certain files, - /// by creating an allowlist using gitignore - /// patterns under false_secrets in the pubspec. - /// - /// For example, the following entry causes pub not to look - /// for leaks in the file lib/src/hardcoded_api_key.dart - /// and in all .pem files in the test/localhost_certificates/ directory: - /// - /// ```yaml - /// false_secrets: - /// - /lib/src/hardcoded_api_key.dart - /// - /test/localhost_certificates/*.pem - /// ``` - /// - /// Starting a gitignore pattern with slash (/) ensures - /// that the pattern is considered relative to the package’s root directory. - static const List falseSecrets = []; - - /// Screenshots - /// - /// Current app [screenshots] - /// - /// Packages can showcase their widgets or other visual elements - /// using screenshots displayed on their pub.dev page. - /// To specify screenshots for the package to display, - /// use the screenshots field. - /// - /// A package can list up to 10 screenshots under the screenshots field. - /// Don’t include logos or other branding imagery in this section. - /// Each screenshot includes one description and one path. - /// The description explains what the screenshot depicts - /// in no more than 160 characters. For example: - /// - /// ```yaml - /// screenshots: - /// - description: 'This screenshot shows the transformation of a number of bytes - /// to a human-readable expression.' - /// path: path/to/image/in/package/500x500.webp - /// - description: 'This screenshot shows a stack trace returning a human-readable - /// representation.' - /// path: path/to/image/in/package.png - /// ``` - /// - /// Pub.dev limits screenshots to the following specifications: - /// - /// - File size: max 4 MB per image. - /// - File types: png, jpg, gif, or webp. - /// - Static and animated images are both allowed. - /// - /// Keep screenshot files small. Each download of the package - /// includes all screenshot files. - /// - /// Pub.dev generates the package’s thumbnail image from the first screenshot. - /// If this screenshot uses animation, pub.dev uses its first frame. - static const List screenshots = []; - - /// Topics - /// - /// Current app [topics] - /// - /// Package authors can use the topics field to categorize their package. Topics can be used to assist discoverability during search with filters on pub.dev. Pub.dev displays the topics on the package page as well as in the search results. - /// - /// The field consists of a list of names. For example: - /// - /// ```yaml - /// topics: - /// - network - /// - http - /// ``` - /// - /// Pub.dev requires topics to follow these specifications: - /// - /// - Tag each package with at most 5 topics. - /// - Write the topic name following these requirements: - /// 1) Use between 2 and 32 characters. - /// 2) Use only lowercase alphanumeric characters or hyphens (a-z, 0-9, -). - /// 3) Don’t use two consecutive hyphens (--). - /// 4) Start the name with lowercase alphabet characters (a-z). - /// 5) End with alphanumeric characters (a-z or 0-9). - /// - /// When choosing topics, consider if existing topics are relevant. - /// Tagging with existing topics helps users discover your package. - static const List topics = [ - r'spinify', - r'centrifugo', - r'centrifuge', - r'websocket', - r'cross-platform', - ]; - - /// Environment - static const Map environment = { - 'sdk': '>=3.1.0-63.1.beta <4.0.0', - 'flutter': '>=3.1.0-63.1.beta <4.0.0', - }; - - /// Platforms - /// - /// Current app [platforms] - /// - /// When you [publish a package](https://dart.dev/tools/pub/publishing), - /// pub.dev automatically detects the platforms that the package supports. - /// If this platform-support list is incorrect, - /// use platforms to explicitly declare which platforms your package supports. - /// - /// For example, the following platforms entry causes - /// pub.dev to list the package as supporting - /// Android, iOS, Linux, macOS, Web, and Windows: - /// - /// ```yaml - /// # This package supports all platforms listed below. - /// platforms: - /// android: - /// ios: - /// linux: - /// macos: - /// web: - /// windows: - /// ``` - /// - /// Here is an example of declaring that the package supports only Linux and macOS (and not, for example, Windows): - /// - /// ```yaml - /// # This package supports only Linux and macOS. - /// platforms: - /// linux: - /// macos: - /// ``` - static const Map platforms = { - 'android': r'', - 'ios': r'', - 'linux': r'', - 'macos': r'', - 'web': r'', - 'windows': r'', - }; - - /// Dependencies - /// - /// Current app [dependencies] - /// - /// [Dependencies](https://dart.dev/tools/pub/glossary#dependency) - /// are the pubspec’s `raison d’être`. - /// In this section you list each package that - /// your package needs in order to work. - /// - /// Dependencies fall into one of two types. - /// Regular dependencies are listed under dependencies: - /// these are packages that anyone using your package will also need. - /// Dependencies that are only needed in - /// the development phase of the package itself - /// are listed under dev_dependencies. - /// - /// During the development process, - /// you might need to temporarily override a dependency. - /// You can do so using dependency_overrides. - /// - /// For more information, - /// see [Package dependencies](https://dart.dev/tools/pub/dependencies). - static const Map dependencies = { - 'flutter': { - 'sdk': r'flutter', - }, - 'flutter_localizations': { - 'sdk': r'flutter', - }, - 'intl': r'any', - 'collection': r'any', - 'async': r'any', - 'meta': r'any', - 'path': r'any', - 'platform_info': r'^4.0.2', - 'win32': r'^5.0.6', - 'window_manager': r'^0.3.5', - 'l': r'^4.0.2', - 'spinify': { - 'path': r'../', - }, - 'cupertino_icons': r'^1.0.2', - }; - - /// Developer dependencies - static const Map devDependencies = { - 'flutter_test': { - 'sdk': r'flutter', - }, - 'integration_test': { - 'sdk': r'flutter', - }, - 'build_runner': r'^2.4.6', - 'pubspec_generator': r'>=4.0.0 <5.0.0', - 'flutter_lints': r'^2.0.1', - }; - - /// Dependency overrides - static const Map dependencyOverrides = {}; - - /// Executables - /// - /// Current app [executables] - /// - /// A package may expose one or more of its scripts as executables - /// that can be run directly from the command line. - /// To make a script publicly available, - /// list it under the executables field. - /// Entries are listed as key/value pairs: - /// - /// ```yaml - /// : - /// ``` - /// - /// For example, the following pubspec entry lists two scripts: - /// - /// ```yaml - /// executables: - /// slidy: main - /// fvm: - /// ``` - /// - /// Once the package is activated using pub global activate, - /// typing `slidy` executes `bin/main.dart`. - /// Typing `fvm` executes `bin/fvm.dart`. - /// If you don’t specify the value, it is inferred from the key. - /// - /// For more information, see pub global. - static const Map executables = {}; - - /// Source data from pubspec.yaml - static const Map source = { - 'name': name, - 'description': description, - 'repository': repository, - 'issue_tracker': issueTracker, - 'homepage': homepage, - 'documentation': documentation, - 'publish_to': publishTo, - 'version': version, - 'funding': funding, - 'false_secrets': falseSecrets, - 'screenshots': screenshots, - 'topics': topics, - 'platforms': platforms, - 'environment': environment, - 'dependencies': dependencies, - 'dev_dependencies': devDependencies, - 'dependency_overrides': dependencyOverrides, - 'flutter': { - 'generate': true, - 'uses-material-design': true, - }, - 'flutter_intl': { - 'enabled': true, - 'class_name': r'GeneratedLocalization', - 'main_locale': r'en', - 'arb_dir': r'lib/src/common/localization', - 'output_dir': r'lib/src/common/localization/generated', - 'use_deferred_loading': false, - }, - }; -} diff --git a/example/lib/src/common/controller/controller.dart b/example/lib/src/common/controller/controller.dart deleted file mode 100644 index 1864cbc..0000000 --- a/example/lib/src/common/controller/controller.dart +++ /dev/null @@ -1,77 +0,0 @@ -import 'dart:async'; - -import 'package:flutter/foundation.dart' show Listenable, ChangeNotifier; -import 'package:meta/meta.dart'; - -/// {@template controller} -/// The controller responsible for processing the logic, -/// the connection of widgets and the date of the layer. -/// {@endtemplate} -abstract interface class IController implements Listenable { - /// Whether the controller is currently handling a requests - bool get isProcessing; - - /// Discards any resources used by the object. - /// - /// This method should only be called by the object's owner. - void dispose(); -} - -/// Controller observer -abstract interface class IControllerObserver { - /// Called when the controller is created. - void onCreate(IController controller); - - /// Called when the controller is disposed. - void onDispose(IController controller); - - /// Called on any state change in the controller. - void onStateChanged( - IController controller, Object prevState, Object nextState); - - /// Called on any error in the controller. - void onError(IController controller, Object error, StackTrace stackTrace); -} - -/// {@macro controller} -abstract base class Controller with ChangeNotifier implements IController { - /// {@macro controller} - Controller() { - runZonedGuarded( - () => Controller.observer?.onCreate(this), - (error, stackTrace) {/* ignore */}, - ); - } - - /// Controller observer - static IControllerObserver? observer; - - /// Whether the controller is disposed. - bool get isDisposed => _$isDisposed; - bool _$isDisposed = false; - - @protected - void onError(Object error, StackTrace stackTrace) => runZonedGuarded( - () => Controller.observer?.onError(this, error, stackTrace), - (error, stackTrace) {/* ignore */}, - ); - - @protected - void handle(FutureOr Function() handler); - - @override - @mustCallSuper - void dispose() { - _$isDisposed = true; - runZonedGuarded( - () => Controller.observer?.onDispose(this), - (error, stackTrace) {/* ignore */}, - ); - super.dispose(); - } - - @protected - @nonVirtual - @override - void notifyListeners() => super.notifyListeners(); -} diff --git a/example/lib/src/common/controller/controller_observer.dart b/example/lib/src/common/controller/controller_observer.dart deleted file mode 100644 index f288068..0000000 --- a/example/lib/src/common/controller/controller_observer.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:l/l.dart'; -import 'package:spinifyapp/src/common/controller/controller.dart'; - -class ControllerObserver implements IControllerObserver { - @override - void onCreate(IController controller) { - l.v6('Controller | ${controller.runtimeType} | Created'); - } - - @override - void onDispose(IController controller) { - l.v5('Controller | ${controller.runtimeType} | Disposed'); - } - - @override - void onStateChanged( - IController controller, Object prevState, Object nextState) { - l.d('Controller | ${controller.runtimeType} | $prevState -> $nextState'); - } - - @override - void onError(IController controller, Object error, StackTrace stackTrace) { - l.w('Controller | ${controller.runtimeType} | $error', stackTrace); - } -} diff --git a/example/lib/src/common/controller/droppable_controller_concurrency.dart b/example/lib/src/common/controller/droppable_controller_concurrency.dart deleted file mode 100644 index a029f6b..0000000 --- a/example/lib/src/common/controller/droppable_controller_concurrency.dart +++ /dev/null @@ -1,40 +0,0 @@ -import 'dart:async'; - -import 'package:meta/meta.dart'; -import 'package:spinifyapp/src/common/controller/controller.dart'; - -base mixin DroppableControllerConcurrency on Controller { - @override - @nonVirtual - bool get isProcessing => _$processingCalls > 0; - int _$processingCalls = 0; - - @override - @protected - @mustCallSuper - void handle( - FutureOr Function() handler, [ - FutureOr Function(Object error, StackTrace stackTrace)? errorHandler, - FutureOr Function()? doneHandler, - ]) => - runZonedGuarded( - () async { - if (isDisposed || isProcessing) return; - _$processingCalls++; - try { - await handler(); - } on Object catch (error, stackTrace) { - onError(error, stackTrace); - await Future(() async { - await errorHandler?.call(error, stackTrace); - }).catchError(onError); - } finally { - await Future(() async { - await doneHandler?.call(); - }).catchError(onError); - _$processingCalls--; - } - }, - onError, - ); -} diff --git a/example/lib/src/common/controller/sequential_controller_concurrency.dart b/example/lib/src/common/controller/sequential_controller_concurrency.dart deleted file mode 100644 index 25abf47..0000000 --- a/example/lib/src/common/controller/sequential_controller_concurrency.dart +++ /dev/null @@ -1,124 +0,0 @@ -import 'dart:async'; -import 'dart:collection'; - -import 'package:meta/meta.dart'; -import 'package:spinifyapp/src/common/controller/controller.dart'; - -base mixin SequentialControllerConcurrency on Controller { - final _ControllerEventQueue _eventQueue = _ControllerEventQueue(); - - @override - @nonVirtual - bool get isProcessing => _eventQueue.length > 0; - - @override - @protected - @mustCallSuper - void handle( - FutureOr Function() handler, [ - FutureOr Function(Object error, StackTrace stackTrace)? errorHandler, - FutureOr Function()? doneHandler, - ]) => - _eventQueue.push( - () { - final completer = Completer(); - runZonedGuarded( - () async { - if (isDisposed) return; - try { - await handler(); - } on Object catch (error, stackTrace) { - onError(error, stackTrace); - await Future(() async { - await errorHandler?.call(error, stackTrace); - }).catchError(onError); - } finally { - await Future(() async { - await doneHandler?.call(); - }).catchError(onError); - completer.complete(); - } - }, - onError, - ); - return completer.future; - }, - ); -} - -final class _ControllerEventQueue { - _ControllerEventQueue(); - - final DoubleLinkedQueue<_SequentialTask> _queue = - DoubleLinkedQueue<_SequentialTask>(); - Future? _processing; - bool _isClosed = false; - - /// Event queue length. - int get length => _queue.length; - - /// Push it at the end of the queue. - Future push(FutureOr Function() fn) { - final task = _SequentialTask(fn); - _queue.add(task); - _exec(); - return task.future; - } - - /// Mark the queue as closed. - /// The queue will be processed until it's empty. - /// But all new and current events will be rejected with [WSClientClosed]. - FutureOr close() async { - _isClosed = true; - await _processing; - } - - /// Execute the queue. - void _exec() => _processing ??= Future.doWhile(() async { - final event = _queue.first; - try { - if (_isClosed) { - event.reject(StateError('Controller\'s event queue are disposed'), - StackTrace.current); - } else { - await event(); - } - } on Object catch (error, stackTrace) { - /* warning( - error, - stackTrace, - 'Error while processing event "${event.id}"', - ); */ - Future.sync(() => event.reject(error, stackTrace)).ignore(); - } - _queue.removeFirst(); - final isEmpty = _queue.isEmpty; - if (isEmpty) _processing = null; - return !isEmpty; - }); -} - -class _SequentialTask { - _SequentialTask(FutureOr Function() fn) - : _fn = fn, - _completer = Completer(); - - final Completer _completer; - - final FutureOr Function() _fn; - - Future get future => _completer.future; - - FutureOr call() async { - final result = await _fn(); - if (!_completer.isCompleted) { - _completer.complete(result); - } - return result; - } - - void reject(Object error, [StackTrace? stackTrace]) { - if (_completer.isCompleted) return; - _completer.completeError(error, stackTrace); - } -} diff --git a/example/lib/src/common/controller/state_consumer.dart b/example/lib/src/common/controller/state_consumer.dart deleted file mode 100644 index ad366a2..0000000 --- a/example/lib/src/common/controller/state_consumer.dart +++ /dev/null @@ -1,129 +0,0 @@ -import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/scheduler.dart'; -import 'package:spinifyapp/src/common/controller/state_controller.dart'; - -/// Fire when the state changes. -typedef StateConsumerListener = void Function( - BuildContext context, S previous, S current); - -/// Build when the method returns true. -typedef StateConsumerCondition = bool Function(S previous, S current); - -/// Rebuild the widget when the state changes. -typedef StateConsumerBuilder = Widget Function( - BuildContext context, S state, Widget? child); - -/// {@template state_consumer} -/// StateBuilder widget. -/// {@endtemplate} -class StateConsumer extends StatefulWidget { - /// {@macro state_builder} - const StateConsumer({ - required this.controller, - this.listener, - this.buildWhen, - this.builder, - this.child, - super.key, - }); - - /// The controller responsible for processing the logic, - final IStateController controller; - - /// Takes the `BuildContext` along with the `state` - /// and is responsible for executing in response to `state` changes. - final StateConsumerListener? listener; - - /// Takes the previous `state` and the current `state` and is responsible for - /// returning a [bool] which determines whether or not to trigger - /// [builder] with the current `state`. - final StateConsumerCondition? buildWhen; - - /// The [builder] function which will be invoked on each widget build. - /// The [builder] takes the `BuildContext` and current `state` and - /// must return a widget. - /// This is analogous to the [builder] function in [StreamBuilder]. - final StateConsumerBuilder? builder; - - /// The child widget which will be passed to the [builder]. - final Widget? child; - - @override - State> createState() => _StateConsumerState(); -} - -class _StateConsumerState extends State> { - late IStateController _controller; - late S _previousState; - - @override - void initState() { - super.initState(); - _controller = widget.controller; - _previousState = _controller.state; - _subscribe(); - } - - @override - void didUpdateWidget(StateConsumer oldWidget) { - super.didUpdateWidget(oldWidget); - final oldController = oldWidget.controller, - newController = widget.controller; - if (identical(oldController, newController) || - oldController == newController) return; - _unsubscribe(); - _controller = newController; - _previousState = newController.state; - _subscribe(); - } - - @override - void dispose() { - _unsubscribe(); - super.dispose(); - } - - void _subscribe() => _controller.addListener(_valueChanged); - - void _unsubscribe() => _controller.removeListener(_valueChanged); - - void _valueChanged() { - final oldState = _previousState, newState = _controller.state; - if (!mounted || identical(oldState, newState)) return; - _previousState = newState; - widget.listener?.call(context, oldState, newState); - if (widget.buildWhen?.call(oldState, newState) ?? true) { - // Rebuild the widget when the state changes. - switch (SchedulerBinding.instance.schedulerPhase) { - case SchedulerPhase.idle: - case SchedulerPhase.transientCallbacks: - case SchedulerPhase.postFrameCallbacks: - setState(() {}); - case SchedulerPhase.persistentCallbacks: - case SchedulerPhase.midFrameMicrotasks: - SchedulerBinding.instance.addPostFrameCallback((_) { - if (!mounted) return; - setState(() {}); - }); - } - } - } - - @override - void debugFillProperties(DiagnosticPropertiesBuilder properties) => - super.debugFillProperties(properties - ..add( - DiagnosticsProperty>('Controller', _controller)) - ..add(DiagnosticsProperty('State', _controller.state)) - ..add(FlagProperty('isProcessing', - value: _controller.isProcessing, - ifTrue: 'Processing', - ifFalse: 'Idle'))); - - @override - Widget build(BuildContext context) => - widget.builder?.call(context, _controller.state, widget.child) ?? - widget.child ?? - const SizedBox.shrink(); -} diff --git a/example/lib/src/common/controller/state_controller.dart b/example/lib/src/common/controller/state_controller.dart deleted file mode 100644 index e6dcc64..0000000 --- a/example/lib/src/common/controller/state_controller.dart +++ /dev/null @@ -1,35 +0,0 @@ -import 'dart:async'; - -import 'package:flutter/foundation.dart'; -import 'package:spinifyapp/src/common/controller/controller.dart'; - -/// State controller -abstract interface class IStateController - implements IController { - /// The current state of the controller. - State get state; -} - -/// State controller -abstract base class StateController extends Controller - implements IStateController { - /// State controller - StateController({required State initialState}) : _$state = initialState; - - @override - @nonVirtual - State get state => _$state; - State _$state; - - @protected - @nonVirtual - void setState(State state) { - runZonedGuarded( - () => Controller.observer?.onStateChanged(this, _$state, state), - (error, stackTrace) {/* ignore */}, - ); - _$state = state; - if (isDisposed) return; - notifyListeners(); - } -} diff --git a/example/lib/src/common/localization/generated/intl/messages_all.dart b/example/lib/src/common/localization/generated/intl/messages_all.dart deleted file mode 100644 index 203415c..0000000 --- a/example/lib/src/common/localization/generated/intl/messages_all.dart +++ /dev/null @@ -1,63 +0,0 @@ -// DO NOT EDIT. This is code generated via package:intl/generate_localized.dart -// This is a library that looks up messages for specific locales by -// delegating to the appropriate library. - -// Ignore issues from commonly used lints in this file. -// ignore_for_file:implementation_imports, file_names, unnecessary_new -// ignore_for_file:unnecessary_brace_in_string_interps, directives_ordering -// ignore_for_file:argument_type_not_assignable, invalid_assignment -// ignore_for_file:prefer_single_quotes, prefer_generic_function_type_aliases -// ignore_for_file:comment_references - -import 'dart:async'; - -import 'package:flutter/foundation.dart'; -import 'package:intl/intl.dart'; -import 'package:intl/message_lookup_by_library.dart'; -import 'package:intl/src/intl_helpers.dart'; - -import 'messages_en.dart' as messages_en; - -typedef Future LibraryLoader(); -Map _deferredLibraries = { - 'en': () => new SynchronousFuture(null), -}; - -MessageLookupByLibrary? _findExact(String localeName) { - switch (localeName) { - case 'en': - return messages_en.messages; - default: - return null; - } -} - -/// User programs should call this before using [localeName] for messages. -Future initializeMessages(String localeName) { - var availableLocale = Intl.verifiedLocale( - localeName, (locale) => _deferredLibraries[locale] != null, - onFailure: (_) => null); - if (availableLocale == null) { - return new SynchronousFuture(false); - } - var lib = _deferredLibraries[availableLocale]; - lib == null ? new SynchronousFuture(false) : lib(); - initializeInternalMessageLookup(() => new CompositeMessageLookup()); - messageLookup.addLocale(availableLocale, _findGeneratedMessagesFor); - return new SynchronousFuture(true); -} - -bool _messagesExistFor(String locale) { - try { - return _findExact(locale) != null; - } catch (e) { - return false; - } -} - -MessageLookupByLibrary? _findGeneratedMessagesFor(String locale) { - var actualLocale = - Intl.verifiedLocale(locale, _messagesExistFor, onFailure: (_) => null); - if (actualLocale == null) return null; - return _findExact(actualLocale); -} diff --git a/example/lib/src/common/localization/generated/intl/messages_en.dart b/example/lib/src/common/localization/generated/intl/messages_en.dart deleted file mode 100644 index f998a81..0000000 --- a/example/lib/src/common/localization/generated/intl/messages_en.dart +++ /dev/null @@ -1,154 +0,0 @@ -// DO NOT EDIT. This is code generated via package:intl/generate_localized.dart -// This is a library that provides messages for a en locale. All the -// messages from the main program should be duplicated here with the same -// function name. - -// Ignore issues from commonly used lints in this file. -// ignore_for_file:unnecessary_brace_in_string_interps, unnecessary_new -// ignore_for_file:prefer_single_quotes,comment_references, directives_ordering -// ignore_for_file:annotate_overrides,prefer_generic_function_type_aliases -// ignore_for_file:unused_import, file_names, avoid_escaping_inner_quotes -// ignore_for_file:unnecessary_string_interpolations, unnecessary_string_escapes - -import 'package:intl/intl.dart'; -import 'package:intl/message_lookup_by_library.dart'; - -final messages = new MessageLookup(); - -typedef String MessageIfAbsent(String messageStr, List args); - -class MessageLookup extends MessageLookupByLibrary { - String get localeName => 'en'; - - final messages = _notInlinedMessages(_notInlinedMessages); - static Map _notInlinedMessages(_) => { - "addButton": MessageLookupByLibrary.simpleMessage("Add"), - "addToStarredButton": - MessageLookupByLibrary.simpleMessage("Add to starred"), - "apiDomain": MessageLookupByLibrary.simpleMessage("API domain"), - "appLabel": MessageLookupByLibrary.simpleMessage("App"), - "applicationInformationLabel": - MessageLookupByLibrary.simpleMessage("Application information"), - "applicationLabel": MessageLookupByLibrary.simpleMessage("Application"), - "applicationVersionLabel": - MessageLookupByLibrary.simpleMessage("Application version"), - "authenticateLabel": - MessageLookupByLibrary.simpleMessage("Authenticate"), - "authenticatedLabel": - MessageLookupByLibrary.simpleMessage("Authenticated"), - "authenticationLabel": - MessageLookupByLibrary.simpleMessage("Authentication"), - "backButton": MessageLookupByLibrary.simpleMessage("Back"), - "cancelButton": MessageLookupByLibrary.simpleMessage("Cancel"), - "conectedDevicesLabel": - MessageLookupByLibrary.simpleMessage("Connected devices"), - "confirmButton": MessageLookupByLibrary.simpleMessage("Confirm"), - "continueButton": MessageLookupByLibrary.simpleMessage("Continue"), - "copiedLabel": MessageLookupByLibrary.simpleMessage("Copied"), - "copyButton": MessageLookupByLibrary.simpleMessage("Copy"), - "createButton": MessageLookupByLibrary.simpleMessage("Create"), - "currentLabel": MessageLookupByLibrary.simpleMessage("Current"), - "currentUserLabel": - MessageLookupByLibrary.simpleMessage("Current user"), - "currentVersionLabel": - MessageLookupByLibrary.simpleMessage("Current version"), - "databaseLabel": MessageLookupByLibrary.simpleMessage("Database"), - "dateLabel": MessageLookupByLibrary.simpleMessage("Date"), - "deleteButton": MessageLookupByLibrary.simpleMessage("Delete"), - "downloadButton": MessageLookupByLibrary.simpleMessage("Download"), - "editButton": MessageLookupByLibrary.simpleMessage("Edit"), - "emailLabel": MessageLookupByLibrary.simpleMessage("Email"), - "errAnErrorHasOccurred": - MessageLookupByLibrary.simpleMessage("An error has occurred"), - "errAnExceptionHasOccurred": - MessageLookupByLibrary.simpleMessage("An exception has occurred"), - "errAnUnknownErrorWasReceivedFromTheServer": - MessageLookupByLibrary.simpleMessage( - "An unknown error was received from the server"), - "errAssertionError": - MessageLookupByLibrary.simpleMessage("Assertion error"), - "errBadGateway": MessageLookupByLibrary.simpleMessage("Bad gateway"), - "errBadRequest": MessageLookupByLibrary.simpleMessage("Bad request"), - "errBadStateError": - MessageLookupByLibrary.simpleMessage("Bad state error"), - "errError": MessageLookupByLibrary.simpleMessage("Error"), - "errException": MessageLookupByLibrary.simpleMessage("Exception"), - "errFileSystemException": - MessageLookupByLibrary.simpleMessage("File system error"), - "errForbidden": MessageLookupByLibrary.simpleMessage("Forbidden"), - "errGatewayTimeout": - MessageLookupByLibrary.simpleMessage("Gateway timeout"), - "errInternalServerError": - MessageLookupByLibrary.simpleMessage("Internal server error"), - "errInvalidCredentials": - MessageLookupByLibrary.simpleMessage("Invalid credentials"), - "errInvalidFormat": - MessageLookupByLibrary.simpleMessage("Invalid format"), - "errNotAcceptable": - MessageLookupByLibrary.simpleMessage("Not acceptable"), - "errNotFound": MessageLookupByLibrary.simpleMessage("Not found"), - "errNotImplementedYet": - MessageLookupByLibrary.simpleMessage("Not implemented yet"), - "errRequestTimeout": - MessageLookupByLibrary.simpleMessage("Request timeout"), - "errServiceUnavailable": - MessageLookupByLibrary.simpleMessage("Service unavailable"), - "errSomethingWentWrong": - MessageLookupByLibrary.simpleMessage("Something went wrong"), - "errTimeOutExceeded": - MessageLookupByLibrary.simpleMessage("Time out exceeded"), - "errTooManyRequests": - MessageLookupByLibrary.simpleMessage("Too many requests"), - "errTryAgainLater": - MessageLookupByLibrary.simpleMessage("Please try again later."), - "errUnauthorized": MessageLookupByLibrary.simpleMessage("Unauthorized"), - "errUnimplemented": - MessageLookupByLibrary.simpleMessage("Unimplemented"), - "errUnknownServerError": - MessageLookupByLibrary.simpleMessage("Unknown server error"), - "errUnsupportedOperation": - MessageLookupByLibrary.simpleMessage("Unsupported operation"), - "exitButton": MessageLookupByLibrary.simpleMessage("Exit"), - "helpLabel": MessageLookupByLibrary.simpleMessage("Help"), - "language": MessageLookupByLibrary.simpleMessage("English"), - "languageCode": MessageLookupByLibrary.simpleMessage("en"), - "languageSelectionLabel": - MessageLookupByLibrary.simpleMessage("Language selection"), - "latestVersionLabel": - MessageLookupByLibrary.simpleMessage("Latest version"), - "localeName": MessageLookupByLibrary.simpleMessage("en_US"), - "logInButton": MessageLookupByLibrary.simpleMessage("Log In"), - "logOutButton": MessageLookupByLibrary.simpleMessage("Log Out"), - "logOutDescription": MessageLookupByLibrary.simpleMessage( - "You will be logged out from your account"), - "moveButton": MessageLookupByLibrary.simpleMessage("Move"), - "moveToTrashButton": - MessageLookupByLibrary.simpleMessage("Move to trash"), - "nameLabel": MessageLookupByLibrary.simpleMessage("Name"), - "navigationLabel": MessageLookupByLibrary.simpleMessage("Navigation"), - "removeFromStarredButton": - MessageLookupByLibrary.simpleMessage("Remove from starred"), - "renameButton": MessageLookupByLibrary.simpleMessage("Rename"), - "renewalDateLabel": - MessageLookupByLibrary.simpleMessage("Renewal date"), - "restoreButton": MessageLookupByLibrary.simpleMessage("Restore"), - "saveButton": MessageLookupByLibrary.simpleMessage("Save"), - "selectedLabel": MessageLookupByLibrary.simpleMessage("Selected"), - "shareButton": MessageLookupByLibrary.simpleMessage("Share"), - "shareLinkButton": MessageLookupByLibrary.simpleMessage("Share link"), - "signInButton": MessageLookupByLibrary.simpleMessage("Sign In"), - "signUpButton": MessageLookupByLibrary.simpleMessage("Sign Up"), - "sizeLabel": MessageLookupByLibrary.simpleMessage("Size"), - "statusLabel": MessageLookupByLibrary.simpleMessage("Status"), - "storageLabel": MessageLookupByLibrary.simpleMessage("Storage"), - "surnameLabel": MessageLookupByLibrary.simpleMessage("Surname"), - "timeLabel": MessageLookupByLibrary.simpleMessage("Time"), - "title": MessageLookupByLibrary.simpleMessage("Spinify"), - "typeLabel": MessageLookupByLibrary.simpleMessage("Type"), - "upgradeLabel": MessageLookupByLibrary.simpleMessage("Upgrade"), - "uploadButton": MessageLookupByLibrary.simpleMessage("Upload"), - "usefulLinksLabel": - MessageLookupByLibrary.simpleMessage("Useful links"), - "versionLabel": MessageLookupByLibrary.simpleMessage("Version") - }; -} diff --git a/example/lib/src/common/localization/generated/l10n.dart b/example/lib/src/common/localization/generated/l10n.dart deleted file mode 100644 index 507d46d..0000000 --- a/example/lib/src/common/localization/generated/l10n.dart +++ /dev/null @@ -1,981 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND -import 'package:flutter/material.dart'; -import 'package:intl/intl.dart'; -import 'intl/messages_all.dart'; - -// ************************************************************************** -// Generator: Flutter Intl IDE plugin -// Made by Localizely -// ************************************************************************** - -// ignore_for_file: non_constant_identifier_names, lines_longer_than_80_chars -// ignore_for_file: join_return_with_assignment, prefer_final_in_for_each -// ignore_for_file: avoid_redundant_argument_values, avoid_escaping_inner_quotes - -class GeneratedLocalization { - GeneratedLocalization(); - - static GeneratedLocalization? _current; - - static GeneratedLocalization get current { - assert(_current != null, - 'No instance of GeneratedLocalization was loaded. Try to initialize the GeneratedLocalization delegate before accessing GeneratedLocalization.current.'); - return _current!; - } - - static const AppLocalizationDelegate delegate = AppLocalizationDelegate(); - - static Future load(Locale locale) { - final name = (locale.countryCode?.isEmpty ?? false) - ? locale.languageCode - : locale.toString(); - final localeName = Intl.canonicalizedLocale(name); - return initializeMessages(localeName).then((_) { - Intl.defaultLocale = localeName; - final instance = GeneratedLocalization(); - GeneratedLocalization._current = instance; - - return instance; - }); - } - - static GeneratedLocalization of(BuildContext context) { - final instance = GeneratedLocalization.maybeOf(context); - assert(instance != null, - 'No instance of GeneratedLocalization present in the widget tree. Did you add GeneratedLocalization.delegate in localizationsDelegates?'); - return instance!; - } - - static GeneratedLocalization? maybeOf(BuildContext context) { - return Localizations.of( - context, GeneratedLocalization); - } - - /// `en_US` - String get localeName { - return Intl.message( - 'en_US', - name: 'localeName', - desc: '', - args: [], - ); - } - - /// `en` - String get languageCode { - return Intl.message( - 'en', - name: 'languageCode', - desc: '', - args: [], - ); - } - - /// `English` - String get language { - return Intl.message( - 'English', - name: 'language', - desc: '', - args: [], - ); - } - - /// `Spinify` - String get title { - return Intl.message( - 'Spinify', - name: 'title', - desc: '', - args: [], - ); - } - - /// `Something went wrong` - String get errSomethingWentWrong { - return Intl.message( - 'Something went wrong', - name: 'errSomethingWentWrong', - desc: '', - args: [], - ); - } - - /// `Error` - String get errError { - return Intl.message( - 'Error', - name: 'errError', - desc: '', - args: [], - ); - } - - /// `Exception` - String get errException { - return Intl.message( - 'Exception', - name: 'errException', - desc: '', - args: [], - ); - } - - /// `An error has occurred` - String get errAnErrorHasOccurred { - return Intl.message( - 'An error has occurred', - name: 'errAnErrorHasOccurred', - desc: '', - args: [], - ); - } - - /// `An exception has occurred` - String get errAnExceptionHasOccurred { - return Intl.message( - 'An exception has occurred', - name: 'errAnExceptionHasOccurred', - desc: '', - args: [], - ); - } - - /// `Please try again later.` - String get errTryAgainLater { - return Intl.message( - 'Please try again later.', - name: 'errTryAgainLater', - desc: '', - args: [], - ); - } - - /// `Invalid format` - String get errInvalidFormat { - return Intl.message( - 'Invalid format', - name: 'errInvalidFormat', - desc: '', - args: [], - ); - } - - /// `Time out exceeded` - String get errTimeOutExceeded { - return Intl.message( - 'Time out exceeded', - name: 'errTimeOutExceeded', - desc: '', - args: [], - ); - } - - /// `Invalid credentials` - String get errInvalidCredentials { - return Intl.message( - 'Invalid credentials', - name: 'errInvalidCredentials', - desc: '', - args: [], - ); - } - - /// `Unimplemented` - String get errUnimplemented { - return Intl.message( - 'Unimplemented', - name: 'errUnimplemented', - desc: '', - args: [], - ); - } - - /// `Not implemented yet` - String get errNotImplementedYet { - return Intl.message( - 'Not implemented yet', - name: 'errNotImplementedYet', - desc: '', - args: [], - ); - } - - /// `Unsupported operation` - String get errUnsupportedOperation { - return Intl.message( - 'Unsupported operation', - name: 'errUnsupportedOperation', - desc: '', - args: [], - ); - } - - /// `File system error` - String get errFileSystemException { - return Intl.message( - 'File system error', - name: 'errFileSystemException', - desc: '', - args: [], - ); - } - - /// `Assertion error` - String get errAssertionError { - return Intl.message( - 'Assertion error', - name: 'errAssertionError', - desc: '', - args: [], - ); - } - - /// `Bad state error` - String get errBadStateError { - return Intl.message( - 'Bad state error', - name: 'errBadStateError', - desc: '', - args: [], - ); - } - - /// `Bad request` - String get errBadRequest { - return Intl.message( - 'Bad request', - name: 'errBadRequest', - desc: '', - args: [], - ); - } - - /// `Unauthorized` - String get errUnauthorized { - return Intl.message( - 'Unauthorized', - name: 'errUnauthorized', - desc: '', - args: [], - ); - } - - /// `Forbidden` - String get errForbidden { - return Intl.message( - 'Forbidden', - name: 'errForbidden', - desc: '', - args: [], - ); - } - - /// `Not found` - String get errNotFound { - return Intl.message( - 'Not found', - name: 'errNotFound', - desc: '', - args: [], - ); - } - - /// `Not acceptable` - String get errNotAcceptable { - return Intl.message( - 'Not acceptable', - name: 'errNotAcceptable', - desc: '', - args: [], - ); - } - - /// `Request timeout` - String get errRequestTimeout { - return Intl.message( - 'Request timeout', - name: 'errRequestTimeout', - desc: '', - args: [], - ); - } - - /// `Too many requests` - String get errTooManyRequests { - return Intl.message( - 'Too many requests', - name: 'errTooManyRequests', - desc: '', - args: [], - ); - } - - /// `Internal server error` - String get errInternalServerError { - return Intl.message( - 'Internal server error', - name: 'errInternalServerError', - desc: '', - args: [], - ); - } - - /// `Bad gateway` - String get errBadGateway { - return Intl.message( - 'Bad gateway', - name: 'errBadGateway', - desc: '', - args: [], - ); - } - - /// `Service unavailable` - String get errServiceUnavailable { - return Intl.message( - 'Service unavailable', - name: 'errServiceUnavailable', - desc: '', - args: [], - ); - } - - /// `Gateway timeout` - String get errGatewayTimeout { - return Intl.message( - 'Gateway timeout', - name: 'errGatewayTimeout', - desc: '', - args: [], - ); - } - - /// `Unknown server error` - String get errUnknownServerError { - return Intl.message( - 'Unknown server error', - name: 'errUnknownServerError', - desc: '', - args: [], - ); - } - - /// `An unknown error was received from the server` - String get errAnUnknownErrorWasReceivedFromTheServer { - return Intl.message( - 'An unknown error was received from the server', - name: 'errAnUnknownErrorWasReceivedFromTheServer', - desc: '', - args: [], - ); - } - - /// `Log Out` - String get logOutButton { - return Intl.message( - 'Log Out', - name: 'logOutButton', - desc: '', - args: [], - ); - } - - /// `Log In` - String get logInButton { - return Intl.message( - 'Log In', - name: 'logInButton', - desc: '', - args: [], - ); - } - - /// `Exit` - String get exitButton { - return Intl.message( - 'Exit', - name: 'exitButton', - desc: '', - args: [], - ); - } - - /// `Sign Up` - String get signUpButton { - return Intl.message( - 'Sign Up', - name: 'signUpButton', - desc: '', - args: [], - ); - } - - /// `Sign In` - String get signInButton { - return Intl.message( - 'Sign In', - name: 'signInButton', - desc: '', - args: [], - ); - } - - /// `Back` - String get backButton { - return Intl.message( - 'Back', - name: 'backButton', - desc: '', - args: [], - ); - } - - /// `Cancel` - String get cancelButton { - return Intl.message( - 'Cancel', - name: 'cancelButton', - desc: '', - args: [], - ); - } - - /// `Confirm` - String get confirmButton { - return Intl.message( - 'Confirm', - name: 'confirmButton', - desc: '', - args: [], - ); - } - - /// `Continue` - String get continueButton { - return Intl.message( - 'Continue', - name: 'continueButton', - desc: '', - args: [], - ); - } - - /// `Save` - String get saveButton { - return Intl.message( - 'Save', - name: 'saveButton', - desc: '', - args: [], - ); - } - - /// `Create` - String get createButton { - return Intl.message( - 'Create', - name: 'createButton', - desc: '', - args: [], - ); - } - - /// `Delete` - String get deleteButton { - return Intl.message( - 'Delete', - name: 'deleteButton', - desc: '', - args: [], - ); - } - - /// `Edit` - String get editButton { - return Intl.message( - 'Edit', - name: 'editButton', - desc: '', - args: [], - ); - } - - /// `Add` - String get addButton { - return Intl.message( - 'Add', - name: 'addButton', - desc: '', - args: [], - ); - } - - /// `Copy` - String get copyButton { - return Intl.message( - 'Copy', - name: 'copyButton', - desc: '', - args: [], - ); - } - - /// `Move` - String get moveButton { - return Intl.message( - 'Move', - name: 'moveButton', - desc: '', - args: [], - ); - } - - /// `Rename` - String get renameButton { - return Intl.message( - 'Rename', - name: 'renameButton', - desc: '', - args: [], - ); - } - - /// `Upload` - String get uploadButton { - return Intl.message( - 'Upload', - name: 'uploadButton', - desc: '', - args: [], - ); - } - - /// `Download` - String get downloadButton { - return Intl.message( - 'Download', - name: 'downloadButton', - desc: '', - args: [], - ); - } - - /// `Share` - String get shareButton { - return Intl.message( - 'Share', - name: 'shareButton', - desc: '', - args: [], - ); - } - - /// `Share link` - String get shareLinkButton { - return Intl.message( - 'Share link', - name: 'shareLinkButton', - desc: '', - args: [], - ); - } - - /// `Remove from starred` - String get removeFromStarredButton { - return Intl.message( - 'Remove from starred', - name: 'removeFromStarredButton', - desc: '', - args: [], - ); - } - - /// `Add to starred` - String get addToStarredButton { - return Intl.message( - 'Add to starred', - name: 'addToStarredButton', - desc: '', - args: [], - ); - } - - /// `Move to trash` - String get moveToTrashButton { - return Intl.message( - 'Move to trash', - name: 'moveToTrashButton', - desc: '', - args: [], - ); - } - - /// `Restore` - String get restoreButton { - return Intl.message( - 'Restore', - name: 'restoreButton', - desc: '', - args: [], - ); - } - - /// `Email` - String get emailLabel { - return Intl.message( - 'Email', - name: 'emailLabel', - desc: '', - args: [], - ); - } - - /// `Name` - String get nameLabel { - return Intl.message( - 'Name', - name: 'nameLabel', - desc: '', - args: [], - ); - } - - /// `Surname` - String get surnameLabel { - return Intl.message( - 'Surname', - name: 'surnameLabel', - desc: '', - args: [], - ); - } - - /// `Language selection` - String get languageSelectionLabel { - return Intl.message( - 'Language selection', - name: 'languageSelectionLabel', - desc: '', - args: [], - ); - } - - /// `Upgrade` - String get upgradeLabel { - return Intl.message( - 'Upgrade', - name: 'upgradeLabel', - desc: '', - args: [], - ); - } - - /// `App` - String get appLabel { - return Intl.message( - 'App', - name: 'appLabel', - desc: '', - args: [], - ); - } - - /// `Application` - String get applicationLabel { - return Intl.message( - 'Application', - name: 'applicationLabel', - desc: '', - args: [], - ); - } - - /// `Authenticate` - String get authenticateLabel { - return Intl.message( - 'Authenticate', - name: 'authenticateLabel', - desc: '', - args: [], - ); - } - - /// `Authenticated` - String get authenticatedLabel { - return Intl.message( - 'Authenticated', - name: 'authenticatedLabel', - desc: '', - args: [], - ); - } - - /// `Authentication` - String get authenticationLabel { - return Intl.message( - 'Authentication', - name: 'authenticationLabel', - desc: '', - args: [], - ); - } - - /// `Navigation` - String get navigationLabel { - return Intl.message( - 'Navigation', - name: 'navigationLabel', - desc: '', - args: [], - ); - } - - /// `Database` - String get databaseLabel { - return Intl.message( - 'Database', - name: 'databaseLabel', - desc: '', - args: [], - ); - } - - /// `Copied` - String get copiedLabel { - return Intl.message( - 'Copied', - name: 'copiedLabel', - desc: '', - args: [], - ); - } - - /// `Useful links` - String get usefulLinksLabel { - return Intl.message( - 'Useful links', - name: 'usefulLinksLabel', - desc: '', - args: [], - ); - } - - /// `Current version` - String get currentVersionLabel { - return Intl.message( - 'Current version', - name: 'currentVersionLabel', - desc: '', - args: [], - ); - } - - /// `Latest version` - String get latestVersionLabel { - return Intl.message( - 'Latest version', - name: 'latestVersionLabel', - desc: '', - args: [], - ); - } - - /// `Version` - String get versionLabel { - return Intl.message( - 'Version', - name: 'versionLabel', - desc: '', - args: [], - ); - } - - /// `Size` - String get sizeLabel { - return Intl.message( - 'Size', - name: 'sizeLabel', - desc: '', - args: [], - ); - } - - /// `Type` - String get typeLabel { - return Intl.message( - 'Type', - name: 'typeLabel', - desc: '', - args: [], - ); - } - - /// `Date` - String get dateLabel { - return Intl.message( - 'Date', - name: 'dateLabel', - desc: '', - args: [], - ); - } - - /// `Time` - String get timeLabel { - return Intl.message( - 'Time', - name: 'timeLabel', - desc: '', - args: [], - ); - } - - /// `Status` - String get statusLabel { - return Intl.message( - 'Status', - name: 'statusLabel', - desc: '', - args: [], - ); - } - - /// `Current` - String get currentLabel { - return Intl.message( - 'Current', - name: 'currentLabel', - desc: '', - args: [], - ); - } - - /// `Current user` - String get currentUserLabel { - return Intl.message( - 'Current user', - name: 'currentUserLabel', - desc: '', - args: [], - ); - } - - /// `Application version` - String get applicationVersionLabel { - return Intl.message( - 'Application version', - name: 'applicationVersionLabel', - desc: '', - args: [], - ); - } - - /// `Application information` - String get applicationInformationLabel { - return Intl.message( - 'Application information', - name: 'applicationInformationLabel', - desc: '', - args: [], - ); - } - - /// `Connected devices` - String get conectedDevicesLabel { - return Intl.message( - 'Connected devices', - name: 'conectedDevicesLabel', - desc: '', - args: [], - ); - } - - /// `Renewal date` - String get renewalDateLabel { - return Intl.message( - 'Renewal date', - name: 'renewalDateLabel', - desc: '', - args: [], - ); - } - - /// `API domain` - String get apiDomain { - return Intl.message( - 'API domain', - name: 'apiDomain', - desc: '', - args: [], - ); - } - - /// `Storage` - String get storageLabel { - return Intl.message( - 'Storage', - name: 'storageLabel', - desc: '', - args: [], - ); - } - - /// `Help` - String get helpLabel { - return Intl.message( - 'Help', - name: 'helpLabel', - desc: '', - args: [], - ); - } - - /// `Selected` - String get selectedLabel { - return Intl.message( - 'Selected', - name: 'selectedLabel', - desc: '', - args: [], - ); - } - - /// `You will be logged out from your account` - String get logOutDescription { - return Intl.message( - 'You will be logged out from your account', - name: 'logOutDescription', - desc: '', - args: [], - ); - } -} - -class AppLocalizationDelegate - extends LocalizationsDelegate { - const AppLocalizationDelegate(); - - List get supportedLocales { - return const [ - Locale.fromSubtags(languageCode: 'en'), - ]; - } - - @override - bool isSupported(Locale locale) => _isSupported(locale); - @override - Future load(Locale locale) => - GeneratedLocalization.load(locale); - @override - bool shouldReload(AppLocalizationDelegate old) => false; - - bool _isSupported(Locale locale) { - for (var supportedLocale in supportedLocales) { - if (supportedLocale.languageCode == locale.languageCode) { - return true; - } - } - return false; - } -} diff --git a/example/lib/src/common/localization/intl_en.arb b/example/lib/src/common/localization/intl_en.arb deleted file mode 100644 index 9ab5962..0000000 --- a/example/lib/src/common/localization/intl_en.arb +++ /dev/null @@ -1,98 +0,0 @@ -{ - "@@locale": "en", - "localeName": "en_US", - "languageCode": "en", - "language": "English", - "@ Title": {}, - "title": "Spinify", - "@ ############# Errors #############": {}, - "errSomethingWentWrong": "Something went wrong", - "errError": "Error", - "errException": "Exception", - "errAnErrorHasOccurred": "An error has occurred", - "errAnExceptionHasOccurred": "An exception has occurred", - "errTryAgainLater": "Please try again later.", - "errInvalidFormat": "Invalid format", - "errTimeOutExceeded": "Time out exceeded", - "errInvalidCredentials": "Invalid credentials", - "errUnimplemented": "Unimplemented", - "errNotImplementedYet": "Not implemented yet", - "errUnsupportedOperation": "Unsupported operation", - "errFileSystemException": "File system error", - "errAssertionError": "Assertion error", - "errBadStateError": "Bad state error", - "errBadRequest": "Bad request", - "errUnauthorized": "Unauthorized", - "errForbidden": "Forbidden", - "errNotFound": "Not found", - "errNotAcceptable": "Not acceptable", - "errRequestTimeout": "Request timeout", - "errTooManyRequests": "Too many requests", - "errInternalServerError": "Internal server error", - "errBadGateway": "Bad gateway", - "errServiceUnavailable": "Service unavailable", - "errGatewayTimeout": "Gateway timeout", - "errUnknownServerError": "Unknown server error", - "errAnUnknownErrorWasReceivedFromTheServer": "An unknown error was received from the server", - "@ ############# Buttons #############": {}, - "logOutButton": "Log Out", - "logInButton": "Log In", - "exitButton": "Exit", - "signUpButton": "Sign Up", - "signInButton": "Sign In", - "backButton": "Back", - "cancelButton": "Cancel", - "confirmButton": "Confirm", - "continueButton": "Continue", - "saveButton": "Save", - "createButton": "Create", - "deleteButton": "Delete", - "editButton": "Edit", - "addButton": "Add", - "copyButton": "Copy", - "moveButton": "Move", - "renameButton": "Rename", - "uploadButton": "Upload", - "downloadButton": "Download", - "shareButton": "Share", - "shareLinkButton": "Share link", - "removeFromStarredButton": "Remove from starred", - "addToStarredButton": "Add to starred", - "moveToTrashButton": "Move to trash", - "restoreButton": "Restore", - "@ ############# Labels #############": {}, - "emailLabel": "Email", - "nameLabel": "Name", - "surnameLabel": "Surname", - "languageSelectionLabel": "Language selection", - "upgradeLabel": "Upgrade", - "appLabel": "App", - "applicationLabel": "Application", - "authenticateLabel": "Authenticate", - "authenticatedLabel": "Authenticated", - "authenticationLabel": "Authentication", - "navigationLabel": "Navigation", - "databaseLabel": "Database", - "copiedLabel": "Copied", - "usefulLinksLabel": "Useful links", - "currentVersionLabel": "Current version", - "latestVersionLabel": "Latest version", - "versionLabel": "Version", - "sizeLabel": "Size", - "typeLabel": "Type", - "dateLabel": "Date", - "timeLabel": "Time", - "statusLabel": "Status", - "currentLabel": "Current", - "currentUserLabel": "Current user", - "applicationVersionLabel": "Application version", - "applicationInformationLabel": "Application information", - "conectedDevicesLabel": "Connected devices", - "renewalDateLabel": "Renewal date", - "apiDomain": "API domain", - "storageLabel": "Storage", - "helpLabel": "Help", - "selectedLabel": "Selected", - "@ ############# Descriptions #############": {}, - "logOutDescription": "You will be logged out from your account" -} \ No newline at end of file diff --git a/example/lib/src/common/localization/localization.dart b/example/lib/src/common/localization/localization.dart deleted file mode 100644 index 80600fc..0000000 --- a/example/lib/src/common/localization/localization.dart +++ /dev/null @@ -1,237 +0,0 @@ -import 'package:flutter/widgets.dart'; -import 'package:meta/meta.dart'; -import 'package:spinifyapp/src/common/localization/generated/l10n.dart' - as generated show GeneratedLocalization, AppLocalizationDelegate; - -/// Localization. -final class Localization extends generated.GeneratedLocalization { - Localization._(this.locale); - - final Locale locale; - - /// Localization delegate. - static const LocalizationsDelegate delegate = - _LocalizationView(generated.AppLocalizationDelegate()); - - /// Current localization instance. - static Localization get current => _current; - static late Localization _current; - - /// Get localization instance for the widget structure. - static Localization of(BuildContext context) => - switch (Localizations.of(context, Localization)) { - Localization localization => localization, - _ => throw ArgumentError( - 'Out of scope, not found inherited widget ' - 'a Localization of the exact type', - 'out_of_scope', - ), - }; - - /// Get language by code. - static ({String name, String nativeName})? getLanguageByCode(String code) => - switch (_isoLangs[code]) { - (String name, String nativeName) => ( - name: name, - nativeName: nativeName - ), - _ => null, - }; - - /// Get supported locales. - static List get supportedLocales => - const generated.AppLocalizationDelegate().supportedLocales; -} - -@immutable -final class _LocalizationView extends LocalizationsDelegate { - @literal - const _LocalizationView( - LocalizationsDelegate delegate, - ) : _delegate = delegate; - - final LocalizationsDelegate _delegate; - - @override - bool isSupported(Locale locale) => _delegate.isSupported(locale); - - @override - Future load(Locale locale) => - generated.GeneratedLocalization.load(locale).then( - (localization) => Localization._current = Localization._(locale)); - - @override - bool shouldReload(covariant _LocalizationView old) => - _delegate.shouldReload(old._delegate); -} - -const Map _isoLangs = - { - "ab": ('Abkhaz', 'аҧсуа'), - "aa": ('Afar', 'Afaraf'), - "af": ('Afrikaans', 'Afrikaans'), - "ak": ('Akan', 'Akan'), - "sq": ('Albanian', 'Shqip'), - "am": ('Amharic', 'አማርኛ'), - "ar": ('Arabic', 'العربية'), - "an": ('Aragonese', 'Aragonés'), - "hy": ('Armenian', 'Հայերեն'), - "as": ('Assamese', 'অসমীয়া'), - "av": ('Avaric', 'авар мацӀ, магӀарул мацӀ'), - "ae": ('Avestan', 'avesta'), - "ay": ('Aymara', 'aymar aru'), - "az": ('Azerbaijani', 'azərbaycan dili'), - "bm": ('Bambara', 'bamanankan'), - "ba": ('Bashkir', 'башҡорт теле'), - "eu": ('Basque', 'euskara, euskera'), - "be": ('Belarusian', 'Беларуская'), - "bn": ('Bengali', 'বাংলা'), - "bh": ('Bihari', 'भोजपुरी'), - "bi": ('Bislama', 'Bislama'), - "bs": ('Bosnian', 'bosanski jezik'), - "br": ('Breton', 'brezhoneg'), - "bg": ('Bulgarian', 'български език'), - "my": ('Burmese', 'ဗမာစာ'), - "ca": ('Catalan, Valencian', 'Català'), - "ch": ('Chamorro', 'Chamoru'), - "ce": ('Chechen', 'нохчийн мотт'), - "ny": ('Chichewa, Chewa, Nyanja', 'chiCheŵa, chinyanja'), - "zh": ('Chinese', '中文 (Zhōngwén), 汉语, 漢語'), - "cv": ('Chuvash', 'чӑваш чӗлхи'), - "kw": ('Cornish', 'Kernewek'), - "co": ('Corsican', 'corsu, lingua corsa'), - "cr": ('Cree', 'ᓀᐦᐃᔭᐍᐏᐣ'), - "hr": ('Croatian', 'hrvatski'), - "cs": ('Czech', 'česky, čeština'), - "da": ('Danish', 'dansk'), - "dv": ('Divehi, Dhivehi, Maldivian;', 'ދިވެހި'), - "nl": ('Dutch', 'Nederlands, Vlaams'), - "en": ('English', 'English'), - "eo": ('Esperanto', 'Esperanto'), - "et": ('Estonian', 'eesti, eesti keel'), - "fo": ('Faroese', 'føroyskt'), - "fj": ('Fijian', 'vosa Vakaviti'), - "fi": ('Finnish', 'suomi, suomen kieli'), - "fr": ('French', 'Français'), - "ff": ('Fula, Fulah, Pulaar, Pular', 'Fulfulde, Pulaar, Pular'), - "gl": ('Galician', 'Galego'), - "ka": ('Georgian', 'ქართული'), - "de": ('German', 'Deutsch'), - "el": ('Greek, Modern', 'Ελληνικά'), - "gn": ('Guaraní', 'Avañeẽ'), - "gu": ('Gujarati', 'ગુજરાતી'), - "ht": ('Haitian, Haitian Creole', 'Kreyòl ayisyen'), - "ha": ('Hausa', 'Hausa, هَوُسَ'), - "he": ('Hebrew (modern)', 'עברית'), - "hz": ('Herero', 'Otjiherero'), - "hi": ('Hindi', 'हिन्दी, हिंदी'), - "ho": ('Hiri Motu', 'Hiri Motu'), - "hu": ('Hungarian', 'Magyar'), - "ia": ('Interlingua', 'Interlingua'), - "id": ('Indonesian', 'Bahasa Indonesia'), - "ie": ('Interlingue', 'Interlingue'), - "ga": ('Irish', 'Gaeilge'), - "ig": ('Igbo', 'Asụsụ Igbo'), - "ik": ('Inupiaq', 'Iñupiaq, Iñupiatun'), - "io": ('Ido', 'Ido'), - "is": ('Icelandic', 'Íslenska'), - "it": ('Italian', 'Italiano'), - "iu": ('Inuktitut', 'ᐃᓄᒃᑎᑐᑦ'), - "ja": ('Japanese', '日本語 (にほんご/にっぽんご)'), - "jv": ('Javanese', 'basa Jawa'), - "kl": ('Kalaallisut, Greenlandic', 'kalaallisut, kalaallit oqaasii'), - "kn": ('Kannada', 'ಕನ್ನಡ'), - "kr": ('Kanuri', 'Kanuri'), - "kk": ('Kazakh', 'Қазақ тілі'), - "km": ('Khmer', 'ភាសាខ្មែរ'), - "ki": ('Kikuyu, Gikuyu', 'Gĩkũyũ'), - "rw": ('Kinyarwanda', 'Ikinyarwanda'), - "ky": ('Kirghiz, Kyrgyz', 'кыргыз тили'), - "kv": ('Komi', 'коми кыв'), - "kg": ('Kongo', 'KiKongo'), - "ko": ('Korean', '한국어 (韓國語), 조선말 (朝鮮語)'), - "kj": ('Kwanyama, Kuanyama', 'Kuanyama'), - "la": ('Latin', 'latine, lingua latina'), - "lb": ('Luxembourgish', 'Lëtzebuergesch'), - "lg": ('Luganda', 'Luganda'), - "li": ('Limburgish, Limburgan, Limburger', 'Limburgs'), - "ln": ('Lingala', 'Lingála'), - "lo": ('Lao', 'ພາສາລາວ'), - "lt": ('Lithuanian', 'lietuvių kalba'), - "lu": ('Luba-Katanga', ''), - "lv": ('Latvian', 'latviešu valoda'), - "gv": ('Manx', 'Gaelg, Gailck'), - "mk": ('Macedonian', 'македонски јазик'), - "mg": ('Malagasy', 'Malagasy fiteny'), - "ml": ('Malayalam', 'മലയാളം'), - "mt": ('Maltese', 'Malti'), - "mi": ('Māori', 'te reo Māori'), - "mr": ('Marathi (Marāṭhī)', 'मराठी'), - "mh": ('Marshallese', 'Kajin M̧ajeļ'), - "mn": ('Mongolian', 'монгол'), - "na": ('Nauru', 'Ekakairũ Naoero'), - "nb": ('Norwegian Bokmål', 'Norsk bokmål'), - "nd": ('North Ndebele', 'isiNdebele'), - "ne": ('Nepali', 'नेपाली'), - "ng": ('Ndonga', 'Owambo'), - "nn": ('Norwegian Nynorsk', 'Norsk nynorsk'), - "no": ('Norwegian', 'Norsk'), - "ii": ('Nuosu', 'ꆈꌠ꒿ Nuosuhxop'), - "nr": ('South Ndebele', 'isiNdebele'), - "oc": ('Occitan', 'Occitan'), - "oj": ('Ojibwe, Ojibwa', 'ᐊᓂᔑᓈᐯᒧᐎᓐ'), - "om": ('Oromo', 'Afaan Oromoo'), - "or": ('Oriya', 'ଓଡ଼ିଆ'), - "pi": ('Pāli', 'पाऴि'), - "fa": ('Persian', 'فارسی'), - "pl": ('Polish', 'Polski'), - "ps": ('Pashto, Pushto', 'پښتو'), - "pt": ('Portuguese', 'Português'), - "qu": ('Quechua', 'Runa Simi, Kichwa'), - "rm": ('Romansh', 'rumantsch grischun'), - "rn": ('Kirundi', 'kiRundi'), - "ro": ('Romanian, Moldavian, Moldovan', 'română'), - "ru": ('Russian', 'Русский'), - "sa": ('Sanskrit (Saṁskṛta)', 'संस्कृतम्'), - "sc": ('Sardinian', 'sardu'), - "se": ('Northern Sami', 'Davvisámegiella'), - "sm": ('Samoan', 'gagana faa Samoa'), - "sg": ('Sango', 'yângâ tî sängö'), - "sr": ('Serbian', 'српски језик'), - "gd": ('Scottish Gaelic, Gaelic', 'Gàidhlig'), - "sn": ('Shona', 'chiShona'), - "si": ('Sinhala, Sinhalese', 'සිංහල'), - "sk": ('Slovak', 'slovenčina'), - "sl": ('Slovene', 'slovenščina'), - "so": ('Somali', 'Soomaaliga, af Soomaali'), - "st": ('Southern Sotho', 'Sesotho'), - "es": ('Spanish', 'Español'), - "su": ('Sundanese', 'Basa Sunda'), - "sw": ('Swahili', 'Kiswahili'), - "ss": ('Swati', 'SiSwati'), - "sv": ('Swedish', 'svenska'), - "ta": ('Tamil', 'தமிழ்'), - "te": ('Telugu', 'తెలుగు'), - "th": ('Thai', 'ไทย'), - "ti": ('Tigrinya', 'ትግርኛ'), - "bo": ('Tibetan', 'བོད་ཡིག'), - "tk": ('Turkmen', 'Türkmen, Түркмен'), - "tn": ('Tswana', 'Setswana'), - "to": ('Tonga (Tonga Islands)', 'faka Tonga'), - "tr": ('Turkish', 'Türkçe'), - "ts": ('Tsonga', 'Xitsonga'), - "tw": ('Twi', 'Twi'), - "ty": ('Tahitian', 'Reo Tahiti'), - "uk": ('Ukrainian', 'українська'), - "ur": ('Urdu', 'اردو'), - "ve": ('Venda', 'Tshivenḓa'), - "vi": ('Vietnamese', 'Tiếng Việt'), - "vo": ('Volapük', 'Volapük'), - "wa": ('Walloon', 'Walon'), - "cy": ('Welsh', 'Cymraeg'), - "wo": ('Wolof', 'Wollof'), - "fy": ('Western Frisian', 'Frysk'), - "xh": ('Xhosa', 'isiXhosa'), - "yi": ('Yiddish', 'ייִדיש'), - "yo": ('Yoruba', 'Yorùbá'), -}; diff --git a/example/lib/src/common/util/color_util.dart b/example/lib/src/common/util/color_util.dart deleted file mode 100644 index 5c16622..0000000 --- a/example/lib/src/common/util/color_util.dart +++ /dev/null @@ -1,29 +0,0 @@ -import 'package:flutter/material.dart'; - -sealed class ColorUtil { - /// Get list of colors with length [count]. - static List getColors(int count) { - final primariesLength = Colors.primaries.length; - if (count <= primariesLength) return Colors.primaries.take(count).toList(); - - final colors = List.filled(count, Colors.transparent); - final step = count / (primariesLength - 1); - - var index = 0; - for (var i = 0; i < primariesLength - 1; i++) { - for (var j = 0; j < step; j++) { - final color1 = Colors.primaries[i], color2 = Colors.primaries[i + 1]; - colors[index] = Color.lerp(color1, color2, j / step)!; - index++; - if (index == count) return colors; - } - } - - while (index < count) { - colors[index] = Colors.primaries.last; - index++; - } - - return colors; - } -} diff --git a/example/lib/src/common/util/date_util.dart b/example/lib/src/common/util/date_util.dart deleted file mode 100644 index cd9945e..0000000 --- a/example/lib/src/common/util/date_util.dart +++ /dev/null @@ -1,27 +0,0 @@ -import 'package:intl/intl.dart' as intl; - -sealed class DateUtil { - /// Format date - static String format( - DateTime? date, { - intl.DateFormat? format, - String fallback = '-', - }) { - if (date == null) return fallback; - if (format != null) return format.format(date); - final now = DateTime.now(); - final today = now.copyWith( - hour: 0, minute: 0, second: 0, millisecond: 0, microsecond: 0); - if (date.isAfter(today)) return intl.DateFormat.Hms().format(date); - if (date.isAfter(today.subtract(const Duration(days: 7)))) { - return intl.DateFormat(intl.DateFormat.WEEKDAY).format(date); - } - return intl.DateFormat.yMd().format(date); - } -} - -extension DateUtilX on DateTime { - /// Format date - String format({intl.DateFormat? format}) => - DateUtil.format(this, format: format); -} diff --git a/example/lib/src/common/util/error_util.dart b/example/lib/src/common/util/error_util.dart deleted file mode 100644 index 38010d7..0000000 --- a/example/lib/src/common/util/error_util.dart +++ /dev/null @@ -1,106 +0,0 @@ -import 'dart:async'; -import 'dart:io'; - -import 'package:flutter/material.dart' - show BuildContext, Colors, ScaffoldMessenger, SnackBar, Text; -import 'package:l/l.dart'; -import 'package:spinifyapp/src/common/localization/localization.dart'; -import 'package:spinifyapp/src/common/util/platform/error_util_vm.dart' - // ignore: uri_does_not_exist - if (dart.library.js_util) 'package:spinifyapp/src/common/util/platform/error_util_js.dart'; - -/// Error util. -sealed class ErrorUtil { - /// Log the error to the console and to Crashlytics. - static Future logError( - Object exception, - StackTrace stackTrace, { - String? hint, - bool fatal = false, - }) async { - try { - if (exception is String) { - return await logMessage( - exception, - stackTrace: stackTrace, - hint: hint, - warning: true, - ); - } - $captureException(exception, stackTrace, hint, fatal).ignore(); - l.e(exception, stackTrace); - } on Object catch (error, stackTrace) { - l.e( - 'Error while logging error "$error" inside ErrorUtil.logError', - stackTrace, - ); - } - } - - /// Logs a message to the console and to Crashlytics. - static Future logMessage( - String message, { - StackTrace? stackTrace, - String? hint, - bool warning = false, - }) async { - try { - l.e(message, stackTrace ?? StackTrace.current); - $captureMessage(message, stackTrace, hint, warning).ignore(); - } on Object catch (error, stackTrace) { - l.e( - 'Error while logging error "$error" inside ErrorUtil.logMessage', - stackTrace, - ); - } - } - - /// Rethrows the error with the stack trace. - static Never throwWithStackTrace(Object error, StackTrace stackTrace) => - Error.throwWithStackTrace(error, stackTrace); - - @pragma('vm:prefer-inline') - static String _localizedError( - String fallback, String Function(Localization l) localize) { - try { - return localize(Localization.current); - } on Object { - return fallback; - } - } - - // Also we can add current localization to this method - static String formatMessage( - Object error, [ - String fallback = 'An error has occurred', - ]) => - switch (error) { - String e => e, - FormatException _ => - _localizedError('Invalid format', (lcl) => lcl.errInvalidFormat), - TimeoutException _ => - _localizedError('Timeout exceeded', (lcl) => lcl.errTimeOutExceeded), - UnimplementedError _ => _localizedError( - 'Not implemented yet', (lcl) => lcl.errNotImplementedYet), - UnsupportedError _ => _localizedError( - 'Unsupported operation', (lcl) => lcl.errUnsupportedOperation), - FileSystemException _ => _localizedError( - 'File system error', (lcl) => lcl.errFileSystemException), - AssertionError _ => - _localizedError('Assertion error', (lcl) => lcl.errAssertionError), - Error _ => _localizedError( - 'An error has occurred', (lcl) => lcl.errAnErrorHasOccurred), - Exception _ => _localizedError('An exception has occurred', - (lcl) => lcl.errAnExceptionHasOccurred), - _ => fallback, - }; - - /// Shows a error snackbar with the given message. - static void showSnackBar(BuildContext context, Object message) => - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text(formatMessage(message)), - backgroundColor: Colors.red, - ), - ); -} diff --git a/example/lib/src/common/util/log_buffer.dart b/example/lib/src/common/util/log_buffer.dart deleted file mode 100644 index 94c0730..0000000 --- a/example/lib/src/common/util/log_buffer.dart +++ /dev/null @@ -1,47 +0,0 @@ -import 'dart:collection' show Queue; - -import 'package:flutter/foundation.dart' show ChangeNotifier; -import 'package:l/l.dart'; - -/// LogBuffer Singleton class -class LogBuffer with ChangeNotifier { - static final LogBuffer _internalSingleton = LogBuffer._internal(); - static LogBuffer get instance => _internalSingleton; - LogBuffer._internal(); - - static const int bufferLimit = 10000; - final Queue _queue = Queue(); - - /// Get the logs - Iterable get logs => _queue; - - /// Clear the logs - void clear() { - _queue.clear(); - notifyListeners(); - } - - /// Add a log to the buffer - void add(LogMessage log) { - if (_queue.length >= bufferLimit) _queue.removeFirst(); - _queue.add(log); - notifyListeners(); - } - - /// Add a list of logs to the buffer - void addAll(List logs) { - logs = logs.take(bufferLimit).toList(); - if (_queue.length + logs.length >= bufferLimit) { - final toRemove = _queue.length + logs.length - bufferLimit; - for (var i = 0; i < toRemove; i++) _queue.removeFirst(); - } - _queue.addAll(logs); - notifyListeners(); - } - - @override - void dispose() { - _queue.clear(); - super.dispose(); - } -} diff --git a/example/lib/src/common/util/logger_util.dart b/example/lib/src/common/util/logger_util.dart deleted file mode 100644 index aa7dbdd..0000000 --- a/example/lib/src/common/util/logger_util.dart +++ /dev/null @@ -1,12 +0,0 @@ -import 'package:l/l.dart'; - -sealed class LoggerUtil { - /// Formats the log message. - static Object messageFormatting( - Object message, LogLevel logLevel, DateTime now) => - '${timeFormat(now)} | $message'; - - /// Formats the time. - static String timeFormat(DateTime time) => - '${time.hour}:${time.minute.toString().padLeft(2, '0')}'; -} diff --git a/example/lib/src/common/util/platform/error_util_js.dart b/example/lib/src/common/util/platform/error_util_js.dart deleted file mode 100644 index 6e966ea..0000000 --- a/example/lib/src/common/util/platform/error_util_js.dart +++ /dev/null @@ -1,17 +0,0 @@ -// ignore_for_file: avoid_positional_boolean_parameters - -Future $captureException( - Object exception, - StackTrace stackTrace, - String? hint, - bool fatal, -) => - Future.value(null); - -Future $captureMessage( - String message, - StackTrace? stackTrace, - String? hint, - bool warning, -) => - Future.value(null); diff --git a/example/lib/src/common/util/platform/error_util_vm.dart b/example/lib/src/common/util/platform/error_util_vm.dart deleted file mode 100644 index a3a83bf..0000000 --- a/example/lib/src/common/util/platform/error_util_vm.dart +++ /dev/null @@ -1,47 +0,0 @@ -// ignore_for_file: avoid_positional_boolean_parameters -//import 'package:firebase_crashlytics/firebase_crashlytics.dart'; - -/* - * Sentry.captureException(exception, stackTrace: stackTrace, hint: hint); - * FirebaseCrashlytics.instance - * .recordError(exception, stackTrace ?? StackTrace.current, reason: hint, fatal: fatal); - * */ -Future $captureException( - Object exception, - StackTrace stackTrace, - String? hint, - bool fatal, -) => - Future.value(); -// FirebaseCrashlytics.instance.recordError(exception, stackTrace, reason: hint, fatal: fatal); - -/* - * Sentry.captureMessage( - * message, - * level: warning ? SentryLevel.warning : SentryLevel.info, - * hint: hint, - * params: [ - * ...?params, - * if (stackTrace != null) 'StackTrace: $stackTrace', - * ], - * ); - * (warning || stackTrace != null) - * ? FirebaseCrashlytics.instance.recordError(message, stackTrace ?? StackTrace.current); - * : FirebaseCrashlytics.instance.log('$message${hint != null ? '\r\n$hint' : ''}'); - * */ -Future $captureMessage( - String message, - StackTrace? stackTrace, - String? hint, - bool warning, -) => - Future.value(); -/* warning || stackTrace != null - ? FirebaseCrashlytics.instance.recordError( - message, - stackTrace ?? StackTrace.current, - reason: hint, - fatal: false, - ) - : FirebaseCrashlytics.instance.log('$message' - '${stackTrace != null ? '\nHint: $hint' : ''}'); */ diff --git a/example/lib/src/common/util/screen_util.dart b/example/lib/src/common/util/screen_util.dart deleted file mode 100644 index 0bc1659..0000000 --- a/example/lib/src/common/util/screen_util.dart +++ /dev/null @@ -1,256 +0,0 @@ -import 'dart:ui' as ui; - -import 'package:flutter/widgets.dart'; -import 'package:meta/meta.dart'; - -/// {@macro screen_util} -extension ScreenUtilExtension on BuildContext { - /// Get current screen logical size representation - /// - /// phone | <= 600 dp | 4 column - /// tablet | 600..1023 dp | 8 column - /// desktop | >= 1024 dp | 12 column - ScreenSize get screenSize => ScreenUtil.screenSizeOf(this); - - /// Portrait or Landscape - Orientation get orientation => ScreenUtil.orientationOf(this); - - /// Evaluate the result of the first matching callback. - /// - /// phone | <= 600 dp | 4 column - /// tablet | 600..1023 dp | 8 column - /// desktop | >= 1024 dp | 12 column - ScreenSizeWhenResult screenSizeWhen({ - required final ScreenSizeWhenResult Function() phone, - required final ScreenSizeWhenResult Function() tablet, - required final ScreenSizeWhenResult Function() desktop, - }) => - ScreenUtil.screenSizeOf(this).when( - phone: phone, - tablet: tablet, - desktop: desktop, - ); - - /// The [screenSizeMaybeWhen] method is equivalent to [screenSizeWhen], - /// but doesn't require all callbacks to be specified. - /// - /// On the other hand, it adds an extra [orElse] required parameter, - /// for fallback behavior. - ScreenSizeWhenResult - screenSizeMaybeWhen({ - required final ScreenSizeWhenResult Function() orElse, - final ScreenSizeWhenResult Function()? phone, - final ScreenSizeWhenResult Function()? tablet, - final ScreenSizeWhenResult Function()? desktop, - }) => - ScreenUtil.screenSizeOf(this).maybeWhen( - phone: phone, - tablet: tablet, - desktop: desktop, - orElse: orElse, - ); -} - -/// {@template screen_util} -/// Screen logical size representation -/// -/// phone | <= 600 dp | 4 column -/// tablet | 600..1023 dp | 8 column -/// desktop | >= 1024 dp | 12 column -/// {@endtemplate} -sealed class ScreenUtil { - /// {@macro screen_util} - static ScreenSize screenSize() { - final view = ui.PlatformDispatcher.instance.implicitView; - if (view == null) return ScreenSize.phone; - final size = view.physicalSize ~/ view.devicePixelRatio; - return _screenSizeFromSize(size); - } - - static ScreenSize from(Size size) => _screenSizeFromSize(size); - - /// {@macro screen_util} - static ScreenSize screenSizeOf(final BuildContext context) { - final size = MediaQuery.of(context).size; - return _screenSizeFromSize(size); - } - - static ScreenSize _screenSizeFromSize(final Size size) => - switch (size.width) { - >= 1024 => ScreenSize.desktop, - <= 600 => ScreenSize.phone, - _ => ScreenSize.tablet, - }; - - /// Portrait or Landscape - static Orientation orientation() { - final view = ui.PlatformDispatcher.instance.implicitView; - final size = view?.physicalSize; - return size == null || size.height > size.width - ? Orientation.portrait - : Orientation.landscape; - } - - /// Portrait or Landscape - static Orientation orientationOf(BuildContext context) => - MediaQuery.of(context).orientation; -} - -/// {@macro screen_util} -@immutable -sealed class ScreenSize { - /// {@macro screen_util} - @literal - const ScreenSize._(this.representation, this.min, this.max); - - /// Phone - static const ScreenSize phone = ScreenSize$Phone(); - - /// Tablet - static const ScreenSize tablet = ScreenSize$Tablet(); - - /// Large desktop - static const ScreenSize desktop = ScreenSize$Desktop(); - - /// Minimum width in logical pixels - final double min; - - /// Maximum width in logical pixels - final double max; - - /// String representation - final String representation; - - /// Is phone - abstract final bool isPhone; - - /// Is tablet - abstract final bool isTablet; - - /// Is desktop - abstract final bool isDesktop; - - /// Evaluate the result of the first matching callback. - /// - /// phone | <= 600 dp | 4 column - /// tablet | 600..1023 dp | 8 column - /// desktop | >= 1024 dp | 12 column - ScreenSizeWhenResult when({ - required final ScreenSizeWhenResult Function() phone, - required final ScreenSizeWhenResult Function() tablet, - required final ScreenSizeWhenResult Function() desktop, - }); - - /// The [maybeWhen] method is equivalent to [when], - /// but doesn't require all callbacks to be specified. - /// - /// On the other hand, it adds an extra [orElse] required parameter, - /// for fallback behavior. - ScreenSizeWhenResult maybeWhen({ - required final ScreenSizeWhenResult Function() orElse, - final ScreenSizeWhenResult Function()? phone, - final ScreenSizeWhenResult Function()? tablet, - final ScreenSizeWhenResult Function()? desktop, - }) => - when( - phone: phone ?? orElse, - tablet: tablet ?? orElse, - desktop: desktop ?? orElse, - ); - - @override - String toString() => representation; -} - -/// {@macro screen_util} -final class ScreenSize$Phone extends ScreenSize { - /// {@macro screen_util} - @literal - const ScreenSize$Phone() : super._('Phone', 0, 599); - - @override - ScreenSizeWhenResult when({ - required final ScreenSizeWhenResult Function() phone, - required final ScreenSizeWhenResult Function() tablet, - required final ScreenSizeWhenResult Function() desktop, - }) => - phone(); - - @override - final bool isPhone = true; - - @override - final bool isTablet = false; - - @override - final bool isDesktop = false; - - @override - int get hashCode => 0; - - @override - bool operator ==(final Object other) => - identical(other, this) || other is ScreenSize$Phone; -} - -/// {@macro screen_util} -final class ScreenSize$Tablet extends ScreenSize { - /// {@macro screen_util} - @literal - const ScreenSize$Tablet() : super._('Tablet', 600, 1023); - - @override - ScreenSizeWhenResult when({ - required final ScreenSizeWhenResult Function() phone, - required final ScreenSizeWhenResult Function() tablet, - required final ScreenSizeWhenResult Function() desktop, - }) => - tablet(); - - @override - final bool isPhone = false; - - @override - final bool isTablet = true; - - @override - final bool isDesktop = false; - - @override - int get hashCode => 1; - - @override - bool operator ==(final Object other) => - identical(other, this) || other is ScreenSize$Tablet; -} - -/// {@macro screen_util} -final class ScreenSize$Desktop extends ScreenSize { - /// {@macro screen_util} - @literal - const ScreenSize$Desktop() : super._('Desktop', 1024, double.infinity); - - @override - ScreenSizeWhenResult when({ - required final ScreenSizeWhenResult Function() phone, - required final ScreenSizeWhenResult Function() tablet, - required final ScreenSizeWhenResult Function() desktop, - }) => - desktop(); - - @override - final bool isPhone = false; - - @override - final bool isTablet = false; - - @override - final bool isDesktop = true; - - @override - int get hashCode => 2; - - @override - bool operator ==(final Object other) => - identical(other, this) || other is ScreenSize$Desktop; -} diff --git a/example/lib/src/common/util/timeouts.dart b/example/lib/src/common/util/timeouts.dart deleted file mode 100644 index 94de7f7..0000000 --- a/example/lib/src/common/util/timeouts.dart +++ /dev/null @@ -1,19 +0,0 @@ -import 'dart:async'; - -/// Extension methods for [Future]. -extension TimeoutsExtension on Future { - /// Returns a [Future] that completes with this future's result, or with the - /// result of calling the [onTimeout] function, if this future doesn't - /// complete before the timeout is exceeded. - /// - /// The [onTimeout] function must return a [Future] which will be used as the - /// result of the returned [Future], and must not throw. - Future logicTimeout({ - double coefficient = 1, - FutureOr Function()? onTimeout, - }) => - timeout( - const Duration(milliseconds: 20000) * coefficient, - onTimeout: onTimeout, - ); -} diff --git a/example/lib/src/common/widget/app.dart b/example/lib/src/common/widget/app.dart deleted file mode 100644 index 59046b9..0000000 --- a/example/lib/src/common/widget/app.dart +++ /dev/null @@ -1,52 +0,0 @@ -import 'package:collection/collection.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_localizations/flutter_localizations.dart'; -import 'package:platform_info/platform_info.dart'; -import 'package:spinifyapp/src/common/localization/localization.dart'; -import 'package:spinifyapp/src/common/widget/window_scope.dart'; -import 'package:spinifyapp/src/feature/authentication/widget/authentication_scope.dart'; -import 'package:spinifyapp/src/feature/authentication/widget/sign_in_form.dart'; -import 'package:spinifyapp/src/feature/chat/widget/chat_screen.dart'; - -/// {@template app} -/// App widget. -/// {@endtemplate} -class App extends StatelessWidget { - /// {@macro app} - const App({super.key}); - - @override - Widget build(BuildContext context) => MaterialApp( - title: 'Spinify', - debugShowCheckedModeBanner: false, - localizationsDelegates: const >[ - GlobalMaterialLocalizations.delegate, - GlobalWidgetsLocalizations.delegate, - GlobalCupertinoLocalizations.delegate, - Localization.delegate, - ], - theme: View.of(context).platformDispatcher.platformBrightness == - Brightness.dark - ? ThemeData.dark(useMaterial3: true) - : ThemeData.light(useMaterial3: true), - /* themeMode: ThemeMode.system, */ - home: const AuthenticationScope( - signInForm: SignInForm(), - child: ChatScreen(), - ), - supportedLocales: Localization.supportedLocales, - locale: Localization.supportedLocales - .firstWhereOrNull((e) => e.languageCode == platform.locale) ?? - const Locale('en', 'US'), - builder: (context, child) => MediaQuery( - data: MediaQuery.of(context).copyWith( - /* textScaler: TextScaler.noScaling, */ - textScaler: const TextScaler.linear(1), - ), - child: WindowScope( - /* title: Localization.of(context).title, */ - child: child ?? const SizedBox.shrink(), - ), - ), - ); -} diff --git a/example/lib/src/common/widget/radial_progress_indicator.dart b/example/lib/src/common/widget/radial_progress_indicator.dart deleted file mode 100644 index 44d4fb1..0000000 --- a/example/lib/src/common/widget/radial_progress_indicator.dart +++ /dev/null @@ -1,106 +0,0 @@ -import 'dart:math' as math; - -import 'package:flutter/material.dart'; - -/// {@template radial_progress_indicator} -/// RadialProgressIndicator widget -/// {@endtemplate} -class RadialProgressIndicator extends StatefulWidget { - /// {@macro radial_progress_indicator} - const RadialProgressIndicator({ - this.size = 64, - this.child, - super.key, - }); - - /// The size of the progress indicator - final double size; - - /// The child widget - final Widget? child; - - @override - State createState() => - _RadialProgressIndicatorState(); -} - -class _RadialProgressIndicatorState extends State - with SingleTickerProviderStateMixin { - late final AnimationController _sweepController; - late final Animation _curvedAnimation; - - @override - void initState() { - super.initState(); - _sweepController = AnimationController( - vsync: this, - duration: const Duration(milliseconds: 1000), - )..repeat(); - _curvedAnimation = CurvedAnimation( - parent: _sweepController, - curve: Curves.ease, - ); - } - - @override - void dispose() { - _sweepController.dispose(); - super.dispose(); - } - - @override - Widget build(BuildContext context) => Center( - child: SizedBox.square( - dimension: widget.size, - child: RepaintBoundary( - child: CustomPaint( - painter: _RadialProgressIndicatorPainter( - animation: _curvedAnimation, - color: Theme.of(context).indicatorColor, - ), - child: Center( - child: widget.child, - ), - ), - ), - ), - ); -} - -class _RadialProgressIndicatorPainter extends CustomPainter { - _RadialProgressIndicatorPainter({ - required Animation animation, - Color color = Colors.blue, - }) : _animation = animation, - _arcPaint = Paint() - ..strokeCap = StrokeCap.round - ..style = PaintingStyle.stroke - ..color = color, - super(repaint: animation); - - final Animation _animation; - final Paint _arcPaint; - - @override - void paint(Canvas canvas, Size size) { - _arcPaint.strokeWidth = size.shortestSide / 8; - final progress = _animation.value; - final rect = Rect.fromCircle( - center: size.center(Offset.zero), - radius: size.shortestSide / 2 - _arcPaint.strokeWidth / 2, - ); - final rotate = math.pow(progress, 2) * math.pi * 2; - final sweep = math.sin(progress * math.pi) * 3 + math.pi * .25; - - canvas.drawArc(rect, rotate, sweep, false, _arcPaint); - } - - @override - bool shouldRepaint(covariant _RadialProgressIndicatorPainter oldDelegate) => - _animation.value != oldDelegate._animation.value; - - @override - bool shouldRebuildSemantics( - covariant _RadialProgressIndicatorPainter oldDelegate) => - false; -} diff --git a/example/lib/src/common/widget/window_scope.dart b/example/lib/src/common/widget/window_scope.dart deleted file mode 100644 index 9461b8e..0000000 --- a/example/lib/src/common/widget/window_scope.dart +++ /dev/null @@ -1,242 +0,0 @@ -import 'dart:io' as io; - -import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; -import 'package:window_manager/window_manager.dart'; - -/// {@template window_scope} -/// WindowScope widget. -/// {@endtemplate} -class WindowScope extends StatefulWidget { - /// {@macro window_scope} - const WindowScope({ - required this.child, - this.title, - super.key, - }); - - /// Title of the window. - final String? title; - - /// The widget below this widget in the tree. - final Widget child; - - @override - State createState() => _WindowScopeState(); -} - -class _WindowScopeState extends State { - @override - Widget build(BuildContext context) => - kIsWeb || io.Platform.isAndroid || io.Platform.isIOS - ? widget.child - : Column( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - const _WindowTitle(), - Expanded( - child: widget.child, - ), - ], - ); -} - -class _WindowTitle extends StatefulWidget { - const _WindowTitle(); - - @override - State<_WindowTitle> createState() => _WindowTitleState(); -} - -class _WindowTitleState extends State<_WindowTitle> with WindowListener { - final ValueNotifier _isFullScreen = ValueNotifier(false); - final ValueNotifier _isAlwaysOnTop = ValueNotifier(false); - - @override - void initState() { - windowManager.addListener(this); - super.initState(); - } - - @override - void dispose() { - windowManager.removeListener(this); - super.dispose(); - } - - @override - void onWindowEnterFullScreen() { - super.onWindowEnterFullScreen(); - _isFullScreen.value = true; - } - - @override - void onWindowLeaveFullScreen() { - super.onWindowLeaveFullScreen(); - _isFullScreen.value = false; - } - - @override - void onWindowFocus() { - // Make sure to call once. - setState(() {}); - // do something - } - - void setAlwaysOnTop(bool value) { - Future(() async { - await windowManager.setAlwaysOnTop(value); - _isAlwaysOnTop.value = await windowManager.isAlwaysOnTop(); - }).ignore(); - } - - @override - Widget build(BuildContext context) { - final title = context.findAncestorWidgetOfExactType()?.title; - return SizedBox( - height: 24, - child: GestureDetector( - behavior: HitTestBehavior.translucent, - onPanStart: (details) => windowManager.startDragging(), - onDoubleTap: null, - /* () async { - bool isMaximized = await windowManager.isMaximized(); - if (!isMaximized) { - windowManager.maximize(); - } else { - windowManager.unmaximize(); - } - }, */ - child: Material( - color: Theme.of(context).primaryColor, - child: Stack( - alignment: Alignment.center, - children: [ - if (title != null) - Builder( - builder: (context) { - final size = MediaQuery.of(context).size; - return AnimatedPositioned( - duration: const Duration(milliseconds: 350), - left: size.width < 800 ? 8 : 78, - right: 78, - top: 0, - bottom: 0, - child: Center( - child: AnimatedSwitcher( - duration: const Duration(milliseconds: 250), - transitionBuilder: (child, animation) => - FadeTransition( - opacity: animation, - child: ScaleTransition( - scale: animation, - child: child, - ), - ), - child: Text( - title, - maxLines: 1, - overflow: TextOverflow.ellipsis, - style: Theme.of(context) - .textTheme - .labelLarge - ?.copyWith(height: 1), - ), - ), - ), - ); - }, - ), - _WindowButtons$Windows( - isFullScreen: _isFullScreen, - isAlwaysOnTop: _isAlwaysOnTop, - setAlwaysOnTop: setAlwaysOnTop, - ), - ], - ), - ), - ), - ); - } -} - -class _WindowButtons$Windows extends StatelessWidget { - const _WindowButtons$Windows({ - required ValueListenable isFullScreen, - required ValueListenable isAlwaysOnTop, - required this.setAlwaysOnTop, - }) : _isFullScreen = isFullScreen, - _isAlwaysOnTop = isAlwaysOnTop; - - // ignore: unused_field - final ValueListenable _isFullScreen; - final ValueListenable _isAlwaysOnTop; - - final ValueChanged setAlwaysOnTop; - - @override - Widget build(BuildContext context) => Align( - alignment: Alignment.centerRight, - child: Row( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - // Is always on top - ValueListenableBuilder( - valueListenable: _isAlwaysOnTop, - builder: (context, isAlwaysOnTop, _) => _WindowButton( - onPressed: () => setAlwaysOnTop(!isAlwaysOnTop), - icon: isAlwaysOnTop ? Icons.push_pin : Icons.push_pin_outlined, - ), - ), - - // Minimize - _WindowButton( - onPressed: () => windowManager.minimize(), - icon: Icons.minimize, - ), - - /* ValueListenableBuilder( - valueListenable: _isFullScreen, - builder: (context, isFullScreen, _) => _WindowButton( - onPressed: () => windowManager.setFullScreen(!isFullScreen), - icon: isFullScreen ? Icons.fullscreen_exit : Icons.fullscreen, - )), */ - - // Close - _WindowButton( - onPressed: () => windowManager.close(), - icon: Icons.close, - ), - const SizedBox(width: 4), - ], - ), - ); -} - -class _WindowButton extends StatelessWidget { - const _WindowButton({ - required this.onPressed, - required this.icon, - }); - - final VoidCallback onPressed; - final IconData icon; - - @override - Widget build(BuildContext context) => Padding( - padding: const EdgeInsets.symmetric(horizontal: 4), - child: IconButton( - onPressed: onPressed, - icon: Icon(icon), - iconSize: 16, - alignment: Alignment.center, - padding: EdgeInsets.zero, - splashRadius: 12, - constraints: const BoxConstraints.tightFor(width: 24, height: 24), - ), - ); -} diff --git a/example/lib/src/feature/authentication/controller/authentication_controller.dart b/example/lib/src/feature/authentication/controller/authentication_controller.dart deleted file mode 100644 index c0c8d29..0000000 --- a/example/lib/src/feature/authentication/controller/authentication_controller.dart +++ /dev/null @@ -1,79 +0,0 @@ -import 'dart:async'; - -import 'package:spinifyapp/src/common/controller/droppable_controller_concurrency.dart'; -import 'package:spinifyapp/src/common/controller/state_controller.dart'; -import 'package:spinifyapp/src/common/util/error_util.dart'; -import 'package:spinifyapp/src/feature/authentication/controller/authentication_state.dart'; -import 'package:spinifyapp/src/feature/authentication/data/authentication_repository.dart'; -import 'package:spinifyapp/src/feature/authentication/model/sign_in_data.dart'; -import 'package:spinifyapp/src/feature/authentication/model/user.dart'; - -final class AuthenticationController - extends StateController - with DroppableControllerConcurrency { - AuthenticationController( - {required IAuthenticationRepository repository, - super.initialState = - const AuthenticationState.idle(user: User.unauthenticated())}) - : _repository = repository { - _userSubscription = repository - .userChanges() - .map((u) => AuthenticationState.idle(user: u)) - .where((newState) => - state.isProcessing || !identical(newState.user, state.user)) - .listen(setState); - } - - final IAuthenticationRepository _repository; - StreamSubscription? _userSubscription; - - void signIn(SignInData data) => handle( - () async { - setState( - AuthenticationState.processing( - user: state.user, - message: 'Logging in...', - ), - ); - await _repository.signIn(data); - }, - (error, _) => setState( - AuthenticationState.idle( - user: state.user, - error: ErrorUtil.formatMessage(error), - ), - ), - () => setState( - AuthenticationState.idle(user: state.user), - ), - ); - - void signOut() => handle( - () async { - setState( - AuthenticationState.processing( - user: state.user, - message: 'Logging out...', - ), - ); - await _repository.signOut(); - }, - (error, _) => setState( - AuthenticationState.idle( - user: state.user, - error: ErrorUtil.formatMessage(error), - ), - ), - () => setState( - const AuthenticationState.idle( - user: User.unauthenticated(), - ), - ), - ); - - @override - void dispose() { - _userSubscription?.cancel(); - super.dispose(); - } -} diff --git a/example/lib/src/feature/authentication/controller/authentication_state.dart b/example/lib/src/feature/authentication/controller/authentication_state.dart deleted file mode 100644 index 4ffa238..0000000 --- a/example/lib/src/feature/authentication/controller/authentication_state.dart +++ /dev/null @@ -1,128 +0,0 @@ -import 'package:meta/meta.dart'; -import 'package:spinifyapp/src/feature/authentication/model/user.dart'; - -/// {@template authentication_state} -/// AuthenticationState. -/// {@endtemplate} -sealed class AuthenticationState extends _$AuthenticationStateBase { - /// Idling state - /// {@macro authentication_state} - const factory AuthenticationState.idle({ - required User user, - String message, - String? error, - }) = AuthenticationState$Idle; - - /// Processing - /// {@macro authentication_state} - const factory AuthenticationState.processing({ - required User user, - String message, - }) = AuthenticationState$Processing; - - /// {@macro authentication_state} - const AuthenticationState({required super.user, required super.message}); -} - -/// Idling state -final class AuthenticationState$Idle extends AuthenticationState - with _$AuthenticationState { - const AuthenticationState$Idle( - {required super.user, super.message = 'Idling', this.error}); - - @override - final String? error; -} - -/// Processing -final class AuthenticationState$Processing extends AuthenticationState - with _$AuthenticationState { - const AuthenticationState$Processing( - {required super.user, super.message = 'Processing'}); - - @override - String? get error => null; -} - -base mixin _$AuthenticationState on AuthenticationState {} - -/// Pattern matching for [AuthenticationState]. -typedef AuthenticationStateMatch = R Function( - S state); - -@immutable -abstract base class _$AuthenticationStateBase { - const _$AuthenticationStateBase({required this.user, required this.message}); - - /// Data entity payload. - @nonVirtual - final User user; - - /// Message or state description. - @nonVirtual - final String message; - - /// Error message. - abstract final String? error; - - /// If an error has occurred? - bool get hasError => error != null; - - /// Is in progress state? - bool get isProcessing => - maybeMap(orElse: () => false, processing: (_) => true); - - /// Is in idle state? - bool get isIdling => !isProcessing; - - /// Pattern matching for [AuthenticationState]. - R map({ - required AuthenticationStateMatch idle, - required AuthenticationStateMatch - processing, - }) => - switch (this) { - AuthenticationState$Idle s => idle(s), - AuthenticationState$Processing s => processing(s), - _ => throw AssertionError(), - }; - - /// Pattern matching for [AuthenticationState]. - R maybeMap({ - AuthenticationStateMatch? idle, - AuthenticationStateMatch? processing, - required R Function() orElse, - }) => - map( - idle: idle ?? (_) => orElse(), - processing: processing ?? (_) => orElse(), - ); - - /// Pattern matching for [AuthenticationState]. - R? mapOrNull({ - AuthenticationStateMatch? idle, - AuthenticationStateMatch? processing, - }) => - map( - idle: idle ?? (_) => null, - processing: processing ?? (_) => null, - ); - - @override - int get hashCode => user.hashCode; - - @override - bool operator ==(Object other) => identical(this, other); - - @override - String toString() { - final buffer = StringBuffer() - ..write('AuthenticationState(') - ..write('user: $user, '); - if (error != null) buffer.write('error: $error, '); - buffer - ..write('message: $message') - ..write(')'); - return buffer.toString(); - } -} diff --git a/example/lib/src/feature/authentication/data/authentication_repository.dart b/example/lib/src/feature/authentication/data/authentication_repository.dart deleted file mode 100644 index cf99cca..0000000 --- a/example/lib/src/feature/authentication/data/authentication_repository.dart +++ /dev/null @@ -1,86 +0,0 @@ -import 'dart:async'; -import 'dart:convert'; - -import 'package:convert/convert.dart'; -import 'package:crypto/crypto.dart'; -import 'package:spinify/spinify.dart'; -import 'package:spinifyapp/src/feature/authentication/model/sign_in_data.dart'; -import 'package:spinifyapp/src/feature/authentication/model/user.dart'; - -abstract interface class IAuthenticationRepository { - Stream userChanges(); - FutureOr getUser(); - FutureOr getToken(); - Future signIn(SignInData data); - Future signOut(); -} - -class AuthenticationRepositoryImpl implements IAuthenticationRepository { - AuthenticationRepositoryImpl(); - - final StreamController _userController = - StreamController.broadcast(); - User _user = const User.unauthenticated(); - - @override - FutureOr getUser() => _user; - - @override - Future getToken() async { - switch (_user) { - case AuthenticatedUser user: - final AuthenticatedUser( - :String username, - :String token, - :String channel - ) = user; - final now = DateTime.now().millisecondsSinceEpoch ~/ 1000; - SpinifyJWT jwt = SpinifyJWT( - sub: username, - exp: now + (24 * 60 * 60), - iat: now, - info: { - 'username': username, - }, - channels: [channel], - ); - return jwt.encode(token); - case UnauthenticatedUser _: - throw Exception('User is not authenticated'); - } - } - - @override - Stream userChanges() => _userController.stream; - - @override - Future signIn(SignInData data) { - String buildChannelName(String channel, [String? secret]) => - switch (secret) { - null || '' => channel, - String secret => '$channel' - '#' - '${hex.encode(utf8.encoder.fuse(sha256).convert(secret).bytes)}', - }; - return Future.sync( - () => _userController.add( - _user = User.authenticated( - username: data.username, - endpoint: data.endpoint, - token: data.token, - channel: buildChannelName(data.channel, data.secret), - secret: switch (data.secret) { - null || '' => null, - String secret => secret, - }), - ), - ); - } - - @override - Future signOut() => Future.sync( - () => _userController.add( - _user = const User.unauthenticated(), - ), - ); -} diff --git a/example/lib/src/feature/authentication/model/sign_in_data.dart b/example/lib/src/feature/authentication/model/sign_in_data.dart deleted file mode 100644 index 77a8a9a..0000000 --- a/example/lib/src/feature/authentication/model/sign_in_data.dart +++ /dev/null @@ -1,82 +0,0 @@ -import 'package:flutter/material.dart'; - -@immutable -final class SignInData { - SignInData({ - required this.endpoint, - required this.token, - required this.username, - required this.channel, - String? secret, - }) : secret = secret == null || secret.isEmpty ? null : secret; - - /// Centrifuge endpoint - final String endpoint; - - /// Centrifuge HMAC token for JWT authentication. - /// **BEWARE**: You should not store the token in the real app! - final String token; - - /// Centrifuge username. - final String username; - - /// Centrifuge channel. - final String channel; - - /// Centrifuge secret (optional) - final String? secret; - - static final RegExp _urlValidator = RegExp( - r'^(https?|ws|wss):\/\/(localhost|((([a-z\d]([a-z\d-]*[a-z\d])*)\.)+[a-z]{2,}|((\d{1,3}\.){3}\d{1,3})))?(:\d+)?(\/[-a-z\d%_.~+]*)*(\?[;&a-z\d%_.~+=-]*)?(\#[-a-z\d_]*)?$', - caseSensitive: false, - multiLine: false, - ); - String? isValidEndpoint() { - if (endpoint.isEmpty) return 'Endpoint is required'; - if (endpoint.length < 6) return 'Endpoint is too short'; - if (endpoint.length > 1024) return 'Endpoint is too long'; - if (!_urlValidator.hasMatch(endpoint)) return 'Endpoint is invalid'; - return null; - } - - String? isValidToken() { - if (token.isEmpty) return 'Token is required'; - if (token.length < 6) return 'Token is too short'; - if (token.length > 64) return 'Token is too long'; - return null; - } - - static final RegExp _usernameValidator = RegExp( - r'\@|[A-Z]|[a-z]|[0-9]|\.|\-|\_|\+', - caseSensitive: false, - multiLine: false, - ); - String? isValidUsername() { - if (username.isEmpty) return 'Username is required'; - if (username.length < 4) return 'Username is too short'; - if (username.length > 64) return 'Username is too long'; - if (!_usernameValidator.hasMatch(username)) return 'Username is invalid'; - return null; - } - - static final RegExp _channelValidator = RegExp( - r'^[a-zA-Z0-9_-]+$', - caseSensitive: false, - multiLine: false, - ); - String? isValidChannel() { - if (channel.isEmpty) return 'Channel is required'; - if (channel.length < 4) return 'Channel is too short'; - if (channel.length > 64) return 'Channel is too long'; - if (!_channelValidator.hasMatch(channel)) return 'Channel is invalid'; - return null; - } - - String? isValidSecret() { - final secret = this.secret; - if (secret == null || secret.isEmpty) return null; - if (secret.length < 4) return 'Secret is too short'; - if (secret.length > 64) return 'Secret is too long'; - return null; - } -} diff --git a/example/lib/src/feature/authentication/model/user.dart b/example/lib/src/feature/authentication/model/user.dart deleted file mode 100644 index 7c2d0f4..0000000 --- a/example/lib/src/feature/authentication/model/user.dart +++ /dev/null @@ -1,175 +0,0 @@ -import 'package:meta/meta.dart'; - -/// User username type. -typedef Username = String; - -/// {@template user} -/// The user entry model. -/// {@endtemplate} -sealed class User with _UserPatternMatching, _UserShortcuts { - /// {@macro user} - const User._(); - - /// {@macro user} - @literal - const factory User.unauthenticated() = UnauthenticatedUser; - - /// {@macro user} - const factory User.authenticated({ - required Username username, - required String endpoint, - required String token, - required String channel, - String? secret, - }) = AuthenticatedUser; - - /// The user's username. - abstract final Username? username; -} - -/// {@macro user} -/// -/// Unauthenticated user. -class UnauthenticatedUser extends User { - /// {@macro user} - const UnauthenticatedUser() : super._(); - - @override - Username? get username => null; - - @override - @nonVirtual - bool get isAuthenticated => false; - - @override - T map({ - required T Function(UnauthenticatedUser user) unauthenticated, - required T Function(AuthenticatedUser user) authenticated, - }) => - unauthenticated(this); - - @override - int get hashCode => -2; - - @override - bool operator ==(Object other) => - identical(this, other) || other is UnauthenticatedUser; - - @override - String toString() => 'UnauthenticatedUser()'; -} - -final class AuthenticatedUser extends User { - const AuthenticatedUser({ - required this.username, - required this.endpoint, - required this.token, - required this.channel, - this.secret, - }) : super._(); - - factory AuthenticatedUser.fromJson(Map json) { - if (json.isEmpty) throw FormatException('Json is empty', json); - if (json - case { - 'username': Username username, - 'endpoint': String endpoint, - 'token': String token, - 'channel': String channel, - 'secret': String? secret, - }) - return AuthenticatedUser( - username: username, - endpoint: endpoint, - token: token, - channel: channel, - secret: secret, - ); - throw FormatException('Invalid json format', json); - } - - @override - @nonVirtual - final Username username; - - /// Centrifuge endpoint - final String endpoint; - - /// Centrifuge HMAC token for JWT authentication. - /// **BEWARE**: You should not store the token in the real app! - final String token; - - /// Centrifuge channel. - final String channel; - - /// Centrifuge secret (optional) - final String? secret; - - @override - @nonVirtual - bool get isAuthenticated => true; - - @override - T map({ - required T Function(UnauthenticatedUser user) unauthenticated, - required T Function(AuthenticatedUser user) authenticated, - }) => - authenticated(this); - - Map toJson() => { - 'username': username, - }; - - @override - int get hashCode => username.hashCode; - - @override - bool operator ==(Object other) => - identical(this, other) || - other is AuthenticatedUser && - username == other.username && - endpoint == other.endpoint && - token == other.token && - channel == other.channel && - secret == other.secret; - - @override - String toString() => 'AuthenticatedUser(username: $username)'; -} - -mixin _UserPatternMatching { - /// Pattern matching on [User] subclasses. - T map({ - required T Function(UnauthenticatedUser user) unauthenticated, - required T Function(AuthenticatedUser user) authenticated, - }); - - /// Pattern matching on [User] subclasses. - T maybeMap({ - required T Function() orElse, - T Function(UnauthenticatedUser user)? unauthenticated, - T Function(AuthenticatedUser user)? authenticated, - }) => - map( - unauthenticated: (user) => unauthenticated?.call(user) ?? orElse(), - authenticated: (user) => authenticated?.call(user) ?? orElse(), - ); - - /// Pattern matching on [User] subclasses. - T? mapOrNull({ - T Function(UnauthenticatedUser user)? unauthenticated, - T Function(AuthenticatedUser user)? authenticated, - }) => - map( - unauthenticated: (user) => unauthenticated?.call(user), - authenticated: (user) => authenticated?.call(user), - ); -} - -mixin _UserShortcuts on _UserPatternMatching { - /// User is authenticated. - bool get isAuthenticated; - - /// User is not authenticated. - bool get isNotAuthenticated => !isAuthenticated; -} diff --git a/example/lib/src/feature/authentication/widget/authentication_scope.dart b/example/lib/src/feature/authentication/widget/authentication_scope.dart deleted file mode 100644 index 87a70dd..0000000 --- a/example/lib/src/feature/authentication/widget/authentication_scope.dart +++ /dev/null @@ -1,150 +0,0 @@ -import 'dart:ui'; - -import 'package:flutter/widgets.dart'; -import 'package:spinifyapp/src/feature/authentication/controller/authentication_controller.dart'; -import 'package:spinifyapp/src/feature/authentication/model/user.dart'; -import 'package:spinifyapp/src/feature/dependencies/widget/dependencies_scope.dart'; - -/// {@template authentication_scope} -/// AuthenticationScope widget. -/// {@endtemplate} -class AuthenticationScope extends StatefulWidget { - /// {@macro authentication_scope} - const AuthenticationScope({ - required this.signInForm, - required this.child, - super.key, - }); - - /// Sign In form for unauthenticated users. - final Widget signInForm; - - /// The widget below this widget in the tree. - final Widget child; - - /// User of the authentication scope. - static User userOf(BuildContext context, {bool listen = true}) => - _InheritedAuthenticationScope.of(context, listen: listen).user; - - /// Authentication controller of the authentication scope. - static AuthenticationController controllerOf(BuildContext context) => - _InheritedAuthenticationScope.of(context, listen: false).controller; - - @override - State createState() => _AuthenticationScopeState(); -} - -/// State for widget AuthenticationScope. -class _AuthenticationScopeState extends State { - late final AuthenticationController _authenticationController; - User _user = const User.unauthenticated(); - bool _showForm = true; - - @override - void initState() { - super.initState(); - _authenticationController = AuthenticationController( - repository: DependenciesScope.of(context).authenticationRepository, - )..addListener(_onAuthenticationControllerChanged); - } - - @override - void dispose() { - _authenticationController - ..removeListener(_onAuthenticationControllerChanged) - ..dispose(); - super.dispose(); - } - - void _onAuthenticationControllerChanged() { - final user = _authenticationController.state.user; - if (!identical(_user, user)) { - if (user.isNotAuthenticated) _showForm = true; - setState(() => _user = user); - } - } - - @override - Widget build(BuildContext context) => _InheritedAuthenticationScope( - controller: _authenticationController, - user: _user, - child: ClipRect( - child: StatefulBuilder( - builder: (context, setState) => Stack( - children: [ - Positioned.fill( - key: const ValueKey('child'), - child: IgnorePointer( - ignoring: _user.isNotAuthenticated, - child: widget.child, - ), - ), - if (_showForm) - Positioned.fill( - key: const ValueKey('authentication-form'), - child: IgnorePointer( - ignoring: _user.isAuthenticated, - child: AnimatedOpacity( - duration: const Duration(milliseconds: 350), - onEnd: () => setState(() => _showForm = false), - curve: Curves.easeInOut, - opacity: _user.isNotAuthenticated ? 1 : 0, - child: RepaintBoundary( - child: BackdropFilter( - filter: ImageFilter.blur( - sigmaX: 2.5, - sigmaY: 2.5, - ), - child: Center( - child: widget.signInForm, - ), - ), - ), - ), - ), - ), - ], - )), - ), - ); -} - -/// Inherited widget for quick access in the element tree. -class _InheritedAuthenticationScope extends InheritedWidget { - const _InheritedAuthenticationScope({ - required this.controller, - required this.user, - required super.child, - }); - - final AuthenticationController controller; - final User user; - - /// The state from the closest instance of this class - /// that encloses the given context, if any. - /// For example: `AuthenticationScope.maybeOf(context)`. - static _InheritedAuthenticationScope? maybeOf(BuildContext context, - {bool listen = true}) => - listen - ? context.dependOnInheritedWidgetOfExactType< - _InheritedAuthenticationScope>() - : context - .getInheritedWidgetOfExactType<_InheritedAuthenticationScope>(); - - static Never _notFoundInheritedWidgetOfExactType() => throw ArgumentError( - 'Out of scope, not found inherited widget ' - 'a _InheritedAuthenticationScope of the exact type', - 'out_of_scope', - ); - - /// The state from the closest instance of this class - /// that encloses the given context. - /// For example: `AuthenticationScope.of(context)`. - static _InheritedAuthenticationScope of(BuildContext context, - {bool listen = true}) => - maybeOf(context, listen: listen) ?? _notFoundInheritedWidgetOfExactType(); - - @override - bool updateShouldNotify(covariant _InheritedAuthenticationScope oldWidget) => - !identical(user, oldWidget.user); -} diff --git a/example/lib/src/feature/authentication/widget/authentication_screen.dart b/example/lib/src/feature/authentication/widget/authentication_screen.dart deleted file mode 100644 index 08691b6..0000000 --- a/example/lib/src/feature/authentication/widget/authentication_screen.dart +++ /dev/null @@ -1,19 +0,0 @@ -import 'package:flutter/material.dart'; - -/// {@template authentication_screen} -/// AuthenticationScreen widget. -/// {@endtemplate} -class AuthenticationScreen extends StatelessWidget { - /// {@macro authentication_screen} - const AuthenticationScreen({super.key}); - - @override - Widget build(BuildContext context) => Scaffold( - appBar: AppBar( - title: const Text('Authentication'), - ), - body: const Center( - child: Text('Authentication'), - ), - ); -} diff --git a/example/lib/src/feature/authentication/widget/sign_in_form.dart b/example/lib/src/feature/authentication/widget/sign_in_form.dart deleted file mode 100644 index 92ad085..0000000 --- a/example/lib/src/feature/authentication/widget/sign_in_form.dart +++ /dev/null @@ -1,406 +0,0 @@ -import 'dart:math' as math; - -import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:spinifyapp/src/common/constant/config.dart'; -import 'package:spinifyapp/src/common/controller/state_consumer.dart'; -import 'package:spinifyapp/src/common/localization/localization.dart'; -import 'package:spinifyapp/src/feature/authentication/controller/authentication_controller.dart'; -import 'package:spinifyapp/src/feature/authentication/model/sign_in_data.dart'; -import 'package:spinifyapp/src/feature/authentication/widget/authentication_scope.dart'; - -/// {@template sign_in_form} -/// SignInScreen widget. -/// {@endtemplate} -class SignInForm extends StatelessWidget implements PreferredSizeWidget { - /// {@macro sign_in_form} - const SignInForm({super.key}); - - /// Width of the sign in form. - static const double width = 480; - - /// Height of the sign in form. - static const double height = 720; - - @override - Size get preferredSize => const Size(width, height); - - @override - Widget build(BuildContext context) => - LayoutBuilder(builder: (context, constraints) { - final space = math.min(constraints.maxHeight - preferredSize.height, - constraints.maxWidth - preferredSize.width); - final padding = switch (space) { - > 32 => 24.0, - > 24 => 16.0, - > 16 => 8.0, - _ => 0.0, - }; - Widget wrap({required Widget child}) => padding > 0 - ? SizedBox( - width: width, - height: height, - child: child, - ) - : SizedBox.expand( - child: child, - ); - return wrap( - child: Card( - elevation: padding > 0 ? 8 : 0, - margin: EdgeInsets.all(padding), - shape: padding > 0 - ? RoundedRectangleBorder( - borderRadius: BorderRadius.circular(padding), - ) - : const RoundedRectangleBorder(borderRadius: BorderRadius.zero), - child: const _SignInForm(), - ), - ); - }); -} - -class _SignInForm extends StatefulWidget { - const _SignInForm(); - - @override - State<_SignInForm> createState() => _SignInFormState(); -} - -/// State for widget _SignInForm. -class _SignInFormState extends State<_SignInForm> { - // Make it static so that it doesn't get disposed when the widget is rebuilt. - static final TextEditingController _endpointController = - TextEditingController(text: Config.centrifugeBaseUrl), - _tokenController = TextEditingController(text: Config.centrifugeToken), - _channelController = - TextEditingController(text: Config.centrifugeChannel), - _usernameController = - TextEditingController(text: Config.centrifugeUsername), - _secretController = TextEditingController(); - - final FocusNode _endpointFocusNode = FocusNode(), - _tokenFocusNode = FocusNode(), - _channelFocusNode = FocusNode(), - _usernameFocusNode = FocusNode(), - _secretFocusNode = FocusNode(); - - final ValueNotifier _endpointError = ValueNotifier(null), - _tokenError = ValueNotifier(null), - _channelError = ValueNotifier(null), - _usernameError = ValueNotifier(null), - _secretError = ValueNotifier(null); - - final ValueNotifier _validNotifier = ValueNotifier(false); - - late final AuthenticationController authenticationController; - late final Listenable _observer; - - @override - void initState() { - super.initState(); - authenticationController = AuthenticationScope.controllerOf(context); - _observer = Listenable.merge([ - _endpointController, - _tokenController, - _channelController, - _usernameController, - _secretController, - ]) - ..addListener(_onChanged); - _onChanged(); - } - - @override - void dispose() { - _observer.removeListener(_onChanged); - _validNotifier.dispose(); - super.dispose(); - } - - late SignInData _data; - - void _onChanged() { - if (!mounted) return; - _data = SignInData( - endpoint: _endpointController.text, - token: _tokenController.text, - channel: _channelController.text, - username: _usernameController.text, - secret: _secretController.text, - ); - _validNotifier.value = _validate(_data); - } - - late final List _validators = - [ - (data) => _endpointError.value = data.isValidEndpoint(), - (data) => _tokenError.value = data.isValidToken(), - (data) => _usernameError.value = data.isValidUsername(), - (data) => _channelError.value = data.isValidChannel(), - (data) => _secretError.value = data.isValidSecret(), - ]; - bool _validate(SignInData data) { - for (final validator in _validators) { - if (validator(data) != null) return false; - } - return true; - } - - void _submit() { - final data = _data; - if (!_validate(data)) return; - authenticationController.signIn(data); - } - - @override - Widget build(BuildContext context) => FocusScope( - child: Column( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Expanded( - child: ListView( - padding: const EdgeInsets.all(16), - shrinkWrap: true, - children: [ - SizedBox( - width: double.infinity, - height: 48, - child: Text( - Localization.of(context).signInButton, - maxLines: 1, - overflow: TextOverflow.ellipsis, - textAlign: TextAlign.center, - style: Theme.of(context) - .textTheme - .headlineMedium - ?.copyWith(height: 1), - ), - ), - const SizedBox(height: 12), - SignInTextField( - focusNode: _endpointFocusNode, - controller: _endpointController, - error: _endpointError, - autofillHints: const [ - AutofillHints.url, - ], - maxLength: 1024, - keyboardType: TextInputType.url, - labelText: 'Endpoint', - hintText: 'Enter your endpoint', - ), - SignInTextField( - focusNode: _tokenFocusNode, - controller: _tokenController, - error: _tokenError, - maxLength: 64, - autofillHints: const [ - AutofillHints.password, - ], - keyboardType: TextInputType.visiblePassword, - labelText: 'Token', - hintText: 'Enter HMAC secret token', - obscureText: true, - ), - SignInTextField( - focusNode: _channelFocusNode, - controller: _channelController, - error: _channelError, - maxLength: 64, - labelText: 'Channel', - hintText: 'Enter your channel', - autofillHints: const [ - AutofillHints.username, - ], - keyboardType: TextInputType.name, - formatters: [ - FilteringTextInputFormatter.allow( - RegExp(r'^[a-zA-Z0-9_-]+$'), - ), - ], - ), - SignInTextField( - focusNode: _usernameFocusNode, - controller: _usernameController, - error: _usernameError, - maxLength: 64, - labelText: 'Username', - hintText: 'Select your username', - autofillHints: const [ - AutofillHints.username, - ], - keyboardType: TextInputType.name, - formatters: [ - FilteringTextInputFormatter.allow( - /// Allow only letters, numbers, - /// and the following characters: @.-_+ - RegExp(r'\@|[A-Z]|[a-z]|[0-9]|\.|\-|\_|\+'), - ), - ], - ), - SignInTextField( - focusNode: _secretFocusNode, - controller: _secretController, - error: _secretError, - maxLength: 64, - autofillHints: const [ - AutofillHints.password, - ], - keyboardType: TextInputType.visiblePassword, - labelText: 'Secret (optional)', - hintText: 'For private channels only', - obscureText: true, - ), - ], - ), - ), - const Divider(height: 1, thickness: 1, indent: 16, endIndent: 16), - Padding( - padding: const EdgeInsets.all(16), - child: Center( - child: SizedBox( - width: 320, - height: 64, - child: ValueListenableBuilder( - valueListenable: _validNotifier, - builder: (context, valid, _) => AnimatedOpacity( - opacity: valid ? 1 : .5, - duration: const Duration(milliseconds: 350), - child: ElevatedButton( - onPressed: valid ? _submit : null, - style: ElevatedButton.styleFrom( - shape: const RoundedRectangleBorder( - borderRadius: BorderRadius.only( - topLeft: Radius.circular(24), - bottomLeft: Radius.circular(8), - bottomRight: Radius.circular(24), - topRight: Radius.circular(8), - ), - ), - textStyle: const TextStyle( - fontSize: 18, - fontWeight: FontWeight.bold, - ), - ), - child: const Text('Sign In'), - ), - ), - ), - ), - ), - ), - ], - ), - ); -} - -class SignInTextField extends StatefulWidget { - const SignInTextField({ - required this.controller, - this.formatters, - this.focusNode, - this.error, - this.autofillHints, - this.labelText, - this.hintText, - this.obscureText = false, - this.keyboardType, - this.maxLength, - super.key, - }); - - final TextEditingController controller; - final List? formatters; - final FocusNode? focusNode; - final ValueListenable? error; - final List? autofillHints; - final String? labelText; - final String? hintText; - final bool obscureText; - final TextInputType? keyboardType; - final int? maxLength; - - @override - State createState() => _SignInTextFieldState(); -} - -class _SignInTextFieldState extends State { - bool _obscurePassword = false; - FocusNode? focusNode; - - @override - void initState() { - super.initState(); - _obscurePassword = widget.obscureText; - focusNode = widget.focusNode?..addListener(_onFocusChanged); - } - - @override - void dispose() { - focusNode?.removeListener(_onFocusChanged); - super.dispose(); - } - - void _onFocusChanged() { - if (focusNode?.hasFocus == false && - mounted && - widget.obscureText && - !_obscurePassword) { - setState(() => _obscurePassword = true); - } - } - - @override - Widget build(BuildContext context) => Padding( - padding: const EdgeInsets.symmetric(vertical: 6), - child: StateConsumer( - controller: AuthenticationScope.controllerOf(context), - builder: (context, state, _) => AnimatedOpacity( - opacity: state.isIdling ? 1 : .5, - duration: const Duration(milliseconds: 250), - child: ValueListenableBuilder( - valueListenable: widget.error ?? ValueNotifier(null), - builder: (context, error, child) => StatefulBuilder( - builder: (context, setState) => TextField( - focusNode: widget.focusNode, - enabled: state.isIdling, - maxLines: 1, - minLines: 1, - maxLength: widget.maxLength, - controller: widget.controller, - autocorrect: false, - autofillHints: widget.autofillHints, - keyboardType: widget.keyboardType, - inputFormatters: widget.formatters, - obscureText: _obscurePassword, - decoration: InputDecoration( - constraints: const BoxConstraints(maxHeight: 84), - labelText: widget.labelText, - hintText: widget.hintText, - helperText: '', - helperMaxLines: 1, - errorText: error ?? state.error, - errorMaxLines: 1, - suffixIcon: widget.obscureText - ? IconButton( - icon: Icon(_obscurePassword - ? Icons.visibility - : Icons.visibility_off), - onPressed: () => setState( - () => _obscurePassword = !_obscurePassword, - ), - ) - : null, - border: const OutlineInputBorder(), - ), - ), - ), - ), - ), - ), - ); -} diff --git a/example/lib/src/feature/chat/controller/chat_connection_controller.dart b/example/lib/src/feature/chat/controller/chat_connection_controller.dart deleted file mode 100644 index 9495966..0000000 --- a/example/lib/src/feature/chat/controller/chat_connection_controller.dart +++ /dev/null @@ -1,26 +0,0 @@ -import 'package:spinifyapp/src/common/controller/droppable_controller_concurrency.dart'; -import 'package:spinifyapp/src/common/controller/state_controller.dart'; -import 'package:spinifyapp/src/feature/chat/controller/chat_connection_state.dart'; -import 'package:spinifyapp/src/feature/chat/data/chat_repository.dart'; - -final class ChatConnectionController - extends StateController - with DroppableControllerConcurrency { - ChatConnectionController({required IChatRepository repository}) - : _repository = repository, - super(initialState: repository.connectionState) { - _repository.connectionStates.distinct().listen(setState); - } - - final IChatRepository _repository; - - void connect(String url) => handle(() => _repository.connect(url)); - - void disconnect() => handle(_repository.disconnect); - - @override - void dispose() { - _repository.disconnect(); - super.dispose(); - } -} diff --git a/example/lib/src/feature/chat/controller/chat_connection_state.dart b/example/lib/src/feature/chat/controller/chat_connection_state.dart deleted file mode 100644 index 16f6468..0000000 --- a/example/lib/src/feature/chat/controller/chat_connection_state.dart +++ /dev/null @@ -1,111 +0,0 @@ -import 'package:meta/meta.dart'; - -/// {@template chat_connection_state} -/// ChatConnectionState. -/// {@endtemplate} -sealed class ChatConnectionState extends _$ChatConnectionStateBase { - /// Disconnected - /// {@macro chat_connection_state} - const factory ChatConnectionState.disconnected({ - String message, - }) = ChatConnectionState$Disconnected; - - /// Connecting - /// {@macro chat_connection_state} - const factory ChatConnectionState.connecting({ - String message, - }) = ChatConnectionState$Connecting; - - /// Connected - /// {@macro chat_connection_state} - const factory ChatConnectionState.connected({ - String message, - }) = ChatConnectionState$Connected; - - /// {@macro chat_connection_state} - const ChatConnectionState({required super.message}); -} - -/// Disconnected -final class ChatConnectionState$Disconnected extends ChatConnectionState { - const ChatConnectionState$Disconnected({super.message = 'Disconnected'}); -} - -/// Connecting -final class ChatConnectionState$Connecting extends ChatConnectionState { - const ChatConnectionState$Connecting({super.message = 'Connecting'}); -} - -/// Connected -final class ChatConnectionState$Connected extends ChatConnectionState { - const ChatConnectionState$Connected({super.message = 'Connected'}); -} - -/// Pattern matching for [ChatConnectionState]. -typedef ChatConnectionStateMatch = R Function( - S state); - -@immutable -abstract base class _$ChatConnectionStateBase { - const _$ChatConnectionStateBase({required this.message}); - - /// Message or state description. - @nonVirtual - final String message; - - /// Is connecting? - bool get isConnecting => - maybeMap(orElse: () => false, connecting: (_) => true); - - /// Is connected? - bool get isConnected => - maybeMap(orElse: () => false, connected: (_) => true); - - /// Is disconnected? - bool get isDisconnected => - maybeMap(orElse: () => false, disconnected: (_) => true); - - /// Pattern matching for [ChatConnectionState]. - R map({ - required ChatConnectionStateMatch - disconnected, - required ChatConnectionStateMatch - connecting, - required ChatConnectionStateMatch - connected, - }) => - switch (this) { - ChatConnectionState$Disconnected s => disconnected(s), - ChatConnectionState$Connecting s => connecting(s), - ChatConnectionState$Connected s => connected(s), - _ => throw AssertionError(), - }; - - /// Pattern matching for [ChatConnectionState]. - R maybeMap({ - ChatConnectionStateMatch? disconnected, - ChatConnectionStateMatch? connecting, - ChatConnectionStateMatch? connected, - required R Function() orElse, - }) => - map( - disconnected: disconnected ?? (_) => orElse(), - connecting: connecting ?? (_) => orElse(), - connected: connected ?? (_) => orElse(), - ); - - /// Pattern matching for [ChatConnectionState]. - R? mapOrNull({ - ChatConnectionStateMatch? disconnected, - ChatConnectionStateMatch? connecting, - ChatConnectionStateMatch? connected, - }) => - map( - disconnected: disconnected ?? (_) => null, - connecting: connecting ?? (_) => null, - connected: connected ?? (_) => null, - ); - - @override - String toString() => message; -} diff --git a/example/lib/src/feature/chat/controller/chat_messages_controller.dart b/example/lib/src/feature/chat/controller/chat_messages_controller.dart deleted file mode 100644 index 295da6b..0000000 --- a/example/lib/src/feature/chat/controller/chat_messages_controller.dart +++ /dev/null @@ -1,63 +0,0 @@ -import 'dart:async'; -import 'dart:collection'; - -import 'package:l/l.dart'; -import 'package:spinifyapp/src/common/controller/droppable_controller_concurrency.dart'; -import 'package:spinifyapp/src/common/controller/state_controller.dart'; -import 'package:spinifyapp/src/feature/authentication/model/user.dart'; -import 'package:spinifyapp/src/feature/chat/controller/chat_messages_state.dart'; -import 'package:spinifyapp/src/feature/chat/data/chat_repository.dart'; -import 'package:spinifyapp/src/feature/chat/model/message.dart'; - -final class ChatMessagesController extends StateController - with DroppableControllerConcurrency { - ChatMessagesController( - {required AuthenticatedUser user, required IChatRepository repository}) - : _user = user, - _repository = repository, - super(initialState: ChatMessagesState.initial) { - final AuthenticatedUser(:channel, :secret) = user; - _messagesSubscription = - _repository.getMessages(channel, secret).listen(_onMessage); - } - - final AuthenticatedUser _user; - final IChatRepository _repository; - late final StreamSubscription _messagesSubscription; - late final Set _messages = SplayTreeSet.of( - state.data, - (a, b) => b.compareTo(a), - ); - - void _onMessage(Message message) { - setState(state.copyWith( - data: (_messages..add(message)).toList(growable: false))); - } - - void sendMessage(String message) => handle( - () async { - l.v6('Sending message'); - await _repository.sendMessage(_user, message); - setState(ChatMessagesState.successful( - data: state.data, message: 'Message sent')); - l.v6('Message sent'); - }, - (error, stackTrace) { - l.w('Error sending message: $error', stackTrace); - setState( - ChatMessagesState.error( - data: state.data, message: 'Error sending message'), - ); - }, - () => setState(ChatMessagesState.idle(data: state.data)), - ); - - void disconnect() => handle(_repository.disconnect); - - @override - void dispose() { - _messagesSubscription.cancel(); - _repository.disconnect(); - super.dispose(); - } -} diff --git a/example/lib/src/feature/chat/controller/chat_messages_state.dart b/example/lib/src/feature/chat/controller/chat_messages_state.dart deleted file mode 100644 index 93e9ce3..0000000 --- a/example/lib/src/feature/chat/controller/chat_messages_state.dart +++ /dev/null @@ -1,193 +0,0 @@ -import 'package:meta/meta.dart'; -import 'package:spinifyapp/src/feature/chat/model/message.dart'; - -/// Chat messages entity. -typedef ChatMessages = List; - -/// {@template chat_messages_state} -/// ChatMessagesState. -/// {@endtemplate} -sealed class ChatMessagesState extends _$ChatMessagesStateBase { - /// Idling state - /// {@macro chat_messages_state} - const factory ChatMessagesState.idle({ - required ChatMessages data, - String message, - }) = ChatMessagesState$Idle; - - /// Processing - /// {@macro chat_messages_state} - const factory ChatMessagesState.processing({ - required ChatMessages data, - String message, - }) = ChatMessagesState$Processing; - - /// Successful - /// {@macro chat_messages_state} - const factory ChatMessagesState.successful({ - required ChatMessages data, - String message, - }) = ChatMessagesState$Successful; - - /// An error has occurred - /// {@macro chat_messages_state} - const factory ChatMessagesState.error({ - required ChatMessages data, - String message, - }) = ChatMessagesState$Error; - - /// {@macro chat_messages_state} - const ChatMessagesState({required super.data, required super.message}); - - static ChatMessagesState get initial => - const ChatMessagesState.idle(data: []); -} - -/// Idling state -final class ChatMessagesState$Idle extends ChatMessagesState { - const ChatMessagesState$Idle({required super.data, super.message = 'Idling'}); - - @override - ChatMessagesState$Idle copyWith({ - ChatMessages? data, - String? message, - }) => - ChatMessagesState$Idle( - data: data ?? this.data, - message: message ?? this.message, - ); -} - -/// Processing -final class ChatMessagesState$Processing extends ChatMessagesState { - const ChatMessagesState$Processing( - {required super.data, super.message = 'Processing'}); - - @override - ChatMessagesState$Processing copyWith({ - ChatMessages? data, - String? message, - }) => - ChatMessagesState$Processing( - data: data ?? this.data, - message: message ?? this.message, - ); -} - -/// Successful -final class ChatMessagesState$Successful extends ChatMessagesState { - const ChatMessagesState$Successful( - {required super.data, super.message = 'Successful'}); - - @override - ChatMessagesState$Successful copyWith({ - ChatMessages? data, - String? message, - }) => - ChatMessagesState$Successful( - data: data ?? this.data, - message: message ?? this.message, - ); -} - -/// Error -final class ChatMessagesState$Error extends ChatMessagesState { - const ChatMessagesState$Error( - {required super.data, super.message = 'An error has occurred.'}); - - @override - ChatMessagesState$Error copyWith({ - ChatMessages? data, - String? message, - }) => - ChatMessagesState$Error( - data: data ?? this.data, - message: message ?? this.message, - ); -} - -/// Pattern matching for [ChatMessagesState]. -typedef ChatMessagesStateMatch = R Function( - S state); - -@immutable -abstract base class _$ChatMessagesStateBase { - const _$ChatMessagesStateBase({required this.data, required this.message}); - - /// Data entity payload. - @nonVirtual - final ChatMessages data; - - /// Message or state description. - @nonVirtual - final String message; - - /// If an error has occurred? - bool get hasError => maybeMap(orElse: () => false, error: (_) => true); - - /// Is in progress state? - bool get isProcessing => - maybeMap(orElse: () => false, processing: (_) => true); - - /// Is in idle state? - bool get isIdling => !isProcessing; - - /// Copy with new data. - ChatMessagesState copyWith({ - ChatMessages? data, - String? message, - }); - - /// Pattern matching for [ChatMessagesState]. - R map({ - required ChatMessagesStateMatch idle, - required ChatMessagesStateMatch processing, - required ChatMessagesStateMatch successful, - required ChatMessagesStateMatch error, - }) => - switch (this) { - ChatMessagesState$Idle s => idle(s), - ChatMessagesState$Processing s => processing(s), - ChatMessagesState$Successful s => successful(s), - ChatMessagesState$Error s => error(s), - _ => throw AssertionError(), - }; - - /// Pattern matching for [ChatMessagesState]. - R maybeMap({ - ChatMessagesStateMatch? idle, - ChatMessagesStateMatch? processing, - ChatMessagesStateMatch? successful, - ChatMessagesStateMatch? error, - required R Function() orElse, - }) => - map( - idle: idle ?? (_) => orElse(), - processing: processing ?? (_) => orElse(), - successful: successful ?? (_) => orElse(), - error: error ?? (_) => orElse(), - ); - - /// Pattern matching for [ChatMessagesState]. - R? mapOrNull({ - ChatMessagesStateMatch? idle, - ChatMessagesStateMatch? processing, - ChatMessagesStateMatch? successful, - ChatMessagesStateMatch? error, - }) => - map( - idle: idle ?? (_) => null, - processing: processing ?? (_) => null, - successful: successful ?? (_) => null, - error: error ?? (_) => null, - ); - - @override - int get hashCode => data.hashCode; - - @override - bool operator ==(Object other) => identical(this, other); - - @override - String toString() => 'ChatMessagesState(data: $data, message: $message)'; -} diff --git a/example/lib/src/feature/chat/data/chat_repository.dart b/example/lib/src/feature/chat/data/chat_repository.dart deleted file mode 100644 index 2a8b1bc..0000000 --- a/example/lib/src/feature/chat/data/chat_repository.dart +++ /dev/null @@ -1,110 +0,0 @@ -import 'dart:async'; -import 'dart:convert'; - -import 'package:l/l.dart'; -import 'package:spinify/spinify.dart'; -import 'package:spinifyapp/src/feature/authentication/model/user.dart'; -import 'package:spinifyapp/src/feature/chat/controller/chat_connection_state.dart'; -import 'package:spinifyapp/src/feature/chat/model/message.dart'; - -/// Chat repository -abstract interface class IChatRepository { - /// Receive messages stream - Stream getMessages(String channel, [String? secret]); - - /// Connection state - ChatConnectionState get connectionState; - - /// Connection states stream - Stream get connectionStates; - - /// Connect to chat server - Future connect(String url); - - /// Disconnect from chat server - Future disconnect(); - - /// Send message to chat server - Future sendMessage(AuthenticatedUser user, String message); -} - -final class ChatRepositorySpinifyImpl implements IChatRepository { - ChatRepositorySpinifyImpl({required Spinify spinify}) : _spinify = spinify; - - /// Centrifugo client - final Spinify _spinify; - - @override - ChatConnectionState get connectionState => - _spinifyStateToConnectionState(_spinify.state); - - @override - late final Stream connectionStates = - _spinify.states.map(_spinifyStateToConnectionState); - - ChatConnectionState _spinifyStateToConnectionState(SpinifyState state) => - switch (state) { - SpinifyState$Connected _ => const ChatConnectionState.connected(), - SpinifyState$Connecting _ => const ChatConnectionState.connecting(), - _ => const ChatConnectionState.disconnected(), - }; - - @override - Stream getMessages(String channel, [String? secret]) { - void ignoreErrors(Object error, StackTrace? stackTrace) { - l.w('Error receiving message: $error', stackTrace); - } - - final Converter, Message> decoder; - if (secret != null && secret.isNotEmpty) { - decoder = EncryptedMessageDecoder(secretKey: secret); - } else { - decoder = const PlainMessageDecoder(); - } - - return _spinify.stream - .publication(channel: channel) - .map>((event) => event.data) - .map(decoder.convert) - .handleError(ignoreErrors); - } - - @override - Future connect(String url) => _spinify.connect(url); - - @override - Future disconnect() => _spinify.disconnect(); - - @override - Future sendMessage(AuthenticatedUser user, String message) async { - if (!_spinify.state.isConnected) { - throw Exception('Spinify is not connected'); - } - final serverChannels = _spinify.subscriptions.server.values.toList(); - final AuthenticatedUser(:channel, :username, :secret) = user; - if (!serverChannels.any((c) => c.channel == channel)) - throw Exception('Spinify server channel is not set'); - List data; - switch (secret) { - case null || '': - data = const PlainMessageEncoder().convert( - PlainMessage( - author: username, - text: message, - createdAt: DateTime.now(), - version: 1, - ), - ); - case String secret: - data = EncryptedMessageEncoder(secretKey: secret).convert( - EncryptedMessage( - author: username, - text: message, - createdAt: DateTime.now(), - version: 1, - ), - ); - } - await _spinify.publish(channel, data); - } -} diff --git a/example/lib/src/feature/chat/model/message.dart b/example/lib/src/feature/chat/model/message.dart deleted file mode 100644 index 4367fa9..0000000 --- a/example/lib/src/feature/chat/model/message.dart +++ /dev/null @@ -1,212 +0,0 @@ -import 'dart:convert'; - -import 'package:crypto/crypto.dart'; -import 'package:meta/meta.dart'; - -@immutable -sealed class Message implements Comparable { - const Message({ - required this.author, - required this.text, - required this.version, - required this.createdAt, - }); - - /// The type of the message. - abstract final String type; - - /// The author of the message. - final String author; - - /// The text of the message. - final String text; - - /// The version of the message. - final int version; - - /// The time the message was created. - final DateTime createdAt; - - Map toJson(); -} - -final class PlainMessage extends Message { - const PlainMessage({ - required super.author, - required super.text, - required super.version, - required super.createdAt, - }); - - factory PlainMessage.fromJson(Map json) { - if (json - case { - 'type': 'plain', - 'author': String author, - 'text': String text, - 'version': int version, - 'createdAt': int createdAt, - }) - return PlainMessage( - author: author, - text: text, - version: version, - createdAt: DateTime.fromMillisecondsSinceEpoch(createdAt * 1000), - ); - throw const FormatException('Invalid message type'); - } - - @override - String get type => 'plain'; - - @override - int compareTo(Message other) => createdAt.compareTo(other.createdAt); - - @override - Map toJson() => { - 'type': type, - 'author': author, - 'text': text, - 'version': version, - 'createdAt': createdAt.millisecondsSinceEpoch ~/ 1000, - }; - - @override - String toString() => '$author: $text'; -} - -final class EncryptedMessage extends Message { - const EncryptedMessage({ - required super.author, - required super.text, - required super.version, - required super.createdAt, - }); - - factory EncryptedMessage.fromJson(Map json) { - if (json - case { - 'type': 'encrypted', - 'author': String author, - 'text': String text, - 'version': int version, - 'createdAt': int createdAt, - }) - return EncryptedMessage( - author: author, - text: text, - version: version, - createdAt: DateTime.fromMillisecondsSinceEpoch(createdAt * 1000), - ); - throw const FormatException('Invalid message type'); - } - - @override - int compareTo(Message other) => createdAt.compareTo(other.createdAt); - - @override - String get type => 'encrypted'; - - @override - Map toJson() => { - 'type': type, - 'author': author, - 'text': text, - 'version': version, - 'createdAt': createdAt.millisecondsSinceEpoch ~/ 1000, - }; - - @override - String toString() => '$author: $text'; -} - -@immutable -final class PlainMessageCodec extends Codec> { - const PlainMessageCodec(); - - @override - Converter, PlainMessage> get decoder => const PlainMessageDecoder(); - - @override - Converter> get encoder => const PlainMessageEncoder(); -} - -final class PlainMessageDecoder extends Converter, PlainMessage> { - const PlainMessageDecoder(); - - @override - PlainMessage convert(List input) => - PlainMessage.fromJson(_$bytesDecoder.convert(input)); -} - -final class PlainMessageEncoder extends Converter> { - const PlainMessageEncoder(); - - @override - List convert(PlainMessage input) => - _$bytesEncoder.convert(input.toJson()); -} - -@immutable -final class EncryptedMessageCodec extends Codec> { - const EncryptedMessageCodec({required this.secretKey}); - - final String secretKey; - - @override - Converter, EncryptedMessage> get decoder => - EncryptedMessageDecoder(secretKey: secretKey); - - @override - Converter> get encoder => - EncryptedMessageEncoder(secretKey: secretKey); -} - -final class EncryptedMessageDecoder - extends Converter, EncryptedMessage> { - EncryptedMessageDecoder({required String secretKey}) - : _secret = utf8.encode(secretKey); - - final List _secret; - late final int secretLength = _secret.length; - late final Digest _digest = sha256.convert(_secret); - - @override - EncryptedMessage convert(List input) { - if (input.length < 32) throw const FormatException('Message too short'); - final signature = input.sublist(input.length - 32); - if (_digest != Digest(signature)) - throw const FormatException('Invalid signature'); - final bytes = input.sublist(0, input.length - 32); - for (var i = 0; i < bytes.length; i++) - bytes[i] ^= _secret[i % secretLength]; - return EncryptedMessage.fromJson(_$bytesDecoder.convert(bytes)); - } -} - -final class EncryptedMessageEncoder - extends Converter> { - EncryptedMessageEncoder({required String secretKey}) - : _secret = utf8.encode(secretKey); - - final List _secret; - late final int secretLength = _secret.length; - late final Digest _digest = sha256.convert(_secret); - - @override - List convert(EncryptedMessage input) { - final bytes = _$bytesEncoder.convert(input.toJson()); - for (var i = 0; i < bytes.length; i++) - bytes[i] ^= _secret[i % secretLength]; - return bytes + _digest.bytes; - } -} - -final Converter, Map> _$bytesDecoder = - const Utf8Decoder() - .fuse(const JsonDecoder().cast>()); - -final Converter, List> _$bytesEncoder = - const JsonEncoder() - .cast, String>() - .fuse(const Utf8Encoder()); diff --git a/example/lib/src/feature/chat/widget/chat_room.dart b/example/lib/src/feature/chat/widget/chat_room.dart deleted file mode 100644 index 488f736..0000000 --- a/example/lib/src/feature/chat/widget/chat_room.dart +++ /dev/null @@ -1,240 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:spinifyapp/src/common/controller/state_consumer.dart'; -import 'package:spinifyapp/src/common/util/date_util.dart'; -import 'package:spinifyapp/src/feature/authentication/model/user.dart'; -import 'package:spinifyapp/src/feature/chat/controller/chat_connection_controller.dart'; -import 'package:spinifyapp/src/feature/chat/controller/chat_connection_state.dart'; -import 'package:spinifyapp/src/feature/chat/controller/chat_messages_controller.dart'; -import 'package:spinifyapp/src/feature/chat/controller/chat_messages_state.dart'; -import 'package:spinifyapp/src/feature/chat/model/message.dart'; -import 'package:spinifyapp/src/feature/dependencies/widget/dependencies_scope.dart'; - -/// {@template chat_screen} -/// ChatRoom widget. -/// {@endtemplate} -class ChatRoom extends StatefulWidget { - /// {@macro chat_screen} - const ChatRoom({required this.user, super.key}); - - /// The user that is currently logged in - final AuthenticatedUser user; - - @override - State createState() => _ChatRoomState(); -} - -/// State for widget ChatRoom. -class _ChatRoomState extends State { - late final ChatConnectionController _connectionController; - late ChatMessagesController _messagesController; - final TextEditingController _textEditingController = TextEditingController(); - - @override - void initState() { - super.initState(); - final repository = DependenciesScope.of(context).chatRepository; - _connectionController = ChatConnectionController(repository: repository); - _messagesController = - ChatMessagesController(user: widget.user, repository: repository); - _connectionController.connect(widget.user.endpoint); - } - - @override - void didUpdateWidget(covariant ChatRoom oldWidget) { - super.didUpdateWidget(oldWidget); - if (oldWidget.user != widget.user) { - _connectionController.disconnect(); - _connectionController.connect(widget.user.endpoint); - _messagesController.dispose(); - _messagesController = ChatMessagesController( - user: widget.user, - repository: DependenciesScope.of(context).chatRepository, - ); - } - } - - @override - void dispose() { - _messagesController.dispose(); - _connectionController.dispose(); - _textEditingController.dispose(); - super.dispose(); - } - - @override - Widget build(BuildContext context) => Column( - children: [ - Expanded( - child: StateConsumer( - controller: _messagesController, - builder: (context, messagesState, child) => RepaintBoundary( - child: ListView.builder( - scrollDirection: Axis.vertical, - padding: - const EdgeInsets.symmetric(vertical: 16, horizontal: 8), - reverse: true, - itemCount: messagesState.data.length, - itemBuilder: (context, index) => ChatMessageBubble( - message: messagesState.data[index], - currentUser: widget.user, - ), - ), - ), - ), - ), - const Divider(height: 1, thickness: .5), - RepaintBoundary( - child: SizedBox( - height: 64, - width: double.infinity, - child: ColoredBox( - color: Colors.grey.withOpacity(0.2), - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 16), - child: StateConsumer( - controller: _connectionController, - builder: (context, connectionState, _) => - StateConsumer( - controller: _messagesController, - buildWhen: (previous, current) => - !(previous.isIdling && current.isIdling), - listener: (context, previous, current) { - switch (current) { - case ChatMessagesState$Successful _: - _textEditingController.clear(); - case ChatMessagesState$Error state: - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text(state.message), - backgroundColor: Colors.red, - ), - ); - default: - break; - } - }, - builder: (context, messagesState, child) => Row( - children: [ - Expanded( - child: TextField( - controller: _textEditingController, - enabled: connectionState.isConnected, - maxLength: 128, - maxLines: 1, - decoration: const InputDecoration( - border: InputBorder.none, - counterText: '', - hintText: 'Write a message...', - ), - ), - ), - ValueListenableBuilder( - valueListenable: _textEditingController, - builder: (context, value, _) { - final enabled = connectionState.isConnected && - messagesState.isIdling && - value.text.isNotEmpty; - return IconButton( - icon: AnimatedSwitcher( - duration: const Duration(milliseconds: 350), - child: switch (connectionState) { - ChatConnectionState$Connecting _ => - const CircularProgressIndicator(), - ChatConnectionState$Connected _ => - const Icon(Icons.send), - ChatConnectionState$Disconnected _ => - const Icon(Icons.send_outlined), - }, - ), - onPressed: enabled - ? () => _messagesController - .sendMessage(value.text) - : null, - ); - }, - ), - ], - ), - ), - ), - ), - ), - ), - ), - ], - ); -} - -/// {@template chat_room} -/// ChatMessageBubble widget. -/// {@endtemplate} -class ChatMessageBubble extends StatelessWidget { - /// {@macro chat_room} - const ChatMessageBubble( - {required this.message, required this.currentUser, super.key}); - - final Message message; - final AuthenticatedUser currentUser; - - static const List _$colors = Colors.primaries; - static Color _getColorForUsername(String username) => - _$colors[username.codeUnitAt(0) % _$colors.length]; - - @override - Widget build(BuildContext context) => Align( - alignment: message.author == currentUser.username - ? Alignment.centerRight - : Alignment.centerLeft, - child: ConstrainedBox( - constraints: BoxConstraints.loose( - const Size.fromWidth(512), - ), - child: Card( - margin: const EdgeInsets.symmetric(vertical: 8), - child: Stack( - fit: StackFit.loose, - children: [ - Positioned( - top: 4, - left: 8, - child: Text( - message.author, - overflow: TextOverflow.ellipsis, - maxLines: 1, - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 12, - color: _getColorForUsername(message.author), - letterSpacing: 1, - height: 1, - ), - ), - ), - Padding( - padding: const EdgeInsets.fromLTRB(8, 16, 8, 14), - child: ConstrainedBox( - constraints: const BoxConstraints(minWidth: 128), - child: Text(message.text), - ), - ), - Positioned( - bottom: 4, - right: 4, - child: Text( - message.createdAt.format(), - overflow: TextOverflow.ellipsis, - maxLines: 1, - style: const TextStyle( - fontSize: 10, - color: Colors.grey, - letterSpacing: 1.2, - height: 1, - ), - ), - ), - ], - ), - ), - ), - ); -} diff --git a/example/lib/src/feature/chat/widget/chat_screen.dart b/example/lib/src/feature/chat/widget/chat_screen.dart deleted file mode 100644 index e8860ff..0000000 --- a/example/lib/src/feature/chat/widget/chat_screen.dart +++ /dev/null @@ -1,45 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:spinifyapp/src/common/controller/state_consumer.dart'; -import 'package:spinifyapp/src/common/localization/localization.dart'; -import 'package:spinifyapp/src/feature/authentication/widget/authentication_scope.dart'; -import 'package:spinifyapp/src/feature/chat/widget/chat_room.dart'; - -/// {@template chat_screen} -/// ChatScreen widget. -/// {@endtemplate} -class ChatScreen extends StatelessWidget { - /// {@macro chat_screen} - const ChatScreen({super.key}); - - @override - Widget build(BuildContext context) { - final authController = AuthenticationScope.controllerOf(context); - return StateConsumer( - controller: authController, - builder: (context, state, _) => Scaffold( - appBar: AppBar( - title: Text(Localization.of(context).title), - centerTitle: true, - automaticallyImplyLeading: false, - /* elevation: 4, */ - /* pinned: MediaQuery.of(context).size.height > 600, */ - actions: [ - IconButton( - onPressed: () => - AuthenticationScope.controllerOf(context).signOut(), - icon: const Icon(Icons.logout), - ), - const SizedBox(width: 16), - ], - ), - body: AnimatedSwitcher( - duration: const Duration(milliseconds: 250), - child: state.user.map( - authenticated: (user) => ChatRoom(user: user), - unauthenticated: (_) => const SizedBox.expand(), - ), - ), - ), - ); - } -} diff --git a/example/lib/src/feature/dependencies/initialization/initialization.dart b/example/lib/src/feature/dependencies/initialization/initialization.dart deleted file mode 100644 index 092ef58..0000000 --- a/example/lib/src/feature/dependencies/initialization/initialization.dart +++ /dev/null @@ -1,103 +0,0 @@ -import 'dart:async'; - -import 'package:flutter/foundation.dart' - show ChangeNotifier, FlutterError, PlatformDispatcher, ValueListenable; -import 'package:flutter/services.dart' show SystemChrome, DeviceOrientation; -import 'package:flutter/widgets.dart' - show WidgetsBinding, WidgetsFlutterBinding; -import 'package:spinifyapp/src/common/util/error_util.dart'; -import 'package:spinifyapp/src/feature/dependencies/initialization/initialize_dependencies.dart'; -import 'package:spinifyapp/src/feature/dependencies/model/dependencies.dart'; - -typedef InitializationProgressTuple = ({int progress, String message}); - -abstract interface class InitializationProgressListenable - implements ValueListenable {} - -class InitializationExecutor - with ChangeNotifier, InitializeDependencies - implements InitializationProgressListenable { - InitializationExecutor(); - - /// Ephemerally initializes the app and prepares it for use. - Future? _$currentInitialization; - - @override - InitializationProgressTuple get value => _value; - InitializationProgressTuple _value = (progress: 0, message: ''); - - /// Initializes the app and prepares it for use. - Future call({ - bool deferFirstFrame = false, - List? orientations, - void Function(int progress, String message)? onProgress, - void Function(Dependencies dependencies)? onSuccess, - void Function(Object error, StackTrace stackTrace)? onError, - }) => - _$currentInitialization ??= Future(() async { - late final WidgetsBinding binding; - final stopwatch = Stopwatch()..start(); - void notifyProgress(int progress, String message) { - _value = (progress: progress.clamp(0, 100), message: message); - onProgress?.call(_value.progress, _value.message); - notifyListeners(); - } - - notifyProgress(0, 'Initializing'); - try { - binding = WidgetsFlutterBinding.ensureInitialized(); - if (deferFirstFrame) binding.deferFirstFrame(); - await _catchExceptions(); - if (orientations != null) - await SystemChrome.setPreferredOrientations(orientations); - final dependencies = - await $initializeDependencies(onProgress: notifyProgress) - .timeout(const Duration(minutes: 5)); - notifyProgress(100, 'Done'); - onSuccess?.call(dependencies); - return dependencies; - } on Object catch (error, stackTrace) { - onError?.call(error, stackTrace); - ErrorUtil.logError( - error, - stackTrace, - hint: 'Failed to initialize app', - ).ignore(); - rethrow; - } finally { - stopwatch.stop(); - binding.addPostFrameCallback((_) { - // Closes splash screen, and show the app layout. - if (deferFirstFrame) binding.allowFirstFrame(); - //final context = binding.renderViewElement; - }); - _$currentInitialization = null; - } - }); - - Future _catchExceptions() async { - try { - PlatformDispatcher.instance.onError = (error, stackTrace) { - ErrorUtil.logError( - error, - stackTrace, - hint: 'ROOT | ${Error.safeToString(error)}', - ).ignore(); - return true; - }; - - final sourceFlutterError = FlutterError.onError; - FlutterError.onError = (final details) { - ErrorUtil.logError( - details.exception, - details.stack ?? StackTrace.current, - hint: 'FLUTTER ERROR\r\n$details', - ).ignore(); - // FlutterError.presentError(details); - sourceFlutterError?.call(details); - }; - } on Object catch (error, stackTrace) { - ErrorUtil.logError(error, stackTrace).ignore(); - } - } -} diff --git a/example/lib/src/feature/dependencies/initialization/initialize_dependencies.dart b/example/lib/src/feature/dependencies/initialization/initialize_dependencies.dart deleted file mode 100644 index 6caeebd..0000000 --- a/example/lib/src/feature/dependencies/initialization/initialize_dependencies.dart +++ /dev/null @@ -1,118 +0,0 @@ -import 'dart:async'; - -import 'package:l/l.dart'; -import 'package:meta/meta.dart'; -import 'package:platform_info/platform_info.dart'; -import 'package:spinify/spinify.dart'; -import 'package:spinifyapp/src/common/constant/config.dart'; -import 'package:spinifyapp/src/common/constant/pubspec.yaml.g.dart'; -import 'package:spinifyapp/src/common/controller/controller.dart'; -import 'package:spinifyapp/src/common/controller/controller_observer.dart'; -import 'package:spinifyapp/src/common/util/screen_util.dart'; -import 'package:spinifyapp/src/feature/authentication/data/authentication_repository.dart'; -import 'package:spinifyapp/src/feature/chat/data/chat_repository.dart'; -import 'package:spinifyapp/src/feature/dependencies/initialization/platform/initialization_vm.dart' - // ignore: uri_does_not_exist - if (dart.library.js_util) 'package:spinifyapp/src/feature/dependencies/initialization/platform/initialization_js.dart'; -import 'package:spinifyapp/src/feature/dependencies/model/app_metadata.dart'; -import 'package:spinifyapp/src/feature/dependencies/model/dependencies.dart'; - -typedef _InitializationStep = FutureOr Function( - _MutableDependencies dependencies); - -class _MutableDependencies implements Dependencies { - @override - late AppMetadata appMetadata; - - @override - late IAuthenticationRepository authenticationRepository; - - @override - late IChatRepository chatRepository; -} - -@internal -mixin InitializeDependencies { - /// Initializes the app and returns a [Dependencies] object - @protected - Future $initializeDependencies({ - void Function(int progress, String message)? onProgress, - }) async { - final steps = _initializationSteps; - final dependencies = _MutableDependencies(); - final totalSteps = steps.length; - for (var currentStep = 0; currentStep < totalSteps; currentStep++) { - final step = steps[currentStep]; - final percent = (currentStep * 100 ~/ totalSteps).clamp(0, 100); - onProgress?.call(percent, step.$1); - l.v6( - 'Initialization | $currentStep/$totalSteps ($percent%) | "${step.$1}"'); - await step.$2(dependencies); - } - return dependencies; - } - - List<(String, _InitializationStep)> get _initializationSteps => - <(String, _InitializationStep)>[ - ( - 'Platform pre-initialization', - (_) => $platformInitialization(), - ), - ( - 'Creating app metadata', - (dependencies) => dependencies.appMetadata = AppMetadata( - environment: Config.environment.value, - isWeb: platform.isWeb, - isRelease: platform.buildMode.isRelease, - appName: Pubspec.name, - appVersion: Pubspec.version.canonical, - appVersionMajor: Pubspec.version.major, - appVersionMinor: Pubspec.version.minor, - appVersionPatch: Pubspec.version.patch, - appBuildTimestamp: Pubspec.version.build.isNotEmpty - ? (int.tryParse( - Pubspec.version.build.firstOrNull ?? '-1') ?? - -1) - : -1, - operatingSystem: platform.operatingSystem.name, - processorsCount: platform.numberOfProcessors, - appLaunchedTimestamp: DateTime.now(), - locale: platform.locale, - deviceVersion: platform.version, - deviceScreenSize: ScreenUtil.screenSize().representation, - ), - ), - ( - 'Observer state managment', - (_) => Controller.observer = ControllerObserver(), - ), - ( - 'Initializing analytics', - (_) {}, - ), - ( - 'Log app open', - (_) {}, - ), - ( - 'Get remote config', - (_) {}, - ), - ( - 'Authentication repository', - (dependencies) => dependencies.authenticationRepository = - AuthenticationRepositoryImpl(), - ), - ( - 'Chat repository', - (dependencies) => - dependencies.chatRepository = ChatRepositorySpinifyImpl( - spinify: Spinify( - config: SpinifyConfig( - getToken: dependencies.authenticationRepository.getToken, - ), - ), - ), - ), - ]; -} diff --git a/example/lib/src/feature/dependencies/initialization/platform/initialization_js.dart b/example/lib/src/feature/dependencies/initialization/platform/initialization_js.dart deleted file mode 100644 index 611f64e..0000000 --- a/example/lib/src/feature/dependencies/initialization/platform/initialization_js.dart +++ /dev/null @@ -1,21 +0,0 @@ -// ignore_for_file: avoid_web_libraries_in_flutter - -import 'dart:html' as html; - -//import 'package:flutter_web_plugins/flutter_web_plugins.dart'; - -Future $platformInitialization() async { - //setUrlStrategy(const HashUrlStrategy()); - Future.delayed( - const Duration(seconds: 1), - () { - html.document.getElementById('splash')?.remove(); - html.document.getElementById('splash-branding')?.remove(); - html.document.body?.style.background = 'transparent'; - html.document - .getElementsByClassName('splash-loading') - .toList(growable: false) - .forEach((element) => element.remove()); - }, - ); -} diff --git a/example/lib/src/feature/dependencies/initialization/platform/initialization_vm.dart b/example/lib/src/feature/dependencies/initialization/platform/initialization_vm.dart deleted file mode 100644 index bab36ca..0000000 --- a/example/lib/src/feature/dependencies/initialization/platform/initialization_vm.dart +++ /dev/null @@ -1,44 +0,0 @@ -import 'dart:io' as io; - -import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; -import 'package:window_manager/window_manager.dart'; - -Future $platformInitialization() => - io.Platform.isAndroid || io.Platform.isIOS - ? _mobileInitialization() - : _desktopInitialization(); - -Future _mobileInitialization() async {} - -Future _desktopInitialization() async { - // Must add this line. - await windowManager.ensureInitialized(); - final windowOptions = WindowOptions( - minimumSize: const Size(360, 480), - size: const Size(960, 800), - maximumSize: const Size(1440, 1080), - center: true, - backgroundColor: - PlatformDispatcher.instance.platformBrightness == Brightness.dark - ? ThemeData.dark().colorScheme.surface - : ThemeData.light().colorScheme.surface, - skipTaskbar: false, - titleBarStyle: TitleBarStyle.hidden, - /* alwaysOnTop: true, */ - windowButtonVisibility: false, - fullScreen: false, - title: 'Chat App', - ); - await windowManager.waitUntilReadyToShow( - windowOptions, - () async { - if (io.Platform.isMacOS) { - await windowManager.setMovable(true); - } - await windowManager.setMaximizable(false); - await windowManager.show(); - await windowManager.focus(); - }, - ); -} diff --git a/example/lib/src/feature/dependencies/model/app_metadata.dart b/example/lib/src/feature/dependencies/model/app_metadata.dart deleted file mode 100644 index eeb599f..0000000 --- a/example/lib/src/feature/dependencies/model/app_metadata.dart +++ /dev/null @@ -1,92 +0,0 @@ -import 'package:meta/meta.dart'; - -/// {@template app_metadata} -/// App metadata -/// {@endtemplate} -@immutable -class AppMetadata { - /// {@macro app_metadata} - const AppMetadata({ - required this.environment, - required this.isWeb, - required this.isRelease, - required this.appVersion, - required this.appVersionMajor, - required this.appVersionMinor, - required this.appVersionPatch, - required this.appBuildTimestamp, - required this.appName, - required this.operatingSystem, - required this.processorsCount, - required this.locale, - required this.deviceVersion, - required this.deviceScreenSize, - required this.appLaunchedTimestamp, - }); - - /// Environment - /// Possible values: development, staging, production - final String environment; - - /// Is web platform - final bool isWeb; - - /// Is release build - final bool isRelease; - - /// App version - final String appVersion; - - /// App version major - final int appVersionMajor; - - /// App version minor - final int appVersionMinor; - - /// App version patch - final int appVersionPatch; - - /// App build timestamp - final int appBuildTimestamp; - - /// App name - final String appName; - - /// Operating system - final String operatingSystem; - - /// Processors count - final int processorsCount; - - /// Locale - final String locale; - - /// Device representation - final String deviceVersion; - - /// Device logical screen size - final String deviceScreenSize; - - /// App launched timestamp - final DateTime appLaunchedTimestamp; - - /// Convert to headers - Map toHeaders() => { - 'X-Meta-Environment': environment, - 'X-Meta-Is-Web': isWeb ? 'true' : 'false', - 'X-Meta-Is-Release': isRelease ? 'true' : 'false', - 'X-Meta-App-Version': appVersion, - 'X-Meta-App-Version-Major': appVersionMajor.toString(), - 'X-Meta-App-Version-Minor': appVersionMinor.toString(), - 'X-Meta-App-Version-Patch': appVersionPatch.toString(), - 'X-Meta-App-Build-Timestamp': appBuildTimestamp.toString(), - 'X-Meta-App-Name': appName, - 'X-Meta-Operating-System': operatingSystem, - 'X-Meta-Processors-Count': processorsCount.toString(), - 'X-Meta-Locale': locale, - 'X-Meta-Device-Version': deviceVersion, - 'X-Meta-Device-Screen-Size': deviceScreenSize, - 'X-Meta-App-Launched-Timestamp': - appLaunchedTimestamp.millisecondsSinceEpoch.toString(), - }; -} diff --git a/example/lib/src/feature/dependencies/model/dependencies.dart b/example/lib/src/feature/dependencies/model/dependencies.dart deleted file mode 100644 index 3087822..0000000 --- a/example/lib/src/feature/dependencies/model/dependencies.dart +++ /dev/null @@ -1,14 +0,0 @@ -import 'package:spinifyapp/src/feature/authentication/data/authentication_repository.dart'; -import 'package:spinifyapp/src/feature/chat/data/chat_repository.dart'; -import 'package:spinifyapp/src/feature/dependencies/model/app_metadata.dart'; - -abstract interface class Dependencies { - /// App metadata - abstract final AppMetadata appMetadata; - - /// Authentication repository - abstract final IAuthenticationRepository authenticationRepository; - - /// Chat repository - abstract final IChatRepository chatRepository; -} diff --git a/example/lib/src/feature/dependencies/widget/dependencies_scope.dart b/example/lib/src/feature/dependencies/widget/dependencies_scope.dart deleted file mode 100644 index d44d74e..0000000 --- a/example/lib/src/feature/dependencies/widget/dependencies_scope.dart +++ /dev/null @@ -1,83 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/widgets.dart'; -import 'package:spinifyapp/src/feature/dependencies/model/dependencies.dart'; - -/// {@template dependencies_scope} -/// DependenciesScope widget. -/// {@endtemplate} -class DependenciesScope extends StatelessWidget { - /// {@macro dependencies_scope} - const DependenciesScope({ - required this.initialization, - required this.splashScreen, - required this.child, - this.errorBuilder, - super.key, - }); - - /// The state from the closest instance of this class - /// that encloses the given context, if any. - /// e.g. `DependenciesScope.maybeOf(context)`. - static Dependencies? maybeOf(BuildContext context) => switch (context - .getElementForInheritedWidgetOfExactType<_InheritedDependencies>() - ?.widget) { - _InheritedDependencies inheritedDependencies => - inheritedDependencies.dependencies, - _ => null, - }; - - static Never _notFoundInheritedWidgetOfExactType() => throw ArgumentError( - 'Out of scope, not found inherited widget ' - 'a DependenciesScope of the exact type', - 'out_of_scope', - ); - - /// The state from the closest instance of this class - /// that encloses the given context. - /// e.g. `DependenciesScope.of(context)` - static Dependencies of(BuildContext context) => - maybeOf(context) ?? _notFoundInheritedWidgetOfExactType(); - - /// Initialization of the dependencies. - final Future initialization; - - /// Splash screen widget. - final Widget splashScreen; - - /// Error widget. - final Widget Function(Object error, StackTrace? stackTrace)? errorBuilder; - - /// The widget below this widget in the tree. - final Widget child; - - @override - Widget build(BuildContext context) => FutureBuilder( - future: initialization, - builder: (context, snapshot) => - switch ((snapshot.data, snapshot.error, snapshot.stackTrace)) { - (Dependencies dependencies, null, null) => _InheritedDependencies( - dependencies: dependencies, - child: child, - ), - (_, Object error, StackTrace? stackTrace) => - errorBuilder?.call(error, stackTrace) ?? ErrorWidget(error), - _ => splashScreen, - }, - ); -} - -/// {@template inherited_dependencies} -/// InheritedDependencies widget. -/// {@endtemplate} -class _InheritedDependencies extends InheritedWidget { - /// {@macro inherited_dependencies} - const _InheritedDependencies({ - required this.dependencies, - required super.child, - }); - - final Dependencies dependencies; - - @override - bool updateShouldNotify(covariant _InheritedDependencies oldWidget) => false; -} diff --git a/example/lib/src/feature/dependencies/widget/initialization_splash_screen.dart b/example/lib/src/feature/dependencies/widget/initialization_splash_screen.dart deleted file mode 100644 index 1e5139c..0000000 --- a/example/lib/src/feature/dependencies/widget/initialization_splash_screen.dart +++ /dev/null @@ -1,62 +0,0 @@ -import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; -import 'package:spinifyapp/src/common/widget/radial_progress_indicator.dart'; - -class InitializationSplashScreen extends StatelessWidget { - const InitializationSplashScreen({required this.progress, super.key}); - - final ValueListenable<({int progress, String message})> progress; - - @override - Widget build(BuildContext context) { - final theme = View.of(context).platformDispatcher.platformBrightness == - Brightness.dark - ? ThemeData.dark() - : ThemeData.light(); - return Material( - color: theme.primaryColor, - child: Directionality( - textDirection: TextDirection.ltr, - child: Center( - child: ListView( - shrinkWrap: true, - children: [ - RadialProgressIndicator( - size: 128, - child: ValueListenableBuilder<({String message, int progress})>( - valueListenable: progress, - builder: (context, value, _) => Text( - '${value.progress}%', - overflow: TextOverflow.ellipsis, - maxLines: 1, - textAlign: TextAlign.center, - style: theme.textTheme.titleLarge?.copyWith( - height: 1, - fontSize: 32, - ), - ), - ), - ), - const SizedBox(height: 16), - Opacity( - opacity: .25, - child: ValueListenableBuilder<({String message, int progress})>( - valueListenable: progress, - builder: (context, value, _) => Text( - value.message, - overflow: TextOverflow.ellipsis, - maxLines: 3, - textAlign: TextAlign.center, - style: theme.textTheme.labelSmall?.copyWith( - height: 1, - ), - ), - ), - ), - ], - ), - ), - ), - ); - } -} diff --git a/example/linux/.gitignore b/example/linux/.gitignore deleted file mode 100644 index d3896c9..0000000 --- a/example/linux/.gitignore +++ /dev/null @@ -1 +0,0 @@ -flutter/ephemeral diff --git a/example/linux/CMakeLists.txt b/example/linux/CMakeLists.txt deleted file mode 100644 index ac24608..0000000 --- a/example/linux/CMakeLists.txt +++ /dev/null @@ -1,139 +0,0 @@ -# Project-level configuration. -cmake_minimum_required(VERSION 3.10) -project(runner LANGUAGES CXX) - -# The name of the executable created for the application. Change this to change -# the on-disk name of your application. -set(BINARY_NAME "spinifyapp") -# The unique GTK application identifier for this application. See: -# https://wiki.gnome.org/HowDoI/ChooseApplicationID -set(APPLICATION_ID "dev.plugfox.spinify.spinifyapp") - -# Explicitly opt in to modern CMake behaviors to avoid warnings with recent -# versions of CMake. -cmake_policy(SET CMP0063 NEW) - -# Load bundled libraries from the lib/ directory relative to the binary. -set(CMAKE_INSTALL_RPATH "$ORIGIN/lib") - -# Root filesystem for cross-building. -if(FLUTTER_TARGET_PLATFORM_SYSROOT) - set(CMAKE_SYSROOT ${FLUTTER_TARGET_PLATFORM_SYSROOT}) - set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT}) - set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) - set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) - set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) - set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) -endif() - -# Define build configuration options. -if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) - set(CMAKE_BUILD_TYPE "Debug" CACHE - STRING "Flutter build mode" FORCE) - set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS - "Debug" "Profile" "Release") -endif() - -# Compilation settings that should be applied to most targets. -# -# Be cautious about adding new options here, as plugins use this function by -# default. In most cases, you should add new options to specific targets instead -# of modifying this function. -function(APPLY_STANDARD_SETTINGS TARGET) - target_compile_features(${TARGET} PUBLIC cxx_std_14) - target_compile_options(${TARGET} PRIVATE -Wall -Werror) - target_compile_options(${TARGET} PRIVATE "$<$>:-O3>") - target_compile_definitions(${TARGET} PRIVATE "$<$>:NDEBUG>") -endfunction() - -# Flutter library and tool build rules. -set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") -add_subdirectory(${FLUTTER_MANAGED_DIR}) - -# System-level dependencies. -find_package(PkgConfig REQUIRED) -pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) - -add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}") - -# Define the application target. To change its name, change BINARY_NAME above, -# not the value here, or `flutter run` will no longer work. -# -# Any new source files that you add to the application should be added here. -add_executable(${BINARY_NAME} - "main.cc" - "my_application.cc" - "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" -) - -# Apply the standard set of build settings. This can be removed for applications -# that need different build settings. -apply_standard_settings(${BINARY_NAME}) - -# Add dependency libraries. Add any application-specific dependencies here. -target_link_libraries(${BINARY_NAME} PRIVATE flutter) -target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK) - -# Run the Flutter tool portions of the build. This must not be removed. -add_dependencies(${BINARY_NAME} flutter_assemble) - -# Only the install-generated bundle's copy of the executable will launch -# correctly, since the resources must in the right relative locations. To avoid -# people trying to run the unbundled copy, put it in a subdirectory instead of -# the default top-level location. -set_target_properties(${BINARY_NAME} - PROPERTIES - RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run" -) - - -# Generated plugin build rules, which manage building the plugins and adding -# them to the application. -include(flutter/generated_plugins.cmake) - - -# === Installation === -# By default, "installing" just makes a relocatable bundle in the build -# directory. -set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle") -if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) - set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) -endif() - -# Start with a clean build bundle directory every time. -install(CODE " - file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\") - " COMPONENT Runtime) - -set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") -set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib") - -install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" - COMPONENT Runtime) - -install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" - COMPONENT Runtime) - -install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" - COMPONENT Runtime) - -foreach(bundled_library ${PLUGIN_BUNDLED_LIBRARIES}) - install(FILES "${bundled_library}" - DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" - COMPONENT Runtime) -endforeach(bundled_library) - -# Fully re-copy the assets directory on each build to avoid having stale files -# from a previous install. -set(FLUTTER_ASSET_DIR_NAME "flutter_assets") -install(CODE " - file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") - " COMPONENT Runtime) -install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" - DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) - -# Install the AOT library on non-Debug builds only. -if(NOT CMAKE_BUILD_TYPE MATCHES "Debug") - install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" - COMPONENT Runtime) -endif() diff --git a/example/linux/flutter/CMakeLists.txt b/example/linux/flutter/CMakeLists.txt deleted file mode 100644 index d5bd016..0000000 --- a/example/linux/flutter/CMakeLists.txt +++ /dev/null @@ -1,88 +0,0 @@ -# This file controls Flutter-level build steps. It should not be edited. -cmake_minimum_required(VERSION 3.10) - -set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") - -# Configuration provided via flutter tool. -include(${EPHEMERAL_DIR}/generated_config.cmake) - -# TODO: Move the rest of this into files in ephemeral. See -# https://github.com/flutter/flutter/issues/57146. - -# Serves the same purpose as list(TRANSFORM ... PREPEND ...), -# which isn't available in 3.10. -function(list_prepend LIST_NAME PREFIX) - set(NEW_LIST "") - foreach(element ${${LIST_NAME}}) - list(APPEND NEW_LIST "${PREFIX}${element}") - endforeach(element) - set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE) -endfunction() - -# === Flutter Library === -# System-level dependencies. -find_package(PkgConfig REQUIRED) -pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) -pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0) -pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0) - -set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so") - -# Published to parent scope for install step. -set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) -set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) -set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) -set(AOT_LIBRARY "${PROJECT_DIR}/build/lib/libapp.so" PARENT_SCOPE) - -list(APPEND FLUTTER_LIBRARY_HEADERS - "fl_basic_message_channel.h" - "fl_binary_codec.h" - "fl_binary_messenger.h" - "fl_dart_project.h" - "fl_engine.h" - "fl_json_message_codec.h" - "fl_json_method_codec.h" - "fl_message_codec.h" - "fl_method_call.h" - "fl_method_channel.h" - "fl_method_codec.h" - "fl_method_response.h" - "fl_plugin_registrar.h" - "fl_plugin_registry.h" - "fl_standard_message_codec.h" - "fl_standard_method_codec.h" - "fl_string_codec.h" - "fl_value.h" - "fl_view.h" - "flutter_linux.h" -) -list_prepend(FLUTTER_LIBRARY_HEADERS "${EPHEMERAL_DIR}/flutter_linux/") -add_library(flutter INTERFACE) -target_include_directories(flutter INTERFACE - "${EPHEMERAL_DIR}" -) -target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}") -target_link_libraries(flutter INTERFACE - PkgConfig::GTK - PkgConfig::GLIB - PkgConfig::GIO -) -add_dependencies(flutter flutter_assemble) - -# === Flutter tool backend === -# _phony_ is a non-existent file to force this command to run every time, -# since currently there's no way to get a full input/output list from the -# flutter tool. -add_custom_command( - OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} - ${CMAKE_CURRENT_BINARY_DIR}/_phony_ - COMMAND ${CMAKE_COMMAND} -E env - ${FLUTTER_TOOL_ENVIRONMENT} - "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh" - ${FLUTTER_TARGET_PLATFORM} ${CMAKE_BUILD_TYPE} - VERBATIM -) -add_custom_target(flutter_assemble DEPENDS - "${FLUTTER_LIBRARY}" - ${FLUTTER_LIBRARY_HEADERS} -) diff --git a/example/linux/flutter/generated_plugin_registrant.cc b/example/linux/flutter/generated_plugin_registrant.cc deleted file mode 100644 index b7a6d08..0000000 --- a/example/linux/flutter/generated_plugin_registrant.cc +++ /dev/null @@ -1,19 +0,0 @@ -// -// Generated file. Do not edit. -// - -// clang-format off - -#include "generated_plugin_registrant.h" - -#include -#include - -void fl_register_plugins(FlPluginRegistry* registry) { - g_autoptr(FlPluginRegistrar) screen_retriever_registrar = - fl_plugin_registry_get_registrar_for_plugin(registry, "ScreenRetrieverPlugin"); - screen_retriever_plugin_register_with_registrar(screen_retriever_registrar); - g_autoptr(FlPluginRegistrar) window_manager_registrar = - fl_plugin_registry_get_registrar_for_plugin(registry, "WindowManagerPlugin"); - window_manager_plugin_register_with_registrar(window_manager_registrar); -} diff --git a/example/linux/flutter/generated_plugin_registrant.h b/example/linux/flutter/generated_plugin_registrant.h deleted file mode 100644 index e0f0a47..0000000 --- a/example/linux/flutter/generated_plugin_registrant.h +++ /dev/null @@ -1,15 +0,0 @@ -// -// Generated file. Do not edit. -// - -// clang-format off - -#ifndef GENERATED_PLUGIN_REGISTRANT_ -#define GENERATED_PLUGIN_REGISTRANT_ - -#include - -// Registers Flutter plugins. -void fl_register_plugins(FlPluginRegistry* registry); - -#endif // GENERATED_PLUGIN_REGISTRANT_ diff --git a/example/linux/flutter/generated_plugins.cmake b/example/linux/flutter/generated_plugins.cmake deleted file mode 100644 index 913ac71..0000000 --- a/example/linux/flutter/generated_plugins.cmake +++ /dev/null @@ -1,25 +0,0 @@ -# -# Generated file, do not edit. -# - -list(APPEND FLUTTER_PLUGIN_LIST - screen_retriever - window_manager -) - -list(APPEND FLUTTER_FFI_PLUGIN_LIST -) - -set(PLUGIN_BUNDLED_LIBRARIES) - -foreach(plugin ${FLUTTER_PLUGIN_LIST}) - add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin}) - target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) - list(APPEND PLUGIN_BUNDLED_LIBRARIES $) - list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) -endforeach(plugin) - -foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) - add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin}) - list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) -endforeach(ffi_plugin) diff --git a/example/linux/main.cc b/example/linux/main.cc deleted file mode 100644 index e7c5c54..0000000 --- a/example/linux/main.cc +++ /dev/null @@ -1,6 +0,0 @@ -#include "my_application.h" - -int main(int argc, char** argv) { - g_autoptr(MyApplication) app = my_application_new(); - return g_application_run(G_APPLICATION(app), argc, argv); -} diff --git a/example/linux/my_application.cc b/example/linux/my_application.cc deleted file mode 100644 index c44e7ba..0000000 --- a/example/linux/my_application.cc +++ /dev/null @@ -1,108 +0,0 @@ -#include "my_application.h" - -#include -#ifdef GDK_WINDOWING_X11 -#include -#endif - -#include "flutter/generated_plugin_registrant.h" - -struct _MyApplication { - GtkApplication parent_instance; - char **dart_entrypoint_arguments; -}; - -G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION) - -// Implements GApplication::activate. -static void my_application_activate(GApplication *application) { - MyApplication *self = MY_APPLICATION(application); - GtkWindow *window = - GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application))); - - // Use a header bar when running in GNOME as this is the common style used - // by applications and is the setup most users will be using (e.g. Ubuntu - // desktop). - // If running on X and not using GNOME then just use a traditional title bar - // in case the window manager does more exotic layout, e.g. tiling. - // If running on Wayland assume the header bar will work (may need changing - // if future cases occur). - gboolean use_header_bar = TRUE; -#ifdef GDK_WINDOWING_X11 - GdkScreen *screen = gtk_window_get_screen(window); - if (GDK_IS_X11_SCREEN(screen)) { - const gchar *wm_name = gdk_x11_screen_get_window_manager_name(screen); - if (g_strcmp0(wm_name, "GNOME Shell") != 0) { - use_header_bar = FALSE; - } - } -#endif - if (use_header_bar) { - GtkHeaderBar *header_bar = GTK_HEADER_BAR(gtk_header_bar_new()); - gtk_widget_show(GTK_WIDGET(header_bar)); - gtk_header_bar_set_title(header_bar, "spinifyapp"); - gtk_header_bar_set_show_close_button(header_bar, TRUE); - gtk_window_set_titlebar(window, GTK_WIDGET(header_bar)); - } else { - gtk_window_set_title(window, "spinifyapp"); - } - - gtk_window_set_default_size(window, 1280, 720); - // gtk_widget_show(GTK_WIDGET(window)); - gtk_widget_realize(GTK_WIDGET(window)); - - g_autoptr(FlDartProject) project = fl_dart_project_new(); - fl_dart_project_set_dart_entrypoint_arguments( - project, self->dart_entrypoint_arguments); - - FlView *view = fl_view_new(project); - gtk_widget_show(GTK_WIDGET(view)); - gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(view)); - - fl_register_plugins(FL_PLUGIN_REGISTRY(view)); - - gtk_widget_grab_focus(GTK_WIDGET(view)); -} - -// Implements GApplication::local_command_line. -static gboolean my_application_local_command_line(GApplication *application, - gchar ***arguments, - int *exit_status) { - MyApplication *self = MY_APPLICATION(application); - // Strip out the first argument as it is the binary name. - self->dart_entrypoint_arguments = g_strdupv(*arguments + 1); - - g_autoptr(GError) error = nullptr; - if (!g_application_register(application, nullptr, &error)) { - g_warning("Failed to register: %s", error->message); - *exit_status = 1; - return TRUE; - } - - g_application_activate(application); - *exit_status = 0; - - return TRUE; -} - -// Implements GObject::dispose. -static void my_application_dispose(GObject *object) { - MyApplication *self = MY_APPLICATION(object); - g_clear_pointer(&self->dart_entrypoint_arguments, g_strfreev); - G_OBJECT_CLASS(my_application_parent_class)->dispose(object); -} - -static void my_application_class_init(MyApplicationClass *klass) { - G_APPLICATION_CLASS(klass)->activate = my_application_activate; - G_APPLICATION_CLASS(klass)->local_command_line = - my_application_local_command_line; - G_OBJECT_CLASS(klass)->dispose = my_application_dispose; -} - -static void my_application_init(MyApplication *self) {} - -MyApplication *my_application_new() { - return MY_APPLICATION(g_object_new(my_application_get_type(), - "application-id", APPLICATION_ID, "flags", - G_APPLICATION_NON_UNIQUE, nullptr)); -} diff --git a/example/linux/my_application.h b/example/linux/my_application.h deleted file mode 100644 index 72271d5..0000000 --- a/example/linux/my_application.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef FLUTTER_MY_APPLICATION_H_ -#define FLUTTER_MY_APPLICATION_H_ - -#include - -G_DECLARE_FINAL_TYPE(MyApplication, my_application, MY, APPLICATION, - GtkApplication) - -/** - * my_application_new: - * - * Creates a new Flutter-based application. - * - * Returns: a new #MyApplication. - */ -MyApplication* my_application_new(); - -#endif // FLUTTER_MY_APPLICATION_H_ diff --git a/example/macos/.gitignore b/example/macos/.gitignore deleted file mode 100644 index 746adbb..0000000 --- a/example/macos/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -# Flutter-related -**/Flutter/ephemeral/ -**/Pods/ - -# Xcode-related -**/dgph -**/xcuserdata/ diff --git a/example/macos/Flutter/Flutter-Debug.xcconfig b/example/macos/Flutter/Flutter-Debug.xcconfig deleted file mode 100644 index 4b81f9b..0000000 --- a/example/macos/Flutter/Flutter-Debug.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" -#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/example/macos/Flutter/Flutter-Release.xcconfig b/example/macos/Flutter/Flutter-Release.xcconfig deleted file mode 100644 index 5caa9d1..0000000 --- a/example/macos/Flutter/Flutter-Release.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" -#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/example/macos/Flutter/GeneratedPluginRegistrant.swift b/example/macos/Flutter/GeneratedPluginRegistrant.swift deleted file mode 100644 index b622947..0000000 --- a/example/macos/Flutter/GeneratedPluginRegistrant.swift +++ /dev/null @@ -1,14 +0,0 @@ -// -// Generated file. Do not edit. -// - -import FlutterMacOS -import Foundation - -import screen_retriever -import window_manager - -func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { - ScreenRetrieverPlugin.register(with: registry.registrar(forPlugin: "ScreenRetrieverPlugin")) - WindowManagerPlugin.register(with: registry.registrar(forPlugin: "WindowManagerPlugin")) -} diff --git a/example/macos/Podfile b/example/macos/Podfile deleted file mode 100644 index c795730..0000000 --- a/example/macos/Podfile +++ /dev/null @@ -1,43 +0,0 @@ -platform :osx, '10.14' - -# CocoaPods analytics sends network stats synchronously affecting flutter build latency. -ENV['COCOAPODS_DISABLE_STATS'] = 'true' - -project 'Runner', { - 'Debug' => :debug, - 'Profile' => :release, - 'Release' => :release, -} - -def flutter_root - generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'ephemeral', 'Flutter-Generated.xcconfig'), __FILE__) - unless File.exist?(generated_xcode_build_settings_path) - raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure \"flutter pub get\" is executed first" - end - - File.foreach(generated_xcode_build_settings_path) do |line| - matches = line.match(/FLUTTER_ROOT\=(.*)/) - return matches[1].strip if matches - end - raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Flutter-Generated.xcconfig, then run \"flutter pub get\"" -end - -require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) - -flutter_macos_podfile_setup - -target 'Runner' do - use_frameworks! - use_modular_headers! - - flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) - target 'RunnerTests' do - inherit! :search_paths - end -end - -post_install do |installer| - installer.pods_project.targets.each do |target| - flutter_additional_macos_build_settings(target) - end -end diff --git a/example/macos/Runner.xcodeproj/project.pbxproj b/example/macos/Runner.xcodeproj/project.pbxproj deleted file mode 100644 index b26d7a9..0000000 --- a/example/macos/Runner.xcodeproj/project.pbxproj +++ /dev/null @@ -1,695 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 54; - objects = { - -/* Begin PBXAggregateTarget section */ - 33CC111A2044C6BA0003C045 /* Flutter Assemble */ = { - isa = PBXAggregateTarget; - buildConfigurationList = 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */; - buildPhases = ( - 33CC111E2044C6BF0003C045 /* ShellScript */, - ); - dependencies = ( - ); - name = "Flutter Assemble"; - productName = FLX; - }; -/* End PBXAggregateTarget section */ - -/* Begin PBXBuildFile section */ - 331C80D8294CF71000263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C80D7294CF71000263BE5 /* RunnerTests.swift */; }; - 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; }; - 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC10F02044A3C60003C045 /* AppDelegate.swift */; }; - 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; - 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; - 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - 331C80D9294CF71000263BE5 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 33CC10E52044A3C60003C045 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 33CC10EC2044A3C60003C045; - remoteInfo = Runner; - }; - 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 33CC10E52044A3C60003C045 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 33CC111A2044C6BA0003C045; - remoteInfo = FLX; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 33CC110E2044A8840003C045 /* Bundle Framework */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - ); - name = "Bundle Framework"; - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 331C80D5294CF71000263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 331C80D7294CF71000263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; - 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; }; - 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = ""; }; - 33CC10ED2044A3C60003C045 /* spinifyapp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "spinifyapp.app"; sourceTree = BUILT_PRODUCTS_DIR; }; - 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = ""; }; - 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; - 33CC10F72044A3C60003C045 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Runner/Info.plist; sourceTree = ""; }; - 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainFlutterWindow.swift; sourceTree = ""; }; - 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Debug.xcconfig"; sourceTree = ""; }; - 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Release.xcconfig"; sourceTree = ""; }; - 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Flutter-Generated.xcconfig"; path = "ephemeral/Flutter-Generated.xcconfig"; sourceTree = ""; }; - 33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = ""; }; - 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = ""; }; - 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = ""; }; - 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; - 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 331C80D2294CF70F00263BE5 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 33CC10EA2044A3C60003C045 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 331C80D6294CF71000263BE5 /* RunnerTests */ = { - isa = PBXGroup; - children = ( - 331C80D7294CF71000263BE5 /* RunnerTests.swift */, - ); - path = RunnerTests; - sourceTree = ""; - }; - 33BA886A226E78AF003329D5 /* Configs */ = { - isa = PBXGroup; - children = ( - 33E5194F232828860026EE4D /* AppInfo.xcconfig */, - 9740EEB21CF90195004384FC /* Debug.xcconfig */, - 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, - 333000ED22D3DE5D00554162 /* Warnings.xcconfig */, - ); - path = Configs; - sourceTree = ""; - }; - 33CC10E42044A3C60003C045 = { - isa = PBXGroup; - children = ( - 33FAB671232836740065AC1E /* Runner */, - 33CEB47122A05771004F2AC0 /* Flutter */, - 331C80D6294CF71000263BE5 /* RunnerTests */, - 33CC10EE2044A3C60003C045 /* Products */, - D73912EC22F37F3D000D13A0 /* Frameworks */, - ); - sourceTree = ""; - }; - 33CC10EE2044A3C60003C045 /* Products */ = { - isa = PBXGroup; - children = ( - 33CC10ED2044A3C60003C045 /* spinifyapp.app */, - 331C80D5294CF71000263BE5 /* RunnerTests.xctest */, - ); - name = Products; - sourceTree = ""; - }; - 33CC11242044D66E0003C045 /* Resources */ = { - isa = PBXGroup; - children = ( - 33CC10F22044A3C60003C045 /* Assets.xcassets */, - 33CC10F42044A3C60003C045 /* MainMenu.xib */, - 33CC10F72044A3C60003C045 /* Info.plist */, - ); - name = Resources; - path = ..; - sourceTree = ""; - }; - 33CEB47122A05771004F2AC0 /* Flutter */ = { - isa = PBXGroup; - children = ( - 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */, - 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */, - 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */, - 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */, - ); - path = Flutter; - sourceTree = ""; - }; - 33FAB671232836740065AC1E /* Runner */ = { - isa = PBXGroup; - children = ( - 33CC10F02044A3C60003C045 /* AppDelegate.swift */, - 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */, - 33E51913231747F40026EE4D /* DebugProfile.entitlements */, - 33E51914231749380026EE4D /* Release.entitlements */, - 33CC11242044D66E0003C045 /* Resources */, - 33BA886A226E78AF003329D5 /* Configs */, - ); - path = Runner; - sourceTree = ""; - }; - D73912EC22F37F3D000D13A0 /* Frameworks */ = { - isa = PBXGroup; - children = ( - ); - name = Frameworks; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 331C80D4294CF70F00263BE5 /* RunnerTests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 331C80DE294CF71000263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; - buildPhases = ( - 331C80D1294CF70F00263BE5 /* Sources */, - 331C80D2294CF70F00263BE5 /* Frameworks */, - 331C80D3294CF70F00263BE5 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - 331C80DA294CF71000263BE5 /* PBXTargetDependency */, - ); - name = RunnerTests; - productName = RunnerTests; - productReference = 331C80D5294CF71000263BE5 /* RunnerTests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; - 33CC10EC2044A3C60003C045 /* Runner */ = { - isa = PBXNativeTarget; - buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */; - buildPhases = ( - 33CC10E92044A3C60003C045 /* Sources */, - 33CC10EA2044A3C60003C045 /* Frameworks */, - 33CC10EB2044A3C60003C045 /* Resources */, - 33CC110E2044A8840003C045 /* Bundle Framework */, - 3399D490228B24CF009A79C7 /* ShellScript */, - ); - buildRules = ( - ); - dependencies = ( - 33CC11202044C79F0003C045 /* PBXTargetDependency */, - ); - name = Runner; - productName = Runner; - productReference = 33CC10ED2044A3C60003C045 /* spinifyapp.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 33CC10E52044A3C60003C045 /* Project object */ = { - isa = PBXProject; - attributes = { - LastSwiftUpdateCheck = 0920; - LastUpgradeCheck = 1430; - ORGANIZATIONNAME = ""; - TargetAttributes = { - 331C80D4294CF70F00263BE5 = { - CreatedOnToolsVersion = 14.0; - TestTargetID = 33CC10EC2044A3C60003C045; - }; - 33CC10EC2044A3C60003C045 = { - CreatedOnToolsVersion = 9.2; - LastSwiftMigration = 1100; - ProvisioningStyle = Automatic; - SystemCapabilities = { - com.apple.Sandbox = { - enabled = 1; - }; - }; - }; - 33CC111A2044C6BA0003C045 = { - CreatedOnToolsVersion = 9.2; - ProvisioningStyle = Manual; - }; - }; - }; - buildConfigurationList = 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */; - compatibilityVersion = "Xcode 9.3"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 33CC10E42044A3C60003C045; - productRefGroup = 33CC10EE2044A3C60003C045 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 33CC10EC2044A3C60003C045 /* Runner */, - 331C80D4294CF70F00263BE5 /* RunnerTests */, - 33CC111A2044C6BA0003C045 /* Flutter Assemble */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 331C80D3294CF70F00263BE5 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 33CC10EB2044A3C60003C045 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */, - 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 3399D490228B24CF009A79C7 /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - alwaysOutOfDate = 1; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - ); - outputFileListPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh embed\n"; - }; - 33CC111E2044C6BF0003C045 /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - Flutter/ephemeral/FlutterInputs.xcfilelist, - ); - inputPaths = ( - Flutter/ephemeral/tripwire, - ); - outputFileListPaths = ( - Flutter/ephemeral/FlutterOutputs.xcfilelist, - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire"; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 331C80D1294CF70F00263BE5 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 331C80D8294CF71000263BE5 /* RunnerTests.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 33CC10E92044A3C60003C045 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */, - 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */, - 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - 331C80DA294CF71000263BE5 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 33CC10EC2044A3C60003C045 /* Runner */; - targetProxy = 331C80D9294CF71000263BE5 /* PBXContainerItemProxy */; - }; - 33CC11202044C79F0003C045 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 33CC111A2044C6BA0003C045 /* Flutter Assemble */; - targetProxy = 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin PBXVariantGroup section */ - 33CC10F42044A3C60003C045 /* MainMenu.xib */ = { - isa = PBXVariantGroup; - children = ( - 33CC10F52044A3C60003C045 /* Base */, - ); - name = MainMenu.xib; - path = Runner; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 331C80DB294CF71000263BE5 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - CURRENT_PROJECT_VERSION = 1; - GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = dev.plugfox.spinify.spinifyapp.RunnerTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 5.0; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/spinifyapp.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/spinifyapp"; - }; - name = Debug; - }; - 331C80DC294CF71000263BE5 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - CURRENT_PROJECT_VERSION = 1; - GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = dev.plugfox.spinify.spinifyapp.RunnerTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 5.0; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/spinifyapp.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/spinifyapp"; - }; - name = Release; - }; - 331C80DD294CF71000263BE5 /* Profile */ = { - isa = XCBuildConfiguration; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - CURRENT_PROJECT_VERSION = 1; - GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = dev.plugfox.spinify.spinifyapp.RunnerTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 5.0; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/spinifyapp.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/spinifyapp"; - }; - name = Profile; - }; - 338D0CE9231458BD00FA5F75 /* Profile */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CODE_SIGN_IDENTITY = "-"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.14; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = macosx; - SWIFT_COMPILATION_MODE = wholemodule; - SWIFT_OPTIMIZATION_LEVEL = "-O"; - }; - name = Profile; - }; - 338D0CEA231458BD00FA5F75 /* Profile */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; - CODE_SIGN_STYLE = Automatic; - COMBINE_HIDPI_IMAGES = YES; - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/../Frameworks", - ); - PROVISIONING_PROFILE_SPECIFIER = ""; - SWIFT_VERSION = 5.0; - }; - name = Profile; - }; - 338D0CEB231458BD00FA5F75 /* Profile */ = { - isa = XCBuildConfiguration; - buildSettings = { - CODE_SIGN_STYLE = Manual; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Profile; - }; - 33CC10F92044A3C60003C045 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CODE_SIGN_IDENTITY = "-"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.14; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = macosx; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - }; - name = Debug; - }; - 33CC10FA2044A3C60003C045 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CODE_SIGN_IDENTITY = "-"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.14; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = macosx; - SWIFT_COMPILATION_MODE = wholemodule; - SWIFT_OPTIMIZATION_LEVEL = "-O"; - }; - name = Release; - }; - 33CC10FC2044A3C60003C045 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; - CODE_SIGN_STYLE = Automatic; - COMBINE_HIDPI_IMAGES = YES; - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/../Frameworks", - ); - PROVISIONING_PROFILE_SPECIFIER = ""; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.0; - }; - name = Debug; - }; - 33CC10FD2044A3C60003C045 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements; - CODE_SIGN_STYLE = Automatic; - COMBINE_HIDPI_IMAGES = YES; - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/../Frameworks", - ); - PROVISIONING_PROFILE_SPECIFIER = ""; - SWIFT_VERSION = 5.0; - }; - name = Release; - }; - 33CC111C2044C6BA0003C045 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CODE_SIGN_STYLE = Manual; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 33CC111D2044C6BA0003C045 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CODE_SIGN_STYLE = Automatic; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 331C80DE294CF71000263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 331C80DB294CF71000263BE5 /* Debug */, - 331C80DC294CF71000263BE5 /* Release */, - 331C80DD294CF71000263BE5 /* Profile */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 33CC10F92044A3C60003C045 /* Debug */, - 33CC10FA2044A3C60003C045 /* Release */, - 338D0CE9231458BD00FA5F75 /* Profile */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 33CC10FC2044A3C60003C045 /* Debug */, - 33CC10FD2044A3C60003C045 /* Release */, - 338D0CEA231458BD00FA5F75 /* Profile */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 33CC111C2044C6BA0003C045 /* Debug */, - 33CC111D2044C6BA0003C045 /* Release */, - 338D0CEB231458BD00FA5F75 /* Profile */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 33CC10E52044A3C60003C045 /* Project object */; -} diff --git a/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d9810..0000000 --- a/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme deleted file mode 100644 index c30f04d..0000000 --- a/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ /dev/null @@ -1,98 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/example/macos/Runner.xcworkspace/contents.xcworkspacedata b/example/macos/Runner.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 1d526a1..0000000 --- a/example/macos/Runner.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d9810..0000000 --- a/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/example/macos/Runner/AppDelegate.swift b/example/macos/Runner/AppDelegate.swift deleted file mode 100644 index a8565c3..0000000 --- a/example/macos/Runner/AppDelegate.swift +++ /dev/null @@ -1,10 +0,0 @@ -import Cocoa -import FlutterMacOS - -@NSApplicationMain -class AppDelegate: FlutterAppDelegate { - override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { - //return true - return false - } -} diff --git a/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index a2ec33f..0000000 --- a/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "images" : [ - { - "size" : "16x16", - "idiom" : "mac", - "filename" : "app_icon_16.png", - "scale" : "1x" - }, - { - "size" : "16x16", - "idiom" : "mac", - "filename" : "app_icon_32.png", - "scale" : "2x" - }, - { - "size" : "32x32", - "idiom" : "mac", - "filename" : "app_icon_32.png", - "scale" : "1x" - }, - { - "size" : "32x32", - "idiom" : "mac", - "filename" : "app_icon_64.png", - "scale" : "2x" - }, - { - "size" : "128x128", - "idiom" : "mac", - "filename" : "app_icon_128.png", - "scale" : "1x" - }, - { - "size" : "128x128", - "idiom" : "mac", - "filename" : "app_icon_256.png", - "scale" : "2x" - }, - { - "size" : "256x256", - "idiom" : "mac", - "filename" : "app_icon_256.png", - "scale" : "1x" - }, - { - "size" : "256x256", - "idiom" : "mac", - "filename" : "app_icon_512.png", - "scale" : "2x" - }, - { - "size" : "512x512", - "idiom" : "mac", - "filename" : "app_icon_512.png", - "scale" : "1x" - }, - { - "size" : "512x512", - "idiom" : "mac", - "filename" : "app_icon_1024.png", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} diff --git a/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png b/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png deleted file mode 100644 index 82b6f9d..0000000 Binary files a/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png and /dev/null differ diff --git a/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png b/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png deleted file mode 100644 index 13b35eb..0000000 Binary files a/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png and /dev/null differ diff --git a/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png b/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png deleted file mode 100644 index 0a3f5fa..0000000 Binary files a/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png and /dev/null differ diff --git a/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png b/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png deleted file mode 100644 index bdb5722..0000000 Binary files a/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png and /dev/null differ diff --git a/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png b/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png deleted file mode 100644 index f083318..0000000 Binary files a/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png and /dev/null differ diff --git a/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png b/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png deleted file mode 100644 index 326c0e7..0000000 Binary files a/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png and /dev/null differ diff --git a/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png b/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png deleted file mode 100644 index 2f1632c..0000000 Binary files a/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png and /dev/null differ diff --git a/example/macos/Runner/Base.lproj/MainMenu.xib b/example/macos/Runner/Base.lproj/MainMenu.xib deleted file mode 100644 index 80e867a..0000000 --- a/example/macos/Runner/Base.lproj/MainMenu.xib +++ /dev/null @@ -1,343 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/example/macos/Runner/Configs/AppInfo.xcconfig b/example/macos/Runner/Configs/AppInfo.xcconfig deleted file mode 100644 index 67ee153..0000000 --- a/example/macos/Runner/Configs/AppInfo.xcconfig +++ /dev/null @@ -1,14 +0,0 @@ -// Application-level settings for the Runner target. -// -// This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the -// future. If not, the values below would default to using the project name when this becomes a -// 'flutter create' template. - -// The application's name. By default this is also the title of the Flutter window. -PRODUCT_NAME = spinifyapp - -// The application's bundle identifier -PRODUCT_BUNDLE_IDENTIFIER = dev.plugfox.spinify.spinifyapp - -// The copyright displayed in application information -PRODUCT_COPYRIGHT = Copyright © 2023 dev.plugfox.spinify. All rights reserved. diff --git a/example/macos/Runner/Configs/Debug.xcconfig b/example/macos/Runner/Configs/Debug.xcconfig deleted file mode 100644 index 36b0fd9..0000000 --- a/example/macos/Runner/Configs/Debug.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include "../../Flutter/Flutter-Debug.xcconfig" -#include "Warnings.xcconfig" diff --git a/example/macos/Runner/Configs/Release.xcconfig b/example/macos/Runner/Configs/Release.xcconfig deleted file mode 100644 index dff4f49..0000000 --- a/example/macos/Runner/Configs/Release.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include "../../Flutter/Flutter-Release.xcconfig" -#include "Warnings.xcconfig" diff --git a/example/macos/Runner/Configs/Warnings.xcconfig b/example/macos/Runner/Configs/Warnings.xcconfig deleted file mode 100644 index 42bcbf4..0000000 --- a/example/macos/Runner/Configs/Warnings.xcconfig +++ /dev/null @@ -1,13 +0,0 @@ -WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings -GCC_WARN_UNDECLARED_SELECTOR = YES -CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES -CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE -CLANG_WARN__DUPLICATE_METHOD_MATCH = YES -CLANG_WARN_PRAGMA_PACK = YES -CLANG_WARN_STRICT_PROTOTYPES = YES -CLANG_WARN_COMMA = YES -GCC_WARN_STRICT_SELECTOR_MATCH = YES -CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES -CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES -GCC_WARN_SHADOW = YES -CLANG_WARN_UNREACHABLE_CODE = YES diff --git a/example/macos/Runner/DebugProfile.entitlements b/example/macos/Runner/DebugProfile.entitlements deleted file mode 100644 index dddb8a3..0000000 --- a/example/macos/Runner/DebugProfile.entitlements +++ /dev/null @@ -1,12 +0,0 @@ - - - - - com.apple.security.app-sandbox - - com.apple.security.cs.allow-jit - - com.apple.security.network.server - - - diff --git a/example/macos/Runner/Info.plist b/example/macos/Runner/Info.plist deleted file mode 100644 index 4789daa..0000000 --- a/example/macos/Runner/Info.plist +++ /dev/null @@ -1,32 +0,0 @@ - - - - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIconFile - - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - APPL - CFBundleShortVersionString - $(FLUTTER_BUILD_NAME) - CFBundleVersion - $(FLUTTER_BUILD_NUMBER) - LSMinimumSystemVersion - $(MACOSX_DEPLOYMENT_TARGET) - NSHumanReadableCopyright - $(PRODUCT_COPYRIGHT) - NSMainNibFile - MainMenu - NSPrincipalClass - NSApplication - - diff --git a/example/macos/Runner/MainFlutterWindow.swift b/example/macos/Runner/MainFlutterWindow.swift deleted file mode 100644 index 1ca7bf0..0000000 --- a/example/macos/Runner/MainFlutterWindow.swift +++ /dev/null @@ -1,21 +0,0 @@ -import Cocoa -import FlutterMacOS -import window_manager - -class MainFlutterWindow: NSWindow { - override func awakeFromNib() { - let flutterViewController = FlutterViewController() - let windowFrame = self.frame - self.contentViewController = flutterViewController - self.setFrame(windowFrame, display: true) - - RegisterGeneratedPlugins(registry: flutterViewController) - - super.awakeFromNib() - } - - override public func order(_ place: NSWindow.OrderingMode, relativeTo otherWin: Int) { - super.order(place, relativeTo: otherWin) - hiddenWindowAtLaunch() - } -} diff --git a/example/macos/Runner/Release.entitlements b/example/macos/Runner/Release.entitlements deleted file mode 100644 index 852fa1a..0000000 --- a/example/macos/Runner/Release.entitlements +++ /dev/null @@ -1,8 +0,0 @@ - - - - - com.apple.security.app-sandbox - - - diff --git a/example/macos/RunnerTests/RunnerTests.swift b/example/macos/RunnerTests/RunnerTests.swift deleted file mode 100644 index 5418c9f..0000000 --- a/example/macos/RunnerTests/RunnerTests.swift +++ /dev/null @@ -1,12 +0,0 @@ -import FlutterMacOS -import Cocoa -import XCTest - -class RunnerTests: XCTestCase { - - func testExample() { - // If you add code to the Runner application, consider adding tests here. - // See https://developer.apple.com/documentation/xctest for more information about using XCTest. - } - -} diff --git a/example/pubspec.yaml b/example/pubspec.yaml deleted file mode 100644 index fe83978..0000000 --- a/example/pubspec.yaml +++ /dev/null @@ -1,113 +0,0 @@ -name: spinifyapp - -description: Spinify App Example - -publish_to: 'none' - -version: 1.0.0+1 - -homepage: https://centrifugal.dev - -repository: https://github.com/PlugFox/spinify - -issue_tracker: https://github.com/PlugFox/spinify/issues - -funding: - - https://www.buymeacoffee.com/plugfox - - https://www.patreon.com/plugfox - - https://boosty.to/plugfox - -topics: - - spinify - - centrifugo - - centrifuge - - websocket - - cross-platform - -platforms: - android: - ios: - linux: - macos: - web: - windows: - - -environment: - sdk: '>=3.1.0-63.1.beta <4.0.0' - flutter: '>=3.10.1' - - -dependencies: - # Flutter SDK - flutter: - sdk: flutter - - # Localization - flutter_localizations: - sdk: flutter - intl: any - - # Utils - collection: any - async: any - meta: any - path: any - platform_info: ^4.0.2 - win32: ^5.0.6 - crypto: ^3.0.3 - convert: ^3.1.1 - - # Desktop - window_manager: ^0.3.5 - - # Logger - l: ^4.0.2 - - # Transport - spinify: - path: ../ - - # UI - cupertino_icons: ^1.0.2 - - -dev_dependencies: - # Unit & Widget tests for Flutter - flutter_test: - sdk: flutter - # Integration tests for Flutter - integration_test: - sdk: flutter - - #mockito: ^5.4.2 - - # Codegen - build_runner: ^2.4.6 - #flutter_launcher_icons: ^0.13.1 - #flutter_native_splash: ^2.3.1 - # build_verify: ^3.1.0 - pubspec_generator: '>=4.0.0 <5.0.0' - #flutter_gen_runner: ^5.3.1 - - # Linting - flutter_lints: ^3.0.0 - - -flutter: - generate: true - uses-material-design: true - - -flutter_intl: - enabled: true - class_name: GeneratedLocalization - main_locale: en - arb_dir: lib/src/common/localization - output_dir: lib/src/common/localization/generated - use_deferred_loading: false - - -#flutter_gen: -# output: lib/src/common/constant/ -# line_length: 120 \ No newline at end of file diff --git a/example/test/widget_test.dart b/example/test/widget_test.dart deleted file mode 100644 index ab73b3a..0000000 --- a/example/test/widget_test.dart +++ /dev/null @@ -1 +0,0 @@ -void main() {} diff --git a/example/web/favicon.png b/example/web/favicon.png deleted file mode 100644 index 8aaa46a..0000000 Binary files a/example/web/favicon.png and /dev/null differ diff --git a/example/web/icons/Icon-192.png b/example/web/icons/Icon-192.png deleted file mode 100644 index b749bfe..0000000 Binary files a/example/web/icons/Icon-192.png and /dev/null differ diff --git a/example/web/icons/Icon-512.png b/example/web/icons/Icon-512.png deleted file mode 100644 index 88cfd48..0000000 Binary files a/example/web/icons/Icon-512.png and /dev/null differ diff --git a/example/web/icons/Icon-maskable-192.png b/example/web/icons/Icon-maskable-192.png deleted file mode 100644 index eb9b4d7..0000000 Binary files a/example/web/icons/Icon-maskable-192.png and /dev/null differ diff --git a/example/web/icons/Icon-maskable-512.png b/example/web/icons/Icon-maskable-512.png deleted file mode 100644 index d69c566..0000000 Binary files a/example/web/icons/Icon-maskable-512.png and /dev/null differ diff --git a/example/web/index.html b/example/web/index.html deleted file mode 100644 index 4fb3004..0000000 --- a/example/web/index.html +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Spinify - - - - - - - - - - diff --git a/example/web/manifest.json b/example/web/manifest.json deleted file mode 100644 index 2716d59..0000000 --- a/example/web/manifest.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "name": "Spinify", - "short_name": "Spinify", - "start_url": ".", - "display": "standalone", - "background_color": "#0175C2", - "theme_color": "#0175C2", - "description": "Spinify App Example", - "orientation": "portrait-primary", - "prefer_related_applications": false, - "icons": [ - { - "src": "icons/Icon-192.png", - "sizes": "192x192", - "type": "image/png" - }, - { - "src": "icons/Icon-512.png", - "sizes": "512x512", - "type": "image/png" - }, - { - "src": "icons/Icon-maskable-192.png", - "sizes": "192x192", - "type": "image/png", - "purpose": "maskable" - }, - { - "src": "icons/Icon-maskable-512.png", - "sizes": "512x512", - "type": "image/png", - "purpose": "maskable" - } - ] -} diff --git a/example/windows/.gitignore b/example/windows/.gitignore deleted file mode 100644 index d492d0d..0000000 --- a/example/windows/.gitignore +++ /dev/null @@ -1,17 +0,0 @@ -flutter/ephemeral/ - -# Visual Studio user-specific files. -*.suo -*.user -*.userosscache -*.sln.docstates - -# Visual Studio build-related files. -x64/ -x86/ - -# Visual Studio cache files -# files ending in .cache can be ignored -*.[Cc]ache -# but keep track of directories ending in .cache -!*.[Cc]ache/ diff --git a/example/windows/CMakeLists.txt b/example/windows/CMakeLists.txt deleted file mode 100644 index 0970965..0000000 --- a/example/windows/CMakeLists.txt +++ /dev/null @@ -1,102 +0,0 @@ -# Project-level configuration. -cmake_minimum_required(VERSION 3.14) -project(spinifyapp LANGUAGES CXX) - -# The name of the executable created for the application. Change this to change -# the on-disk name of your application. -set(BINARY_NAME "spinifyapp") - -# Explicitly opt in to modern CMake behaviors to avoid warnings with recent -# versions of CMake. -cmake_policy(VERSION 3.14...3.25) - -# Define build configuration option. -get_property(IS_MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) -if(IS_MULTICONFIG) - set(CMAKE_CONFIGURATION_TYPES "Debug;Profile;Release" - CACHE STRING "" FORCE) -else() - if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) - set(CMAKE_BUILD_TYPE "Debug" CACHE - STRING "Flutter build mode" FORCE) - set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS - "Debug" "Profile" "Release") - endif() -endif() -# Define settings for the Profile build mode. -set(CMAKE_EXE_LINKER_FLAGS_PROFILE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}") -set(CMAKE_SHARED_LINKER_FLAGS_PROFILE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}") -set(CMAKE_C_FLAGS_PROFILE "${CMAKE_C_FLAGS_RELEASE}") -set(CMAKE_CXX_FLAGS_PROFILE "${CMAKE_CXX_FLAGS_RELEASE}") - -# Use Unicode for all projects. -add_definitions(-DUNICODE -D_UNICODE) - -# Compilation settings that should be applied to most targets. -# -# Be cautious about adding new options here, as plugins use this function by -# default. In most cases, you should add new options to specific targets instead -# of modifying this function. -function(APPLY_STANDARD_SETTINGS TARGET) - target_compile_features(${TARGET} PUBLIC cxx_std_17) - target_compile_options(${TARGET} PRIVATE /W4 /WX /wd"4100") - target_compile_options(${TARGET} PRIVATE /EHsc) - target_compile_definitions(${TARGET} PRIVATE "_HAS_EXCEPTIONS=0") - target_compile_definitions(${TARGET} PRIVATE "$<$:_DEBUG>") -endfunction() - -# Flutter library and tool build rules. -set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") -add_subdirectory(${FLUTTER_MANAGED_DIR}) - -# Application build; see runner/CMakeLists.txt. -add_subdirectory("runner") - - -# Generated plugin build rules, which manage building the plugins and adding -# them to the application. -include(flutter/generated_plugins.cmake) - - -# === Installation === -# Support files are copied into place next to the executable, so that it can -# run in place. This is done instead of making a separate bundle (as on Linux) -# so that building and running from within Visual Studio will work. -set(BUILD_BUNDLE_DIR "$") -# Make the "install" step default, as it's required to run. -set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD 1) -if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) - set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) -endif() - -set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") -set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}") - -install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" - COMPONENT Runtime) - -install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" - COMPONENT Runtime) - -install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" - COMPONENT Runtime) - -if(PLUGIN_BUNDLED_LIBRARIES) - install(FILES "${PLUGIN_BUNDLED_LIBRARIES}" - DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" - COMPONENT Runtime) -endif() - -# Fully re-copy the assets directory on each build to avoid having stale files -# from a previous install. -set(FLUTTER_ASSET_DIR_NAME "flutter_assets") -install(CODE " - file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") - " COMPONENT Runtime) -install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" - DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) - -# Install the AOT library on non-Debug builds only. -install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" - CONFIGURATIONS Profile;Release - COMPONENT Runtime) diff --git a/example/windows/flutter/CMakeLists.txt b/example/windows/flutter/CMakeLists.txt deleted file mode 100644 index 930d207..0000000 --- a/example/windows/flutter/CMakeLists.txt +++ /dev/null @@ -1,104 +0,0 @@ -# This file controls Flutter-level build steps. It should not be edited. -cmake_minimum_required(VERSION 3.14) - -set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") - -# Configuration provided via flutter tool. -include(${EPHEMERAL_DIR}/generated_config.cmake) - -# TODO: Move the rest of this into files in ephemeral. See -# https://github.com/flutter/flutter/issues/57146. -set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper") - -# === Flutter Library === -set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll") - -# Published to parent scope for install step. -set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) -set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) -set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) -set(AOT_LIBRARY "${PROJECT_DIR}/build/windows/app.so" PARENT_SCOPE) - -list(APPEND FLUTTER_LIBRARY_HEADERS - "flutter_export.h" - "flutter_windows.h" - "flutter_messenger.h" - "flutter_plugin_registrar.h" - "flutter_texture_registrar.h" -) -list(TRANSFORM FLUTTER_LIBRARY_HEADERS PREPEND "${EPHEMERAL_DIR}/") -add_library(flutter INTERFACE) -target_include_directories(flutter INTERFACE - "${EPHEMERAL_DIR}" -) -target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}.lib") -add_dependencies(flutter flutter_assemble) - -# === Wrapper === -list(APPEND CPP_WRAPPER_SOURCES_CORE - "core_implementations.cc" - "standard_codec.cc" -) -list(TRANSFORM CPP_WRAPPER_SOURCES_CORE PREPEND "${WRAPPER_ROOT}/") -list(APPEND CPP_WRAPPER_SOURCES_PLUGIN - "plugin_registrar.cc" -) -list(TRANSFORM CPP_WRAPPER_SOURCES_PLUGIN PREPEND "${WRAPPER_ROOT}/") -list(APPEND CPP_WRAPPER_SOURCES_APP - "flutter_engine.cc" - "flutter_view_controller.cc" -) -list(TRANSFORM CPP_WRAPPER_SOURCES_APP PREPEND "${WRAPPER_ROOT}/") - -# Wrapper sources needed for a plugin. -add_library(flutter_wrapper_plugin STATIC - ${CPP_WRAPPER_SOURCES_CORE} - ${CPP_WRAPPER_SOURCES_PLUGIN} -) -apply_standard_settings(flutter_wrapper_plugin) -set_target_properties(flutter_wrapper_plugin PROPERTIES - POSITION_INDEPENDENT_CODE ON) -set_target_properties(flutter_wrapper_plugin PROPERTIES - CXX_VISIBILITY_PRESET hidden) -target_link_libraries(flutter_wrapper_plugin PUBLIC flutter) -target_include_directories(flutter_wrapper_plugin PUBLIC - "${WRAPPER_ROOT}/include" -) -add_dependencies(flutter_wrapper_plugin flutter_assemble) - -# Wrapper sources needed for the runner. -add_library(flutter_wrapper_app STATIC - ${CPP_WRAPPER_SOURCES_CORE} - ${CPP_WRAPPER_SOURCES_APP} -) -apply_standard_settings(flutter_wrapper_app) -target_link_libraries(flutter_wrapper_app PUBLIC flutter) -target_include_directories(flutter_wrapper_app PUBLIC - "${WRAPPER_ROOT}/include" -) -add_dependencies(flutter_wrapper_app flutter_assemble) - -# === Flutter tool backend === -# _phony_ is a non-existent file to force this command to run every time, -# since currently there's no way to get a full input/output list from the -# flutter tool. -set(PHONY_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/_phony_") -set_source_files_properties("${PHONY_OUTPUT}" PROPERTIES SYMBOLIC TRUE) -add_custom_command( - OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} - ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN} - ${CPP_WRAPPER_SOURCES_APP} - ${PHONY_OUTPUT} - COMMAND ${CMAKE_COMMAND} -E env - ${FLUTTER_TOOL_ENVIRONMENT} - "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat" - windows-x64 $ - VERBATIM -) -add_custom_target(flutter_assemble DEPENDS - "${FLUTTER_LIBRARY}" - ${FLUTTER_LIBRARY_HEADERS} - ${CPP_WRAPPER_SOURCES_CORE} - ${CPP_WRAPPER_SOURCES_PLUGIN} - ${CPP_WRAPPER_SOURCES_APP} -) diff --git a/example/windows/flutter/generated_plugin_registrant.cc b/example/windows/flutter/generated_plugin_registrant.cc deleted file mode 100644 index d6b86fa..0000000 --- a/example/windows/flutter/generated_plugin_registrant.cc +++ /dev/null @@ -1,17 +0,0 @@ -// -// Generated file. Do not edit. -// - -// clang-format off - -#include "generated_plugin_registrant.h" - -#include -#include - -void RegisterPlugins(flutter::PluginRegistry* registry) { - ScreenRetrieverPluginRegisterWithRegistrar( - registry->GetRegistrarForPlugin("ScreenRetrieverPlugin")); - WindowManagerPluginRegisterWithRegistrar( - registry->GetRegistrarForPlugin("WindowManagerPlugin")); -} diff --git a/example/windows/flutter/generated_plugin_registrant.h b/example/windows/flutter/generated_plugin_registrant.h deleted file mode 100644 index dc139d8..0000000 --- a/example/windows/flutter/generated_plugin_registrant.h +++ /dev/null @@ -1,15 +0,0 @@ -// -// Generated file. Do not edit. -// - -// clang-format off - -#ifndef GENERATED_PLUGIN_REGISTRANT_ -#define GENERATED_PLUGIN_REGISTRANT_ - -#include - -// Registers Flutter plugins. -void RegisterPlugins(flutter::PluginRegistry* registry); - -#endif // GENERATED_PLUGIN_REGISTRANT_ diff --git a/example/windows/flutter/generated_plugins.cmake b/example/windows/flutter/generated_plugins.cmake deleted file mode 100644 index bfa52f4..0000000 --- a/example/windows/flutter/generated_plugins.cmake +++ /dev/null @@ -1,25 +0,0 @@ -# -# Generated file, do not edit. -# - -list(APPEND FLUTTER_PLUGIN_LIST - screen_retriever - window_manager -) - -list(APPEND FLUTTER_FFI_PLUGIN_LIST -) - -set(PLUGIN_BUNDLED_LIBRARIES) - -foreach(plugin ${FLUTTER_PLUGIN_LIST}) - add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin}) - target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) - list(APPEND PLUGIN_BUNDLED_LIBRARIES $) - list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) -endforeach(plugin) - -foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) - add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin}) - list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) -endforeach(ffi_plugin) diff --git a/example/windows/runner/CMakeLists.txt b/example/windows/runner/CMakeLists.txt deleted file mode 100644 index 394917c..0000000 --- a/example/windows/runner/CMakeLists.txt +++ /dev/null @@ -1,40 +0,0 @@ -cmake_minimum_required(VERSION 3.14) -project(runner LANGUAGES CXX) - -# Define the application target. To change its name, change BINARY_NAME in the -# top-level CMakeLists.txt, not the value here, or `flutter run` will no longer -# work. -# -# Any new source files that you add to the application should be added here. -add_executable(${BINARY_NAME} WIN32 - "flutter_window.cpp" - "main.cpp" - "utils.cpp" - "win32_window.cpp" - "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" - "Runner.rc" - "runner.exe.manifest" -) - -# Apply the standard set of build settings. This can be removed for applications -# that need different build settings. -apply_standard_settings(${BINARY_NAME}) - -# Add preprocessor definitions for the build version. -target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION=\"${FLUTTER_VERSION}\"") -target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MAJOR=${FLUTTER_VERSION_MAJOR}") -target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MINOR=${FLUTTER_VERSION_MINOR}") -target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_PATCH=${FLUTTER_VERSION_PATCH}") -target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_BUILD=${FLUTTER_VERSION_BUILD}") - -# Disable Windows macros that collide with C++ standard library functions. -target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX") - -# Add dependency libraries and include directories. Add any application-specific -# dependencies here. -target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app) -target_link_libraries(${BINARY_NAME} PRIVATE "dwmapi.lib") -target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") - -# Run the Flutter tool portions of the build. This must not be removed. -add_dependencies(${BINARY_NAME} flutter_assemble) diff --git a/example/windows/runner/Runner.rc b/example/windows/runner/Runner.rc deleted file mode 100644 index b13385c..0000000 --- a/example/windows/runner/Runner.rc +++ /dev/null @@ -1,121 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -#pragma code_page(65001) -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "winres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// English (United States) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE -BEGIN - "#include ""winres.h""\r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Icon -// - -// Icon with lowest ID value placed first to ensure application icon -// remains consistent on all systems. -IDI_APP_ICON ICON "resources\\app_icon.ico" - - -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -#if defined(FLUTTER_VERSION_MAJOR) && defined(FLUTTER_VERSION_MINOR) && defined(FLUTTER_VERSION_PATCH) && defined(FLUTTER_VERSION_BUILD) -#define VERSION_AS_NUMBER FLUTTER_VERSION_MAJOR,FLUTTER_VERSION_MINOR,FLUTTER_VERSION_PATCH,FLUTTER_VERSION_BUILD -#else -#define VERSION_AS_NUMBER 1,0,0,0 -#endif - -#if defined(FLUTTER_VERSION) -#define VERSION_AS_STRING FLUTTER_VERSION -#else -#define VERSION_AS_STRING "1.0.0" -#endif - -VS_VERSION_INFO VERSIONINFO - FILEVERSION VERSION_AS_NUMBER - PRODUCTVERSION VERSION_AS_NUMBER - FILEFLAGSMASK VS_FFI_FILEFLAGSMASK -#ifdef _DEBUG - FILEFLAGS VS_FF_DEBUG -#else - FILEFLAGS 0x0L -#endif - FILEOS VOS__WINDOWS32 - FILETYPE VFT_APP - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904e4" - BEGIN - VALUE "CompanyName", "dev.plugfox.spinify" "\0" - VALUE "FileDescription", "spinifyapp" "\0" - VALUE "FileVersion", VERSION_AS_STRING "\0" - VALUE "InternalName", "spinifyapp" "\0" - VALUE "LegalCopyright", "Copyright (C) 2023 dev.plugfox.spinify. All rights reserved." "\0" - VALUE "OriginalFilename", "spinifyapp.exe" "\0" - VALUE "ProductName", "spinifyapp" "\0" - VALUE "ProductVersion", VERSION_AS_STRING "\0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1252 - END -END - -#endif // English (United States) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED diff --git a/example/windows/runner/flutter_window.cpp b/example/windows/runner/flutter_window.cpp deleted file mode 100644 index 0e4c5f5..0000000 --- a/example/windows/runner/flutter_window.cpp +++ /dev/null @@ -1,66 +0,0 @@ -#include "flutter_window.h" - -#include - -#include "flutter/generated_plugin_registrant.h" - -FlutterWindow::FlutterWindow(const flutter::DartProject &project) - : project_(project) {} - -FlutterWindow::~FlutterWindow() {} - -bool FlutterWindow::OnCreate() { - if (!Win32Window::OnCreate()) { - return false; - } - - RECT frame = GetClientArea(); - - // The size here must match the window dimensions to avoid unnecessary surface - // creation / destruction in the startup path. - flutter_controller_ = std::make_unique( - frame.right - frame.left, frame.bottom - frame.top, project_); - // Ensure that basic setup of the controller was successful. - if (!flutter_controller_->engine() || !flutter_controller_->view()) { - return false; - } - RegisterPlugins(flutter_controller_->engine()); - SetChildContent(flutter_controller_->view()->GetNativeWindow()); - - flutter_controller_->engine()->SetNextFrameCallback([&]() { - // this->Show() - }); - - return true; -} - -void FlutterWindow::OnDestroy() { - if (flutter_controller_) { - flutter_controller_ = nullptr; - } - - Win32Window::OnDestroy(); -} - -LRESULT -FlutterWindow::MessageHandler(HWND hwnd, UINT const message, - WPARAM const wparam, - LPARAM const lparam) noexcept { - // Give Flutter, including plugins, an opportunity to handle window messages. - if (flutter_controller_) { - std::optional result = - flutter_controller_->HandleTopLevelWindowProc(hwnd, message, wparam, - lparam); - if (result) { - return *result; - } - } - - switch (message) { - case WM_FONTCHANGE: - flutter_controller_->engine()->ReloadSystemFonts(); - break; - } - - return Win32Window::MessageHandler(hwnd, message, wparam, lparam); -} diff --git a/example/windows/runner/flutter_window.h b/example/windows/runner/flutter_window.h deleted file mode 100644 index 6da0652..0000000 --- a/example/windows/runner/flutter_window.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef RUNNER_FLUTTER_WINDOW_H_ -#define RUNNER_FLUTTER_WINDOW_H_ - -#include -#include - -#include - -#include "win32_window.h" - -// A window that does nothing but host a Flutter view. -class FlutterWindow : public Win32Window { - public: - // Creates a new FlutterWindow hosting a Flutter view running |project|. - explicit FlutterWindow(const flutter::DartProject& project); - virtual ~FlutterWindow(); - - protected: - // Win32Window: - bool OnCreate() override; - void OnDestroy() override; - LRESULT MessageHandler(HWND window, UINT const message, WPARAM const wparam, - LPARAM const lparam) noexcept override; - - private: - // The project to run. - flutter::DartProject project_; - - // The Flutter instance hosted by this window. - std::unique_ptr flutter_controller_; -}; - -#endif // RUNNER_FLUTTER_WINDOW_H_ diff --git a/example/windows/runner/main.cpp b/example/windows/runner/main.cpp deleted file mode 100644 index b9101f9..0000000 --- a/example/windows/runner/main.cpp +++ /dev/null @@ -1,43 +0,0 @@ -#include -#include -#include - -#include "flutter_window.h" -#include "utils.h" - -int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, - _In_ wchar_t *command_line, _In_ int show_command) { - // Attach to console when present (e.g., 'flutter run') or create a - // new console when running with a debugger. - if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) { - CreateAndAttachConsole(); - } - - // Initialize COM, so that it is available for use in the library and/or - // plugins. - ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); - - flutter::DartProject project(L"data"); - - std::vector command_line_arguments = - GetCommandLineArguments(); - - project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); - - FlutterWindow window(project); - Win32Window::Point origin(10, 10); - Win32Window::Size size(1280, 720); - if (!window.Create(L"spinifyapp", origin, size)) { - return EXIT_FAILURE; - } - window.SetQuitOnClose(true); - - ::MSG msg; - while (::GetMessage(&msg, nullptr, 0, 0)) { - ::TranslateMessage(&msg); - ::DispatchMessage(&msg); - } - - ::CoUninitialize(); - return EXIT_SUCCESS; -} diff --git a/example/windows/runner/resource.h b/example/windows/runner/resource.h deleted file mode 100644 index 66a65d1..0000000 --- a/example/windows/runner/resource.h +++ /dev/null @@ -1,16 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by Runner.rc -// -#define IDI_APP_ICON 101 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 102 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1001 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/example/windows/runner/resources/app_icon.ico b/example/windows/runner/resources/app_icon.ico deleted file mode 100644 index c04e20c..0000000 Binary files a/example/windows/runner/resources/app_icon.ico and /dev/null differ diff --git a/example/windows/runner/runner.exe.manifest b/example/windows/runner/runner.exe.manifest deleted file mode 100644 index a42ea76..0000000 --- a/example/windows/runner/runner.exe.manifest +++ /dev/null @@ -1,20 +0,0 @@ - - - - - PerMonitorV2 - - - - - - - - - - - - - - - diff --git a/example/windows/runner/utils.cpp b/example/windows/runner/utils.cpp deleted file mode 100644 index b2b0873..0000000 --- a/example/windows/runner/utils.cpp +++ /dev/null @@ -1,65 +0,0 @@ -#include "utils.h" - -#include -#include -#include -#include - -#include - -void CreateAndAttachConsole() { - if (::AllocConsole()) { - FILE *unused; - if (freopen_s(&unused, "CONOUT$", "w", stdout)) { - _dup2(_fileno(stdout), 1); - } - if (freopen_s(&unused, "CONOUT$", "w", stderr)) { - _dup2(_fileno(stdout), 2); - } - std::ios::sync_with_stdio(); - FlutterDesktopResyncOutputStreams(); - } -} - -std::vector GetCommandLineArguments() { - // Convert the UTF-16 command line arguments to UTF-8 for the Engine to use. - int argc; - wchar_t** argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc); - if (argv == nullptr) { - return std::vector(); - } - - std::vector command_line_arguments; - - // Skip the first argument as it's the binary name. - for (int i = 1; i < argc; i++) { - command_line_arguments.push_back(Utf8FromUtf16(argv[i])); - } - - ::LocalFree(argv); - - return command_line_arguments; -} - -std::string Utf8FromUtf16(const wchar_t* utf16_string) { - if (utf16_string == nullptr) { - return std::string(); - } - int target_length = ::WideCharToMultiByte( - CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, - -1, nullptr, 0, nullptr, nullptr) - -1; // remove the trailing null character - int input_length = (int)wcslen(utf16_string); - std::string utf8_string; - if (target_length <= 0 || target_length > utf8_string.max_size()) { - return utf8_string; - } - utf8_string.resize(target_length); - int converted_length = ::WideCharToMultiByte( - CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, - input_length, utf8_string.data(), target_length, nullptr, nullptr); - if (converted_length == 0) { - return std::string(); - } - return utf8_string; -} diff --git a/example/windows/runner/utils.h b/example/windows/runner/utils.h deleted file mode 100644 index 3879d54..0000000 --- a/example/windows/runner/utils.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef RUNNER_UTILS_H_ -#define RUNNER_UTILS_H_ - -#include -#include - -// Creates a console for the process, and redirects stdout and stderr to -// it for both the runner and the Flutter library. -void CreateAndAttachConsole(); - -// Takes a null-terminated wchar_t* encoded in UTF-16 and returns a std::string -// encoded in UTF-8. Returns an empty std::string on failure. -std::string Utf8FromUtf16(const wchar_t* utf16_string); - -// Gets the command line arguments passed in as a std::vector, -// encoded in UTF-8. Returns an empty std::vector on failure. -std::vector GetCommandLineArguments(); - -#endif // RUNNER_UTILS_H_ diff --git a/example/windows/runner/win32_window.cpp b/example/windows/runner/win32_window.cpp deleted file mode 100644 index 145247b..0000000 --- a/example/windows/runner/win32_window.cpp +++ /dev/null @@ -1,280 +0,0 @@ -#include "win32_window.h" - -#include -#include - -#include "resource.h" - -namespace { - -/// Window attribute that enables dark mode window decorations. -/// -/// Redefined in case the developer's machine has a Windows SDK older than -/// version 10.0.22000.0. -/// See: -/// https://docs.microsoft.com/windows/win32/api/dwmapi/ne-dwmapi-dwmwindowattribute -#ifndef DWMWA_USE_IMMERSIVE_DARK_MODE -#define DWMWA_USE_IMMERSIVE_DARK_MODE 20 -#endif - -constexpr const wchar_t kWindowClassName[] = L"FLUTTER_RUNNER_WIN32_WINDOW"; - -/// Registry key for app theme preference. -/// -/// A value of 0 indicates apps should use dark mode. A non-zero or missing -/// value indicates apps should use light mode. -constexpr const wchar_t kGetPreferredBrightnessRegKey[] = - L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize"; -constexpr const wchar_t kGetPreferredBrightnessRegValue[] = - L"AppsUseLightTheme"; - -// The number of Win32Window objects that currently exist. -static int g_active_window_count = 0; - -using EnableNonClientDpiScaling = BOOL __stdcall(HWND hwnd); - -// Scale helper to convert logical scaler values to physical using passed in -// scale factor -int Scale(int source, double scale_factor) { - return static_cast(source * scale_factor); -} - -// Dynamically loads the |EnableNonClientDpiScaling| from the User32 module. -// This API is only needed for PerMonitor V1 awareness mode. -void EnableFullDpiSupportIfAvailable(HWND hwnd) { - HMODULE user32_module = LoadLibraryA("User32.dll"); - if (!user32_module) { - return; - } - auto enable_non_client_dpi_scaling = - reinterpret_cast( - GetProcAddress(user32_module, "EnableNonClientDpiScaling")); - if (enable_non_client_dpi_scaling != nullptr) { - enable_non_client_dpi_scaling(hwnd); - } - FreeLibrary(user32_module); -} - -} // namespace - -// Manages the Win32Window's window class registration. -class WindowClassRegistrar { -public: - ~WindowClassRegistrar() = default; - - // Returns the singleton registrar instance. - static WindowClassRegistrar *GetInstance() { - if (!instance_) { - instance_ = new WindowClassRegistrar(); - } - return instance_; - } - - // Returns the name of the window class, registering the class if it hasn't - // previously been registered. - const wchar_t *GetWindowClass(); - - // Unregisters the window class. Should only be called if there are no - // instances of the window. - void UnregisterWindowClass(); - -private: - WindowClassRegistrar() = default; - - static WindowClassRegistrar *instance_; - - bool class_registered_ = false; -}; - -WindowClassRegistrar *WindowClassRegistrar::instance_ = nullptr; - -const wchar_t *WindowClassRegistrar::GetWindowClass() { - if (!class_registered_) { - WNDCLASS window_class{}; - window_class.hCursor = LoadCursor(nullptr, IDC_ARROW); - window_class.lpszClassName = kWindowClassName; - window_class.style = CS_HREDRAW | CS_VREDRAW; - window_class.cbClsExtra = 0; - window_class.cbWndExtra = 0; - window_class.hInstance = GetModuleHandle(nullptr); - window_class.hIcon = - LoadIcon(window_class.hInstance, MAKEINTRESOURCE(IDI_APP_ICON)); - window_class.hbrBackground = 0; - window_class.lpszMenuName = nullptr; - window_class.lpfnWndProc = Win32Window::WndProc; - RegisterClass(&window_class); - class_registered_ = true; - } - return kWindowClassName; -} - -void WindowClassRegistrar::UnregisterWindowClass() { - UnregisterClass(kWindowClassName, nullptr); - class_registered_ = false; -} - -Win32Window::Win32Window() { ++g_active_window_count; } - -Win32Window::~Win32Window() { - --g_active_window_count; - Destroy(); -} - -bool Win32Window::Create(const std::wstring &title, const Point &origin, - const Size &size) { - Destroy(); - - const wchar_t *window_class = - WindowClassRegistrar::GetInstance()->GetWindowClass(); - - const POINT target_point = {static_cast(origin.x), - static_cast(origin.y)}; - HMONITOR monitor = MonitorFromPoint(target_point, MONITOR_DEFAULTTONEAREST); - UINT dpi = FlutterDesktopGetDpiForMonitor(monitor); - double scale_factor = dpi / 96.0; - - HWND window = CreateWindow( - window_class, title.c_str(), WS_OVERLAPPEDWINDOW, - Scale(origin.x, scale_factor), Scale(origin.y, scale_factor), - Scale(size.width, scale_factor), Scale(size.height, scale_factor), - nullptr, nullptr, GetModuleHandle(nullptr), this); - - if (!window) { - return false; - } - - UpdateTheme(window); - - return OnCreate(); -} - -bool Win32Window::Show() { return ShowWindow(window_handle_, SW_SHOWNORMAL); } - -// static -LRESULT CALLBACK Win32Window::WndProc(HWND const window, UINT const message, - WPARAM const wparam, - LPARAM const lparam) noexcept { - if (message == WM_NCCREATE) { - auto window_struct = reinterpret_cast(lparam); - SetWindowLongPtr(window, GWLP_USERDATA, - reinterpret_cast(window_struct->lpCreateParams)); - - auto that = static_cast(window_struct->lpCreateParams); - EnableFullDpiSupportIfAvailable(window); - that->window_handle_ = window; - } else if (Win32Window *that = GetThisFromHandle(window)) { - return that->MessageHandler(window, message, wparam, lparam); - } - - return DefWindowProc(window, message, wparam, lparam); -} - -LRESULT -Win32Window::MessageHandler(HWND hwnd, UINT const message, WPARAM const wparam, - LPARAM const lparam) noexcept { - switch (message) { - case WM_DESTROY: - window_handle_ = nullptr; - Destroy(); - if (quit_on_close_) { - PostQuitMessage(0); - } - return 0; - - case WM_DPICHANGED: { - auto newRectSize = reinterpret_cast(lparam); - LONG newWidth = newRectSize->right - newRectSize->left; - LONG newHeight = newRectSize->bottom - newRectSize->top; - - SetWindowPos(hwnd, nullptr, newRectSize->left, newRectSize->top, newWidth, - newHeight, SWP_NOZORDER | SWP_NOACTIVATE); - - return 0; - } - case WM_SIZE: { - RECT rect = GetClientArea(); - if (child_content_ != nullptr) { - // Size and position the child window. - MoveWindow(child_content_, rect.left, rect.top, rect.right - rect.left, - rect.bottom - rect.top, TRUE); - } - return 0; - } - - case WM_ACTIVATE: - if (child_content_ != nullptr) { - SetFocus(child_content_); - } - return 0; - - case WM_DWMCOLORIZATIONCOLORCHANGED: - UpdateTheme(hwnd); - return 0; - } - - return DefWindowProc(window_handle_, message, wparam, lparam); -} - -void Win32Window::Destroy() { - OnDestroy(); - - if (window_handle_) { - DestroyWindow(window_handle_); - window_handle_ = nullptr; - } - if (g_active_window_count == 0) { - WindowClassRegistrar::GetInstance()->UnregisterWindowClass(); - } -} - -Win32Window *Win32Window::GetThisFromHandle(HWND const window) noexcept { - return reinterpret_cast( - GetWindowLongPtr(window, GWLP_USERDATA)); -} - -void Win32Window::SetChildContent(HWND content) { - child_content_ = content; - SetParent(content, window_handle_); - RECT frame = GetClientArea(); - - MoveWindow(content, frame.left, frame.top, frame.right - frame.left, - frame.bottom - frame.top, true); - - SetFocus(child_content_); -} - -RECT Win32Window::GetClientArea() { - RECT frame; - GetClientRect(window_handle_, &frame); - return frame; -} - -HWND Win32Window::GetHandle() { return window_handle_; } - -void Win32Window::SetQuitOnClose(bool quit_on_close) { - quit_on_close_ = quit_on_close; -} - -bool Win32Window::OnCreate() { - // No-op; provided for subclasses. - return true; -} - -void Win32Window::OnDestroy() { - // No-op; provided for subclasses. -} - -void Win32Window::UpdateTheme(HWND const window) { - DWORD light_mode; - DWORD light_mode_size = sizeof(light_mode); - LSTATUS result = - RegGetValue(HKEY_CURRENT_USER, kGetPreferredBrightnessRegKey, - kGetPreferredBrightnessRegValue, RRF_RT_REG_DWORD, nullptr, - &light_mode, &light_mode_size); - - if (result == ERROR_SUCCESS) { - BOOL enable_dark_mode = light_mode == 0; - DwmSetWindowAttribute(window, DWMWA_USE_IMMERSIVE_DARK_MODE, - &enable_dark_mode, sizeof(enable_dark_mode)); - } -} diff --git a/example/windows/runner/win32_window.h b/example/windows/runner/win32_window.h deleted file mode 100644 index e901dde..0000000 --- a/example/windows/runner/win32_window.h +++ /dev/null @@ -1,102 +0,0 @@ -#ifndef RUNNER_WIN32_WINDOW_H_ -#define RUNNER_WIN32_WINDOW_H_ - -#include - -#include -#include -#include - -// A class abstraction for a high DPI-aware Win32 Window. Intended to be -// inherited from by classes that wish to specialize with custom -// rendering and input handling -class Win32Window { - public: - struct Point { - unsigned int x; - unsigned int y; - Point(unsigned int x, unsigned int y) : x(x), y(y) {} - }; - - struct Size { - unsigned int width; - unsigned int height; - Size(unsigned int width, unsigned int height) - : width(width), height(height) {} - }; - - Win32Window(); - virtual ~Win32Window(); - - // Creates a win32 window with |title| that is positioned and sized using - // |origin| and |size|. New windows are created on the default monitor. Window - // sizes are specified to the OS in physical pixels, hence to ensure a - // consistent size this function will scale the inputted width and height as - // as appropriate for the default monitor. The window is invisible until - // |Show| is called. Returns true if the window was created successfully. - bool Create(const std::wstring& title, const Point& origin, const Size& size); - - // Show the current window. Returns true if the window was successfully shown. - bool Show(); - - // Release OS resources associated with window. - void Destroy(); - - // Inserts |content| into the window tree. - void SetChildContent(HWND content); - - // Returns the backing Window handle to enable clients to set icon and other - // window properties. Returns nullptr if the window has been destroyed. - HWND GetHandle(); - - // If true, closing this window will quit the application. - void SetQuitOnClose(bool quit_on_close); - - // Return a RECT representing the bounds of the current client area. - RECT GetClientArea(); - - protected: - // Processes and route salient window messages for mouse handling, - // size change and DPI. Delegates handling of these to member overloads that - // inheriting classes can handle. - virtual LRESULT MessageHandler(HWND window, - UINT const message, - WPARAM const wparam, - LPARAM const lparam) noexcept; - - // Called when CreateAndShow is called, allowing subclass window-related - // setup. Subclasses should return false if setup fails. - virtual bool OnCreate(); - - // Called when Destroy is called. - virtual void OnDestroy(); - - private: - friend class WindowClassRegistrar; - - // OS callback called by message pump. Handles the WM_NCCREATE message which - // is passed when the non-client area is being created and enables automatic - // non-client DPI scaling so that the non-client area automatically - // responds to changes in DPI. All other messages are handled by - // MessageHandler. - static LRESULT CALLBACK WndProc(HWND const window, - UINT const message, - WPARAM const wparam, - LPARAM const lparam) noexcept; - - // Retrieves a class instance pointer for |window| - static Win32Window* GetThisFromHandle(HWND const window) noexcept; - - // Update the window frame's theme to match the system theme. - static void UpdateTheme(HWND const window); - - bool quit_on_close_ = false; - - // window handle for top level window. - HWND window_handle_ = nullptr; - - // window handle for hosted content. - HWND child_content_ = nullptr; -}; - -#endif // RUNNER_WIN32_WINDOW_H_