Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
693d2ad79e
|
|||
|
f19e8950e8
|
|||
|
64d0541dc6
|
|||
|
dfb4d9d9e5
|
|||
| 6306555a30 | |||
| b6b1743285 | |||
|
f6a48140b4
|
|||
|
cd79cf4449
|
|||
|
1aadd9c368
|
|||
|
febc0a8f43
|
|||
|
fd5e714074
|
|||
|
c108859899
|
|||
|
b3083d37c3
|
|||
|
521c1e94c0
|
|||
|
31a45bc4c3
|
|||
|
b6944d1dbb
|
|||
|
32ef2c5023
|
BIN
data/appicon_1.1.xcf
Normal file
2
flutter/.gitignore
vendored
@@ -20,9 +20,11 @@ _releases/*
|
|||||||
*.swp
|
*.swp
|
||||||
.DS_Store
|
.DS_Store
|
||||||
.atom/
|
.atom/
|
||||||
|
.build/
|
||||||
.buildlog/
|
.buildlog/
|
||||||
.history
|
.history
|
||||||
.svn/
|
.svn/
|
||||||
|
.swiftpm/
|
||||||
migrate_working_dir/
|
migrate_working_dir/
|
||||||
|
|
||||||
# IntelliJ related
|
# IntelliJ related
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
# This file should be version controlled and should not be manually edited.
|
# This file should be version controlled and should not be manually edited.
|
||||||
|
|
||||||
version:
|
version:
|
||||||
revision: "41456452f29d64e8deb623a3c927524bcf9f111b"
|
revision: "adc901062556672b4138e18a4dc62a4be8f4b3c2"
|
||||||
channel: "stable"
|
channel: "stable"
|
||||||
|
|
||||||
project_type: app
|
project_type: app
|
||||||
@@ -13,26 +13,26 @@ project_type: app
|
|||||||
migration:
|
migration:
|
||||||
platforms:
|
platforms:
|
||||||
- platform: root
|
- platform: root
|
||||||
create_revision: 41456452f29d64e8deb623a3c927524bcf9f111b
|
create_revision: adc901062556672b4138e18a4dc62a4be8f4b3c2
|
||||||
base_revision: 41456452f29d64e8deb623a3c927524bcf9f111b
|
base_revision: adc901062556672b4138e18a4dc62a4be8f4b3c2
|
||||||
- platform: android
|
- platform: android
|
||||||
create_revision: 41456452f29d64e8deb623a3c927524bcf9f111b
|
create_revision: adc901062556672b4138e18a4dc62a4be8f4b3c2
|
||||||
base_revision: 41456452f29d64e8deb623a3c927524bcf9f111b
|
base_revision: adc901062556672b4138e18a4dc62a4be8f4b3c2
|
||||||
- platform: ios
|
- platform: ios
|
||||||
create_revision: 41456452f29d64e8deb623a3c927524bcf9f111b
|
create_revision: adc901062556672b4138e18a4dc62a4be8f4b3c2
|
||||||
base_revision: 41456452f29d64e8deb623a3c927524bcf9f111b
|
base_revision: adc901062556672b4138e18a4dc62a4be8f4b3c2
|
||||||
- platform: linux
|
- platform: linux
|
||||||
create_revision: 41456452f29d64e8deb623a3c927524bcf9f111b
|
create_revision: adc901062556672b4138e18a4dc62a4be8f4b3c2
|
||||||
base_revision: 41456452f29d64e8deb623a3c927524bcf9f111b
|
base_revision: adc901062556672b4138e18a4dc62a4be8f4b3c2
|
||||||
- platform: macos
|
- platform: macos
|
||||||
create_revision: 41456452f29d64e8deb623a3c927524bcf9f111b
|
create_revision: adc901062556672b4138e18a4dc62a4be8f4b3c2
|
||||||
base_revision: 41456452f29d64e8deb623a3c927524bcf9f111b
|
base_revision: adc901062556672b4138e18a4dc62a4be8f4b3c2
|
||||||
- platform: web
|
- platform: web
|
||||||
create_revision: 41456452f29d64e8deb623a3c927524bcf9f111b
|
create_revision: adc901062556672b4138e18a4dc62a4be8f4b3c2
|
||||||
base_revision: 41456452f29d64e8deb623a3c927524bcf9f111b
|
base_revision: adc901062556672b4138e18a4dc62a4be8f4b3c2
|
||||||
- platform: windows
|
- platform: windows
|
||||||
create_revision: 41456452f29d64e8deb623a3c927524bcf9f111b
|
create_revision: adc901062556672b4138e18a4dc62a4be8f4b3c2
|
||||||
base_revision: 41456452f29d64e8deb623a3c927524bcf9f111b
|
base_revision: adc901062556672b4138e18a4dc62a4be8f4b3c2
|
||||||
|
|
||||||
# User provided section
|
# User provided section
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
|
|
||||||
HASH=$(shell git rev-parse HEAD)
|
HASH=$(shell git rev-parse HEAD)
|
||||||
VERS=$(shell cat pubspec.yaml | grep -oP '(?<=version: ).*' | sed 's/[\s]*//' | tr -d '\n') # lazy evaluated!
|
VERS=$(shell cat pubspec.yaml | grep -oP '(?<=version: ).*' | sed 's/[\s]*//' | tr -d '\n' | tr -d '') # lazy evaluated!
|
||||||
|
|
||||||
java:
|
java:
|
||||||
sudo archlinux-java set java-17-openjdk
|
sudo archlinux-java set java-17-openjdk
|
||||||
@@ -21,7 +21,7 @@ run-web: java gen
|
|||||||
run-android: java gen
|
run-android: java gen
|
||||||
ping -c1 10.10.10.177
|
ping -c1 10.10.10.177
|
||||||
adb connect 10.10.10.177:5555
|
adb connect 10.10.10.177:5555
|
||||||
flutter pub run build_runner build
|
dart run build_runner build
|
||||||
_JAVA_OPTIONS="" flutter run -d 10.10.10.177:5555
|
_JAVA_OPTIONS="" flutter run -d 10.10.10.177:5555
|
||||||
|
|
||||||
install-release: java gen
|
install-release: java gen
|
||||||
@@ -30,25 +30,7 @@ install-release: java gen
|
|||||||
flutter run --release -d 35221JEHN07157
|
flutter run --release -d 35221JEHN07157
|
||||||
|
|
||||||
release: java gen
|
release: java gen
|
||||||
flutter build apk --release
|
@_utils/release.sh
|
||||||
cp build/app/outputs/flutter-apk/app-release.apk "_releases/v$(VERS).apk"
|
|
||||||
@echo ""
|
|
||||||
@echo "--> copied APK to _releases ( Version: $(VERS) )"
|
|
||||||
@echo ""
|
|
||||||
flutter build appbundle --release
|
|
||||||
cp build/app/outputs/bundle/release/app-release.aab "_releases/v$(VERS).aab"
|
|
||||||
cd "build/app/intermediates/merged_native_libs/release/out/lib" && zip -r "../../../../../../../_releases/v$(VERS).symbols.zip" .
|
|
||||||
@echo ""
|
|
||||||
@echo "--> copied AAB to _releases ( Version: $(VERS) )"
|
|
||||||
@echo ""
|
|
||||||
flutter build linux --release
|
|
||||||
tar -czf "_releases/v$(VERS).tar.gz" -C build/linux/x64/release/bundle .
|
|
||||||
@echo ""
|
|
||||||
@echo "--> copied linux-binary to _releases ( Version: $(VERS) )"
|
|
||||||
@echo ""
|
|
||||||
@echo "#=> file://$(shell pwd)/_releases"
|
|
||||||
@echo ""
|
|
||||||
@echo "Done."
|
|
||||||
|
|
||||||
test:
|
test:
|
||||||
dart analyze
|
dart analyze
|
||||||
@@ -63,15 +45,21 @@ gen: java
|
|||||||
|
|
||||||
# run `make run` in another terminal (or another variant of flutter run)
|
# run `make run` in another terminal (or another variant of flutter run)
|
||||||
autoreload:
|
autoreload:
|
||||||
@
|
|
||||||
@_utils/autoreload.sh
|
@_utils/autoreload.sh
|
||||||
|
|
||||||
icons:
|
icons:
|
||||||
flutter pub run flutter_launcher_icons -f "flutter_launcher_icons.yaml"
|
flutter pub run flutter_launcher_icons -f "flutter_launcher_icons.yaml"
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
cd android && ./gradlew clean
|
|
||||||
flutter clean
|
flutter clean
|
||||||
|
flutter pub get
|
||||||
|
|
||||||
|
clean-ios: clean
|
||||||
|
cd ios && xcodebuild clean && rm -rf Pods Podfile.lock && pod install
|
||||||
|
|
||||||
|
clean-android: clean
|
||||||
|
cd android && ./gradlew clean
|
||||||
|
|
||||||
|
|
||||||
# upgrade all packages (add --major-versions even updates across new major versions)
|
# upgrade all packages (add --major-versions even updates across new major versions)
|
||||||
# https://docs.flutter.dev/release/upgrade
|
# https://docs.flutter.dev/release/upgrade
|
||||||
|
|||||||
48
flutter/_utils/release.sh
Executable file
@@ -0,0 +1,48 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
if [[ -d ".git" ]]; then
|
||||||
|
|
||||||
|
echo "Must be called in project root"
|
||||||
|
exit 1
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
VERS="$(cat pubspec.yaml | grep -oP '(?<=version: ).*' | sed 's/[\s]*//' | tr -d '\n' | tr -d '')"
|
||||||
|
|
||||||
|
VERS_BY_SPEC="$( echo -n "$VERS" | awk -F'+' '{print "v"$1}' )"
|
||||||
|
VERS_BY_TAG="$(git describe --abbrev=0 --tags)"
|
||||||
|
|
||||||
|
if [[ "$VERS_BY_TAG" != "$VERS_BY_SPEC" ]]; then
|
||||||
|
echo "Version in pubspec.yaml ($VERS_BY_SPEC) does not match latest git tag ($VERS_BY_TAG)"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "(!) Make sure you've updated version-number in pubspec.yaml (current = ${VERS}) !"
|
||||||
|
echo 'Confirmed' && read -r
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
flutter build apk --release
|
||||||
|
cp build/app/outputs/flutter-apk/app-release.apk "_releases/v${VERS}.apk"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "--> copied APK to _releases ( Version: ${VERS} )"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
flutter build appbundle --release
|
||||||
|
cp build/app/outputs/bundle/release/app-release.aab "_releases/v${VERS}.aab"
|
||||||
|
cd "build/app/intermediates/merged_native_libs/release/out/lib" && zip -r "../../../../../../../_releases/v${VERS}.symbols.zip" .
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "--> copied AAB to _releases ( Version: ${VERS} )"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
flutter build linux --release
|
||||||
|
tar -czf "_releases/v${VERS}.tar.gz" -C build/linux/x64/release/bundle .
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "--> copied linux-binary to _releases ( Version: ${VERS} )"
|
||||||
|
echo ""
|
||||||
|
echo "#=> file://$(pwd)/_releases"
|
||||||
|
echo ""
|
||||||
|
echo "Done."
|
||||||
@@ -34,7 +34,7 @@ if (keystorePropertiesFile.exists()) {
|
|||||||
android {
|
android {
|
||||||
namespace "com.blackforestbytes.simplecloudnotifier"
|
namespace "com.blackforestbytes.simplecloudnotifier"
|
||||||
compileSdkVersion flutter.compileSdkVersion
|
compileSdkVersion flutter.compileSdkVersion
|
||||||
ndkVersion "27.0.12077973" // should be `flutter.ndkVersion` - but some plugins need 27, even though flutter still has the default value of 26 (flutter 3.29 | 2025-04-12)
|
ndkVersion flutter.ndkVersion
|
||||||
|
|
||||||
compileOptions {
|
compileOptions {
|
||||||
coreLibraryDesugaringEnabled true
|
coreLibraryDesugaringEnabled true
|
||||||
|
|||||||
@@ -21,6 +21,6 @@
|
|||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>1.0</string>
|
<string>1.0</string>
|
||||||
<key>MinimumOSVersion</key>
|
<key>MinimumOSVersion</key>
|
||||||
<string>12.0</string>
|
<string>13.0</string>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|||||||
@@ -1 +1,2 @@
|
|||||||
|
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
|
||||||
#include "Generated.xcconfig"
|
#include "Generated.xcconfig"
|
||||||
|
|||||||
@@ -1 +1,2 @@
|
|||||||
|
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
|
||||||
#include "Generated.xcconfig"
|
#include "Generated.xcconfig"
|
||||||
|
|||||||
@@ -8,12 +8,14 @@
|
|||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
|
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
|
||||||
|
331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; };
|
||||||
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
|
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
|
||||||
|
483C144A8FD9FBE0BE4CA31D /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 20818F4FAA848E7B0E1981A1 /* Pods_RunnerTests.framework */; };
|
||||||
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
|
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
|
||||||
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
|
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
|
||||||
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
|
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
|
||||||
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
|
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
|
||||||
331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; };
|
F0CF5BB613220E8F87B9D978 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EDC5CDC3E1AFF7C5BC49C07E /* Pods_Runner.framework */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXContainerItemProxy section */
|
/* Begin PBXContainerItemProxy section */
|
||||||
@@ -40,12 +42,17 @@
|
|||||||
/* End PBXCopyFilesBuildPhase section */
|
/* End PBXCopyFilesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
|
12F3806130EB6FDA0BB8224F /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
|
||||||
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
|
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
|
||||||
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
|
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
|
||||||
|
20818F4FAA848E7B0E1981A1 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = "<group>"; };
|
||||||
|
331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
|
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
|
||||||
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
|
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
|
||||||
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||||
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
|
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
|
||||||
|
7CD878882EBBB898002F3C7D /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = "<group>"; };
|
||||||
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
|
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
|
||||||
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
|
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
|
||||||
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
@@ -53,8 +60,12 @@
|
|||||||
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||||
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||||
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||||
331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = "<group>"; };
|
A4D58F2C21BD1C00F0A1FE7D /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
|
||||||
331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
AE13A81982696D2690FB1CAB /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = "<group>"; };
|
||||||
|
D208168B6EAB5683BAD27E86 /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = "<group>"; };
|
||||||
|
DF96ECE6A0AC0BFA8724174B /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = "<group>"; };
|
||||||
|
EDC5CDC3E1AFF7C5BC49C07E /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
EE5AE3E3797C8A45B5AFA537 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
@@ -62,12 +73,51 @@
|
|||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
F0CF5BB613220E8F87B9D978 /* Pods_Runner.framework in Frameworks */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
985FE5E285D4547AB0054913 /* Frameworks */ = {
|
||||||
|
isa = PBXFrameworksBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
483C144A8FD9FBE0BE4CA31D /* Pods_RunnerTests.framework in Frameworks */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
/* End PBXFrameworksBuildPhase section */
|
/* End PBXFrameworksBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXGroup section */
|
/* Begin PBXGroup section */
|
||||||
|
04ACC4FC139085193359BE10 /* Pods */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
A4D58F2C21BD1C00F0A1FE7D /* Pods-Runner.debug.xcconfig */,
|
||||||
|
EE5AE3E3797C8A45B5AFA537 /* Pods-Runner.release.xcconfig */,
|
||||||
|
12F3806130EB6FDA0BB8224F /* Pods-Runner.profile.xcconfig */,
|
||||||
|
DF96ECE6A0AC0BFA8724174B /* Pods-RunnerTests.debug.xcconfig */,
|
||||||
|
AE13A81982696D2690FB1CAB /* Pods-RunnerTests.release.xcconfig */,
|
||||||
|
D208168B6EAB5683BAD27E86 /* Pods-RunnerTests.profile.xcconfig */,
|
||||||
|
);
|
||||||
|
path = Pods;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
331C8082294A63A400263BE5 /* RunnerTests */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
331C807B294A618700263BE5 /* RunnerTests.swift */,
|
||||||
|
);
|
||||||
|
path = RunnerTests;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
51BA414B0BC240BA4DED076E /* Frameworks */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
EDC5CDC3E1AFF7C5BC49C07E /* Pods_Runner.framework */,
|
||||||
|
20818F4FAA848E7B0E1981A1 /* Pods_RunnerTests.framework */,
|
||||||
|
);
|
||||||
|
name = Frameworks;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
9740EEB11CF90186004384FC /* Flutter */ = {
|
9740EEB11CF90186004384FC /* Flutter */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -79,14 +129,6 @@
|
|||||||
name = Flutter;
|
name = Flutter;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
331C8082294A63A400263BE5 /* RunnerTests */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
331C807B294A618700263BE5 /* RunnerTests.swift */,
|
|
||||||
);
|
|
||||||
path = RunnerTests;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
97C146E51CF9000F007C117D = {
|
97C146E51CF9000F007C117D = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -94,6 +136,8 @@
|
|||||||
97C146F01CF9000F007C117D /* Runner */,
|
97C146F01CF9000F007C117D /* Runner */,
|
||||||
97C146EF1CF9000F007C117D /* Products */,
|
97C146EF1CF9000F007C117D /* Products */,
|
||||||
331C8082294A63A400263BE5 /* RunnerTests */,
|
331C8082294A63A400263BE5 /* RunnerTests */,
|
||||||
|
04ACC4FC139085193359BE10 /* Pods */,
|
||||||
|
51BA414B0BC240BA4DED076E /* Frameworks */,
|
||||||
);
|
);
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
@@ -109,6 +153,7 @@
|
|||||||
97C146F01CF9000F007C117D /* Runner */ = {
|
97C146F01CF9000F007C117D /* Runner */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
7CD878882EBBB898002F3C7D /* Runner.entitlements */,
|
||||||
97C146FA1CF9000F007C117D /* Main.storyboard */,
|
97C146FA1CF9000F007C117D /* Main.storyboard */,
|
||||||
97C146FD1CF9000F007C117D /* Assets.xcassets */,
|
97C146FD1CF9000F007C117D /* Assets.xcassets */,
|
||||||
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
|
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
|
||||||
@@ -128,9 +173,10 @@
|
|||||||
isa = PBXNativeTarget;
|
isa = PBXNativeTarget;
|
||||||
buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */;
|
buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */;
|
||||||
buildPhases = (
|
buildPhases = (
|
||||||
|
827CC5F079B73B9074C059BC /* [CP] Check Pods Manifest.lock */,
|
||||||
331C807D294A63A400263BE5 /* Sources */,
|
331C807D294A63A400263BE5 /* Sources */,
|
||||||
331C807E294A63A400263BE5 /* Frameworks */,
|
|
||||||
331C807F294A63A400263BE5 /* Resources */,
|
331C807F294A63A400263BE5 /* Resources */,
|
||||||
|
985FE5E285D4547AB0054913 /* Frameworks */,
|
||||||
);
|
);
|
||||||
buildRules = (
|
buildRules = (
|
||||||
);
|
);
|
||||||
@@ -146,12 +192,15 @@
|
|||||||
isa = PBXNativeTarget;
|
isa = PBXNativeTarget;
|
||||||
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
|
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
|
||||||
buildPhases = (
|
buildPhases = (
|
||||||
|
1A8E37578D7C990159141841 /* [CP] Check Pods Manifest.lock */,
|
||||||
9740EEB61CF901F6004384FC /* Run Script */,
|
9740EEB61CF901F6004384FC /* Run Script */,
|
||||||
97C146EA1CF9000F007C117D /* Sources */,
|
97C146EA1CF9000F007C117D /* Sources */,
|
||||||
97C146EB1CF9000F007C117D /* Frameworks */,
|
97C146EB1CF9000F007C117D /* Frameworks */,
|
||||||
97C146EC1CF9000F007C117D /* Resources */,
|
97C146EC1CF9000F007C117D /* Resources */,
|
||||||
9705A1C41CF9048500538489 /* Embed Frameworks */,
|
9705A1C41CF9048500538489 /* Embed Frameworks */,
|
||||||
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
|
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
|
||||||
|
81B31B4B9605351C20E486B9 /* [CP] Embed Pods Frameworks */,
|
||||||
|
14FC8825887E7053BC1CD5F8 /* [CP] Copy Pods Resources */,
|
||||||
);
|
);
|
||||||
buildRules = (
|
buildRules = (
|
||||||
);
|
);
|
||||||
@@ -169,7 +218,7 @@
|
|||||||
isa = PBXProject;
|
isa = PBXProject;
|
||||||
attributes = {
|
attributes = {
|
||||||
BuildIndependentTargetsInParallel = YES;
|
BuildIndependentTargetsInParallel = YES;
|
||||||
LastUpgradeCheck = 1430;
|
LastUpgradeCheck = 1510;
|
||||||
ORGANIZATIONNAME = "";
|
ORGANIZATIONNAME = "";
|
||||||
TargetAttributes = {
|
TargetAttributes = {
|
||||||
331C8080294A63A400263BE5 = {
|
331C8080294A63A400263BE5 = {
|
||||||
@@ -223,6 +272,45 @@
|
|||||||
/* End PBXResourcesBuildPhase section */
|
/* End PBXResourcesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXShellScriptBuildPhase section */
|
/* Begin PBXShellScriptBuildPhase section */
|
||||||
|
14FC8825887E7053BC1CD5F8 /* [CP] Copy Pods Resources */ = {
|
||||||
|
isa = PBXShellScriptBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
inputFileListPaths = (
|
||||||
|
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist",
|
||||||
|
);
|
||||||
|
name = "[CP] Copy Pods Resources";
|
||||||
|
outputFileListPaths = (
|
||||||
|
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist",
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
shellPath = /bin/sh;
|
||||||
|
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n";
|
||||||
|
showEnvVarsInLog = 0;
|
||||||
|
};
|
||||||
|
1A8E37578D7C990159141841 /* [CP] Check Pods Manifest.lock */ = {
|
||||||
|
isa = PBXShellScriptBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
inputFileListPaths = (
|
||||||
|
);
|
||||||
|
inputPaths = (
|
||||||
|
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
||||||
|
"${PODS_ROOT}/Manifest.lock",
|
||||||
|
);
|
||||||
|
name = "[CP] Check Pods Manifest.lock";
|
||||||
|
outputFileListPaths = (
|
||||||
|
);
|
||||||
|
outputPaths = (
|
||||||
|
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
shellPath = /bin/sh;
|
||||||
|
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||||
|
showEnvVarsInLog = 0;
|
||||||
|
};
|
||||||
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
|
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
|
||||||
isa = PBXShellScriptBuildPhase;
|
isa = PBXShellScriptBuildPhase;
|
||||||
alwaysOutOfDate = 1;
|
alwaysOutOfDate = 1;
|
||||||
@@ -239,6 +327,45 @@
|
|||||||
shellPath = /bin/sh;
|
shellPath = /bin/sh;
|
||||||
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
|
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
|
||||||
};
|
};
|
||||||
|
81B31B4B9605351C20E486B9 /* [CP] Embed Pods Frameworks */ = {
|
||||||
|
isa = PBXShellScriptBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
inputFileListPaths = (
|
||||||
|
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
|
||||||
|
);
|
||||||
|
name = "[CP] Embed Pods Frameworks";
|
||||||
|
outputFileListPaths = (
|
||||||
|
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
shellPath = /bin/sh;
|
||||||
|
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
|
||||||
|
showEnvVarsInLog = 0;
|
||||||
|
};
|
||||||
|
827CC5F079B73B9074C059BC /* [CP] Check Pods Manifest.lock */ = {
|
||||||
|
isa = PBXShellScriptBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
inputFileListPaths = (
|
||||||
|
);
|
||||||
|
inputPaths = (
|
||||||
|
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
||||||
|
"${PODS_ROOT}/Manifest.lock",
|
||||||
|
);
|
||||||
|
name = "[CP] Check Pods Manifest.lock";
|
||||||
|
outputFileListPaths = (
|
||||||
|
);
|
||||||
|
outputPaths = (
|
||||||
|
"$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt",
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
shellPath = /bin/sh;
|
||||||
|
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||||
|
showEnvVarsInLog = 0;
|
||||||
|
};
|
||||||
9740EEB61CF901F6004384FC /* Run Script */ = {
|
9740EEB61CF901F6004384FC /* Run Script */ = {
|
||||||
isa = PBXShellScriptBuildPhase;
|
isa = PBXShellScriptBuildPhase;
|
||||||
alwaysOutOfDate = 1;
|
alwaysOutOfDate = 1;
|
||||||
@@ -308,6 +435,7 @@
|
|||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
||||||
CLANG_ANALYZER_NONNULL = YES;
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||||
CLANG_CXX_LIBRARY = "libc++";
|
CLANG_CXX_LIBRARY = "libc++";
|
||||||
@@ -337,6 +465,7 @@
|
|||||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
ENABLE_NS_ASSERTIONS = NO;
|
ENABLE_NS_ASSERTIONS = NO;
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
|
ENABLE_USER_SCRIPT_SANDBOXING = NO;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||||
GCC_NO_COMMON_BLOCKS = YES;
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
@@ -345,7 +474,7 @@
|
|||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
||||||
MTL_ENABLE_DEBUG_INFO = NO;
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
SUPPORTED_PLATFORMS = iphoneos;
|
SUPPORTED_PLATFORMS = iphoneos;
|
||||||
@@ -356,19 +485,26 @@
|
|||||||
};
|
};
|
||||||
249021D4217E4FDB00AE95B9 /* Profile */ = {
|
249021D4217E4FDB00AE95B9 /* Profile */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
|
baseConfigurationReference = 12F3806130EB6FDA0BB8224F /* Pods-Runner.profile.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||||
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
DEVELOPMENT_TEAM = H5FLAAV8F2;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
|
INFOPLIST_KEY_CFBundleDisplayName = SimpleCloudNotifier;
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 15.6;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.blackforestbytes.simplecloudnotifier;
|
MARKETING_VERSION = 1.0;
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = com.blackforestbytes.SimpleCloudNotifier;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
VERSIONING_SYSTEM = "apple-generic";
|
VERSIONING_SYSTEM = "apple-generic";
|
||||||
@@ -377,7 +513,7 @@
|
|||||||
};
|
};
|
||||||
331C8088294A63A400263BE5 /* Debug */ = {
|
331C8088294A63A400263BE5 /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
baseConfigurationReference = AE0B7B92F70575B8D7E0D07E /* Pods-RunnerTests.debug.xcconfig */;
|
baseConfigurationReference = DF96ECE6A0AC0BFA8724174B /* Pods-RunnerTests.debug.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
@@ -395,7 +531,7 @@
|
|||||||
};
|
};
|
||||||
331C8089294A63A400263BE5 /* Release */ = {
|
331C8089294A63A400263BE5 /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
baseConfigurationReference = 89B67EB44CE7B6631473024E /* Pods-RunnerTests.release.xcconfig */;
|
baseConfigurationReference = AE13A81982696D2690FB1CAB /* Pods-RunnerTests.release.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
@@ -411,7 +547,7 @@
|
|||||||
};
|
};
|
||||||
331C808A294A63A400263BE5 /* Profile */ = {
|
331C808A294A63A400263BE5 /* Profile */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
baseConfigurationReference = 640959BDD8F10B91D80A66BE /* Pods-RunnerTests.profile.xcconfig */;
|
baseConfigurationReference = D208168B6EAB5683BAD27E86 /* Pods-RunnerTests.profile.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
@@ -427,8 +563,10 @@
|
|||||||
};
|
};
|
||||||
97C147031CF9000F007C117D /* Debug */ = {
|
97C147031CF9000F007C117D /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
|
baseConfigurationReference = 9740EEB31CF90195004384FC /* Generated.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
||||||
CLANG_ANALYZER_NONNULL = YES;
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||||
CLANG_CXX_LIBRARY = "libc++";
|
CLANG_CXX_LIBRARY = "libc++";
|
||||||
@@ -458,6 +596,7 @@
|
|||||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
ENABLE_TESTABILITY = YES;
|
ENABLE_TESTABILITY = YES;
|
||||||
|
ENABLE_USER_SCRIPT_SANDBOXING = NO;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||||
GCC_DYNAMIC_NO_PIC = NO;
|
GCC_DYNAMIC_NO_PIC = NO;
|
||||||
GCC_NO_COMMON_BLOCKS = YES;
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
@@ -472,7 +611,7 @@
|
|||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
||||||
MTL_ENABLE_DEBUG_INFO = YES;
|
MTL_ENABLE_DEBUG_INFO = YES;
|
||||||
ONLY_ACTIVE_ARCH = YES;
|
ONLY_ACTIVE_ARCH = YES;
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
@@ -482,8 +621,10 @@
|
|||||||
};
|
};
|
||||||
97C147041CF9000F007C117D /* Release */ = {
|
97C147041CF9000F007C117D /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
|
baseConfigurationReference = 9740EEB31CF90195004384FC /* Generated.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
||||||
CLANG_ANALYZER_NONNULL = YES;
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||||
CLANG_CXX_LIBRARY = "libc++";
|
CLANG_CXX_LIBRARY = "libc++";
|
||||||
@@ -513,6 +654,7 @@
|
|||||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
ENABLE_NS_ASSERTIONS = NO;
|
ENABLE_NS_ASSERTIONS = NO;
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
|
ENABLE_USER_SCRIPT_SANDBOXING = NO;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||||
GCC_NO_COMMON_BLOCKS = YES;
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
@@ -521,7 +663,7 @@
|
|||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
||||||
MTL_ENABLE_DEBUG_INFO = NO;
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
SUPPORTED_PLATFORMS = iphoneos;
|
SUPPORTED_PLATFORMS = iphoneos;
|
||||||
@@ -534,19 +676,26 @@
|
|||||||
};
|
};
|
||||||
97C147061CF9000F007C117D /* Debug */ = {
|
97C147061CF9000F007C117D /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
|
baseConfigurationReference = A4D58F2C21BD1C00F0A1FE7D /* Pods-Runner.debug.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||||
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
DEVELOPMENT_TEAM = H5FLAAV8F2;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
|
INFOPLIST_KEY_CFBundleDisplayName = SimpleCloudNotifier;
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 15.6;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.blackforestbytes.simplecloudnotifier;
|
MARKETING_VERSION = 1.0;
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = com.blackforestbytes.SimpleCloudNotifier;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
@@ -556,19 +705,26 @@
|
|||||||
};
|
};
|
||||||
97C147071CF9000F007C117D /* Release */ = {
|
97C147071CF9000F007C117D /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
|
baseConfigurationReference = EE5AE3E3797C8A45B5AFA537 /* Pods-Runner.release.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||||
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
DEVELOPMENT_TEAM = H5FLAAV8F2;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
|
INFOPLIST_KEY_CFBundleDisplayName = SimpleCloudNotifier;
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 15.6;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.blackforestbytes.simplecloudnotifier;
|
MARKETING_VERSION = 1.0;
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = com.blackforestbytes.SimpleCloudNotifier;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
VERSIONING_SYSTEM = "apple-generic";
|
VERSIONING_SYSTEM = "apple-generic";
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<Scheme
|
<Scheme
|
||||||
LastUpgradeVersion = "1430"
|
LastUpgradeVersion = "1510"
|
||||||
version = "1.3">
|
version = "1.3">
|
||||||
<BuildAction
|
<BuildAction
|
||||||
parallelizeBuildables = "YES"
|
parallelizeBuildables = "YES"
|
||||||
@@ -26,6 +26,7 @@
|
|||||||
buildConfiguration = "Debug"
|
buildConfiguration = "Debug"
|
||||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
|
customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit"
|
||||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||||
<MacroExpansion>
|
<MacroExpansion>
|
||||||
<BuildableReference
|
<BuildableReference
|
||||||
@@ -54,11 +55,13 @@
|
|||||||
buildConfiguration = "Debug"
|
buildConfiguration = "Debug"
|
||||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
|
customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit"
|
||||||
launchStyle = "0"
|
launchStyle = "0"
|
||||||
useCustomWorkingDirectory = "NO"
|
useCustomWorkingDirectory = "NO"
|
||||||
ignoresPersistentStateOnLaunch = "NO"
|
ignoresPersistentStateOnLaunch = "NO"
|
||||||
debugDocumentVersioning = "YES"
|
debugDocumentVersioning = "YES"
|
||||||
debugServiceExtension = "internal"
|
debugServiceExtension = "internal"
|
||||||
|
enableGPUValidationMode = "1"
|
||||||
allowLocationSimulation = "YES">
|
allowLocationSimulation = "YES">
|
||||||
<BuildableProductRunnable
|
<BuildableProductRunnable
|
||||||
runnableDebuggingMode = "0">
|
runnableDebuggingMode = "0">
|
||||||
|
|||||||
@@ -4,4 +4,7 @@
|
|||||||
<FileRef
|
<FileRef
|
||||||
location = "group:Runner.xcodeproj">
|
location = "group:Runner.xcodeproj">
|
||||||
</FileRef>
|
</FileRef>
|
||||||
|
<FileRef
|
||||||
|
location = "group:Pods/Pods.xcodeproj">
|
||||||
|
</FileRef>
|
||||||
</Workspace>
|
</Workspace>
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
||||||
<plist version="1.0">
|
|
||||||
<dict>
|
|
||||||
<key>PreviewsEnabled</key>
|
|
||||||
<false/>
|
|
||||||
</dict>
|
|
||||||
</plist>
|
|
||||||
@@ -2,7 +2,7 @@ import UIKit
|
|||||||
import Flutter
|
import Flutter
|
||||||
import flutter_local_notifications
|
import flutter_local_notifications
|
||||||
|
|
||||||
@UIApplicationMain
|
@main
|
||||||
@objc class AppDelegate: FlutterAppDelegate {
|
@objc class AppDelegate: FlutterAppDelegate {
|
||||||
|
|
||||||
override func application(
|
override func application(
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
|
<key>CADisableMinimumFrameDurationOnPhone</key>
|
||||||
|
<true/>
|
||||||
<key>CFBundleDevelopmentRegion</key>
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||||
<key>CFBundleDisplayName</key>
|
<key>CFBundleDisplayName</key>
|
||||||
@@ -24,6 +26,17 @@
|
|||||||
<string>$(FLUTTER_BUILD_NUMBER)</string>
|
<string>$(FLUTTER_BUILD_NUMBER)</string>
|
||||||
<key>LSRequiresIPhoneOS</key>
|
<key>LSRequiresIPhoneOS</key>
|
||||||
<true/>
|
<true/>
|
||||||
|
<key>NSCameraUsageDescription</key>
|
||||||
|
<string>This app needs camera access to scan QR codes</string>
|
||||||
|
<key>NSPhotoLibraryUsageDescription</key>
|
||||||
|
<string>This app needs photos access to get QR code from photo library</string>
|
||||||
|
<key>UIApplicationSupportsIndirectInputEvents</key>
|
||||||
|
<true/>
|
||||||
|
<key>UIBackgroundModes</key>
|
||||||
|
<array>
|
||||||
|
<string>remote-notification</string>
|
||||||
|
<string>fetch</string>
|
||||||
|
</array>
|
||||||
<key>UILaunchStoryboardName</key>
|
<key>UILaunchStoryboardName</key>
|
||||||
<string>LaunchScreen</string>
|
<string>LaunchScreen</string>
|
||||||
<key>UIMainStoryboardFile</key>
|
<key>UIMainStoryboardFile</key>
|
||||||
@@ -41,14 +54,5 @@
|
|||||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||||
</array>
|
</array>
|
||||||
<key>CADisableMinimumFrameDurationOnPhone</key>
|
|
||||||
<true/>
|
|
||||||
<key>UIApplicationSupportsIndirectInputEvents</key>
|
|
||||||
<true/>
|
|
||||||
<key>NSCameraUsageDescription</key>
|
|
||||||
<string>This app needs camera access to scan QR codes</string>
|
|
||||||
|
|
||||||
<key>NSPhotoLibraryUsageDescription</key>
|
|
||||||
<string>This app needs photos access to get QR code from photo library</string>
|
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
<key>IDEDidComputeMac32BitWarning</key>
|
<key>aps-environment</key>
|
||||||
<true/>
|
<string>development</string>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
@@ -54,6 +54,20 @@ class MessageFilter {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class SubscriptionFilter {
|
||||||
|
static final SubscriptionFilter ALL = SubscriptionFilter('both', 'all', 'all');
|
||||||
|
static final SubscriptionFilter OWNED_INACTIVE = SubscriptionFilter('outgoing', 'unconfirmed', 'false');
|
||||||
|
static final SubscriptionFilter OWNED_ACTIVE = SubscriptionFilter('outgoing', 'confirmed', 'false');
|
||||||
|
static final SubscriptionFilter EXTERNAL_ALL = SubscriptionFilter('outgoing', 'all', 'true');
|
||||||
|
static final SubscriptionFilter INCOMING_ALL = SubscriptionFilter('incoming', 'all', 'true');
|
||||||
|
|
||||||
|
final String direction; // 'outgoing' | 'incoming' | 'both'
|
||||||
|
final String confirmation; // 'confirmed' | 'unconfirmed' | 'all'
|
||||||
|
final String external; // 'true' | 'false' | 'all'
|
||||||
|
|
||||||
|
SubscriptionFilter(this.direction, this.confirmation, this.external) {}
|
||||||
|
}
|
||||||
|
|
||||||
class APIClient {
|
class APIClient {
|
||||||
static const String _base = 'https://simplecloudnotifier.de';
|
static const String _base = 'https://simplecloudnotifier.de';
|
||||||
static const String _prefix = '/api/v2';
|
static const String _prefix = '/api/v2';
|
||||||
@@ -123,7 +137,7 @@ class APIClient {
|
|||||||
|
|
||||||
RequestLog.addRequestAPIError(name, t0, method, uri, req.body, req.headers, responseStatusCode, responseBody, responseHeaders, apierr);
|
RequestLog.addRequestAPIError(name, t0, method, uri, req.body, req.headers, responseStatusCode, responseBody, responseHeaders, apierr);
|
||||||
Toaster.error("Error", apierr.message);
|
Toaster.error("Error", apierr.message);
|
||||||
throw APIException(responseStatusCode, apierr.error, apierr.errhighlight, apierr.message);
|
throw APIException(responseStatusCode, apierr.error, apierr.errhighlight, apierr.message, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -345,15 +359,15 @@ class APIClient {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<List<Subscription>> getSubscriptionList(TokenSource auth) async {
|
static Future<List<Subscription>> getSubscriptionList(TokenSource auth, SubscriptionFilter filter) async {
|
||||||
return await _request(
|
return await _request(
|
||||||
name: 'getSubscriptionList',
|
name: 'getSubscriptionList',
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
relURL: 'users/${auth.getUserID()}/subscriptions',
|
relURL: 'users/${auth.getUserID()}/subscriptions',
|
||||||
query: {
|
query: {
|
||||||
'direction': ['both'],
|
'direction': [filter.direction],
|
||||||
'confirmation': ['all'],
|
'confirmation': [filter.confirmation],
|
||||||
'external': ['all'],
|
'external': [filter.external],
|
||||||
},
|
},
|
||||||
fn: (json) => Subscription.fromJsonArray(json['subscriptions'] as List<dynamic>),
|
fn: (json) => Subscription.fromJsonArray(json['subscriptions'] as List<dynamic>),
|
||||||
authToken: auth.getToken(),
|
authToken: auth.getToken(),
|
||||||
|
|||||||
@@ -3,8 +3,9 @@ class APIException implements Exception {
|
|||||||
final int error;
|
final int error;
|
||||||
final int errHighlight;
|
final int errHighlight;
|
||||||
final String message;
|
final String message;
|
||||||
|
final bool toastShown;
|
||||||
|
|
||||||
APIException(this.httpStatus, this.error, this.errHighlight, this.message);
|
APIException(this.httpStatus, this.error, this.errHighlight, this.message, this.toastShown);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
|
|||||||
@@ -2,33 +2,56 @@ import 'package:flutter/material.dart';
|
|||||||
|
|
||||||
enum BadgeMode { error, warn, info }
|
enum BadgeMode { error, warn, info }
|
||||||
|
|
||||||
class BadgeDisplay extends StatelessWidget {
|
class BadgeDisplay extends StatefulWidget {
|
||||||
final String text;
|
final String text;
|
||||||
final BadgeMode mode;
|
final BadgeMode mode;
|
||||||
final IconData? icon;
|
final IconData? icon;
|
||||||
|
final TextAlign textAlign;
|
||||||
|
final bool closable;
|
||||||
|
final EdgeInsets extraPadding;
|
||||||
|
final bool hidden;
|
||||||
|
|
||||||
const BadgeDisplay({
|
const BadgeDisplay({
|
||||||
Key? key,
|
Key? key,
|
||||||
required this.text,
|
required this.text,
|
||||||
required this.mode,
|
required this.mode,
|
||||||
required this.icon,
|
required this.icon,
|
||||||
|
this.textAlign = TextAlign.center,
|
||||||
|
this.closable = false,
|
||||||
|
this.extraPadding = EdgeInsets.zero,
|
||||||
|
this.hidden = false,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<BadgeDisplay> createState() => _BadgeDisplayState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _BadgeDisplayState extends State<BadgeDisplay> {
|
||||||
|
bool _isVisible = true;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
if (!_isVisible || widget.hidden) return const SizedBox.shrink();
|
||||||
|
|
||||||
var col = Colors.grey;
|
var col = Colors.grey;
|
||||||
var colFG = Colors.black;
|
var colFG = Colors.black;
|
||||||
|
|
||||||
if (mode == BadgeMode.error) col = Colors.red;
|
if (widget.mode == BadgeMode.error) col = Colors.red;
|
||||||
if (mode == BadgeMode.warn) col = Colors.orange;
|
if (widget.mode == BadgeMode.warn) col = Colors.orange;
|
||||||
if (mode == BadgeMode.info) col = Colors.blue;
|
if (widget.mode == BadgeMode.info) col = Colors.blue;
|
||||||
|
|
||||||
if (mode == BadgeMode.error) colFG = Colors.red[900]!;
|
if (widget.mode == BadgeMode.error) colFG = Colors.red[900]!;
|
||||||
if (mode == BadgeMode.warn) colFG = Colors.black;
|
if (widget.mode == BadgeMode.warn) colFG = Colors.black;
|
||||||
if (mode == BadgeMode.info) colFG = Colors.black;
|
if (widget.mode == BadgeMode.info) colFG = Colors.black;
|
||||||
|
|
||||||
return Container(
|
return Container(
|
||||||
padding: const EdgeInsets.fromLTRB(8, 2, 8, 2),
|
margin: widget.extraPadding,
|
||||||
|
child: Stack(
|
||||||
|
clipBehavior: Clip.none,
|
||||||
|
children: [
|
||||||
|
// The badge itself
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.fromLTRB(8, 2, widget.closable ? 16 : 8, 2),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: col[100],
|
color: col[100],
|
||||||
border: Border.all(color: col[300]!),
|
border: Border.all(color: col[300]!),
|
||||||
@@ -36,16 +59,47 @@ class BadgeDisplay extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
if (icon != null) Icon(icon!, color: colFG, size: 16.0),
|
if (widget.icon != null) Icon(widget.icon!, color: colFG, size: 16.0),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Text(
|
child: Text(
|
||||||
text,
|
widget.text,
|
||||||
textAlign: TextAlign.center,
|
textAlign: widget.textAlign,
|
||||||
style: TextStyle(color: colFG, fontSize: 14.0),
|
style: TextStyle(color: colFG, fontSize: 14.0),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
if (widget.closable) _buildCloseButton(context, colFG),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Positioned _buildCloseButton(BuildContext context, Color colFG) {
|
||||||
|
return Positioned(
|
||||||
|
top: 4,
|
||||||
|
right: 4,
|
||||||
|
child: Material(
|
||||||
|
color: Colors.transparent,
|
||||||
|
child: InkWell(
|
||||||
|
onTap: () {
|
||||||
|
setState(() {
|
||||||
|
_isVisible = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
child: Container(
|
||||||
|
padding: const EdgeInsets.all(2),
|
||||||
|
child: Icon(
|
||||||
|
Icons.close,
|
||||||
|
size: 14,
|
||||||
|
color: colFG,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
47
flutter/lib/components/filter_chips/filter_chips.dart
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class FilterChips<T extends Enum> extends StatelessWidget {
|
||||||
|
final List<(T, String)> options;
|
||||||
|
final T value;
|
||||||
|
final void Function(T)? onChanged;
|
||||||
|
|
||||||
|
const FilterChips({
|
||||||
|
Key? key,
|
||||||
|
required this.options,
|
||||||
|
required this.value,
|
||||||
|
required this.onChanged,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return SingleChildScrollView(
|
||||||
|
scrollDirection: Axis.horizontal,
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
for (var opt in options) _buildChiplet(context, opt.$1, opt.$2),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildChiplet(BuildContext context, T optValue, String optText) {
|
||||||
|
final isSelected = optValue == value;
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.fromLTRB(0, 2, 4, 2),
|
||||||
|
child: InputChip(
|
||||||
|
label: Text(
|
||||||
|
optText,
|
||||||
|
style: isSelected ? TextStyle(color: Theme.of(context).colorScheme.onPrimary) : null,
|
||||||
|
),
|
||||||
|
visualDensity: VisualDensity(horizontal: -4, vertical: -4),
|
||||||
|
isEnabled: true,
|
||||||
|
selected: true,
|
||||||
|
showCheckmark: false,
|
||||||
|
onPressed: () {
|
||||||
|
if (!isSelected) onChanged?.call(optValue);
|
||||||
|
},
|
||||||
|
selectedColor: isSelected ? Theme.of(context).colorScheme.primary : null,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -20,20 +20,30 @@ class SCNNavLayout extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _SCNNavLayoutState extends State<SCNNavLayout> {
|
class _SCNNavLayoutState extends State<SCNNavLayout> {
|
||||||
int _selectedIndex = 0; // 4 == FAB
|
static const INDEX_MESSAGES = 0;
|
||||||
|
static const INDEX_CHANNELS = 1;
|
||||||
|
static const INDEX_ACCOUNT = 2;
|
||||||
|
static const INDEX_CONFIG = 3;
|
||||||
|
static const INDEX_SEND = 4; // FAB
|
||||||
|
|
||||||
|
int _selectedIndex = INDEX_MESSAGES;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
initState() {
|
initState() {
|
||||||
final userAcc = Provider.of<AppAuth>(context, listen: false);
|
final userAcc = Provider.of<AppAuth>(context, listen: false);
|
||||||
if (!userAcc.isAuth()) _selectedIndex = 2;
|
if (!userAcc.isAuth()) _selectedIndex = INDEX_ACCOUNT;
|
||||||
|
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onItemTapped(int index) {
|
void _onItemTapped(int index) {
|
||||||
final userAcc = Provider.of<AppAuth>(context, listen: false);
|
final userAcc = Provider.of<AppAuth>(context, listen: false);
|
||||||
if (!userAcc.isAuth()) {
|
|
||||||
|
if (!userAcc.isAuth() && [INDEX_MESSAGES, INDEX_CHANNELS, INDEX_SEND].contains(index)) {
|
||||||
Toaster.info("Not logged in", "Please login or create a new account first");
|
Toaster.info("Not logged in", "Please login or create a new account first");
|
||||||
|
setState(() {
|
||||||
|
_selectedIndex = INDEX_ACCOUNT;
|
||||||
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,7 +60,7 @@ class _SCNNavLayoutState extends State<SCNNavLayout> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setState(() {
|
setState(() {
|
||||||
_selectedIndex = 4;
|
_selectedIndex = INDEX_SEND;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,17 +69,17 @@ class _SCNNavLayoutState extends State<SCNNavLayout> {
|
|||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: SCNAppBar(
|
appBar: SCNAppBar(
|
||||||
title: null,
|
title: null,
|
||||||
showSearch: _selectedIndex == 0,
|
showSearch: _selectedIndex == INDEX_MESSAGES,
|
||||||
showShare: false,
|
showShare: false,
|
||||||
showThemeSwitch: true,
|
showThemeSwitch: true,
|
||||||
),
|
),
|
||||||
body: IndexedStack(
|
body: IndexedStack(
|
||||||
children: [
|
children: [
|
||||||
ExcludeFocus(excluding: _selectedIndex != 0, child: MessageListPage(isVisiblePage: _selectedIndex == 0)),
|
ExcludeFocus(excluding: _selectedIndex != INDEX_MESSAGES, child: MessageListPage(isVisiblePage: _selectedIndex == INDEX_MESSAGES)),
|
||||||
ExcludeFocus(excluding: _selectedIndex != 1, child: ChannelRootPage(isVisiblePage: _selectedIndex == 1)),
|
ExcludeFocus(excluding: _selectedIndex != INDEX_CHANNELS, child: ChannelRootPage(isVisiblePage: _selectedIndex == INDEX_CHANNELS)),
|
||||||
ExcludeFocus(excluding: _selectedIndex != 2, child: AccountRootPage(isVisiblePage: _selectedIndex == 2)),
|
ExcludeFocus(excluding: _selectedIndex != INDEX_ACCOUNT, child: AccountRootPage(isVisiblePage: _selectedIndex == INDEX_ACCOUNT)),
|
||||||
ExcludeFocus(excluding: _selectedIndex != 3, child: SettingsRootPage(isVisiblePage: _selectedIndex == 3)),
|
ExcludeFocus(excluding: _selectedIndex != INDEX_CONFIG, child: SettingsRootPage(isVisiblePage: _selectedIndex == INDEX_CONFIG)),
|
||||||
ExcludeFocus(excluding: _selectedIndex != 4, child: SendRootPage(isVisiblePage: _selectedIndex == 4)),
|
ExcludeFocus(excluding: _selectedIndex != INDEX_SEND, child: SendRootPage(isVisiblePage: _selectedIndex == INDEX_SEND)),
|
||||||
],
|
],
|
||||||
index: _selectedIndex,
|
index: _selectedIndex,
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ class _FilterModalPriorityState extends State<FilterModalPriority> {
|
|||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
title: const Text('Priority'),
|
title: const Text('Priority'),
|
||||||
content: Container(
|
content: Container(
|
||||||
width: 0,
|
width: 9000,
|
||||||
height: 200,
|
height: 200,
|
||||||
child: ListView.builder(
|
child: ListView.builder(
|
||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
|
|||||||
@@ -167,11 +167,13 @@ class _SCNAppState extends State<SCNApp> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
|
if (Globals().clientType == 'IOS' || Globals().clientType == 'ANDROID') {
|
||||||
_purchaseSubscription = InAppPurchase.instance.purchaseStream.listen(
|
_purchaseSubscription = InAppPurchase.instance.purchaseStream.listen(
|
||||||
purchaseUpdated,
|
purchaseUpdated,
|
||||||
onDone: () => _purchaseSubscription?.cancel(),
|
onDone: () => _purchaseSubscription?.cancel(),
|
||||||
onError: purchaseError,
|
onError: purchaseError,
|
||||||
);
|
);
|
||||||
|
}
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,9 +7,11 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:simplecloudnotifier/api/api_client.dart';
|
import 'package:simplecloudnotifier/api/api_client.dart';
|
||||||
|
import 'package:simplecloudnotifier/api/api_exception.dart';
|
||||||
import 'package:simplecloudnotifier/components/error_display/error_display.dart';
|
import 'package:simplecloudnotifier/components/error_display/error_display.dart';
|
||||||
import 'package:simplecloudnotifier/models/user.dart';
|
import 'package:simplecloudnotifier/models/user.dart';
|
||||||
import 'package:simplecloudnotifier/pages/account/login.dart';
|
import 'package:simplecloudnotifier/pages/account/login.dart';
|
||||||
|
import 'package:simplecloudnotifier/pages/account/show_token_modal.dart';
|
||||||
import 'package:simplecloudnotifier/pages/channel_list/channel_list_extended.dart';
|
import 'package:simplecloudnotifier/pages/channel_list/channel_list_extended.dart';
|
||||||
import 'package:simplecloudnotifier/pages/client_list/client_list.dart';
|
import 'package:simplecloudnotifier/pages/client_list/client_list.dart';
|
||||||
import 'package:simplecloudnotifier/pages/filtered_message_view/filtered_message_view.dart';
|
import 'package:simplecloudnotifier/pages/filtered_message_view/filtered_message_view.dart';
|
||||||
@@ -115,7 +117,7 @@ class _AccountRootPageState extends State<AccountRootPage> {
|
|||||||
|
|
||||||
_futureSubscriptionCount = ImmediateFuture.ofFuture(() async {
|
_futureSubscriptionCount = ImmediateFuture.ofFuture(() async {
|
||||||
if (!userAcc.isAuth()) throw new Exception('not logged in');
|
if (!userAcc.isAuth()) throw new Exception('not logged in');
|
||||||
final subs = await APIClient.getSubscriptionList(userAcc);
|
final subs = await APIClient.getSubscriptionList(userAcc, SubscriptionFilter.ALL);
|
||||||
return subs.length;
|
return subs.length;
|
||||||
}());
|
}());
|
||||||
|
|
||||||
@@ -151,7 +153,7 @@ class _AccountRootPageState extends State<AccountRootPage> {
|
|||||||
// refresh all data and then replace teh futures used in build()
|
// refresh all data and then replace teh futures used in build()
|
||||||
|
|
||||||
final channelsAll = await APIClient.getChannelList(userAcc, ChannelSelector.all);
|
final channelsAll = await APIClient.getChannelList(userAcc, ChannelSelector.all);
|
||||||
final subs = await APIClient.getSubscriptionList(userAcc);
|
final subs = await APIClient.getSubscriptionList(userAcc, SubscriptionFilter.ALL);
|
||||||
final clients = await APIClient.getClientList(userAcc);
|
final clients = await APIClient.getClientList(userAcc);
|
||||||
final keys = await APIClient.getKeyTokenList(userAcc);
|
final keys = await APIClient.getKeyTokenList(userAcc);
|
||||||
final senderNames = await APIClient.getSenderNameList(userAcc);
|
final senderNames = await APIClient.getSenderNameList(userAcc);
|
||||||
@@ -165,6 +167,9 @@ class _AccountRootPageState extends State<AccountRootPage> {
|
|||||||
_futureSenderNamesCount = ImmediateFuture.ofValue(senderNames.length);
|
_futureSenderNamesCount = ImmediateFuture.ofValue(senderNames.length);
|
||||||
_futureUser = ImmediateFuture.ofValue(user);
|
_futureUser = ImmediateFuture.ofValue(user);
|
||||||
});
|
});
|
||||||
|
} on APIException catch (exc, trace) {
|
||||||
|
ApplicationLog.error('Failed to refresh account data: ' + exc.toString(), trace: trace);
|
||||||
|
if (!exc.toastShown) Toaster.error("Error", 'Failed to refresh account data');
|
||||||
} catch (exc, trace) {
|
} catch (exc, trace) {
|
||||||
ApplicationLog.error('Failed to refresh account data: ' + exc.toString(), trace: trace);
|
ApplicationLog.error('Failed to refresh account data: ' + exc.toString(), trace: trace);
|
||||||
Toaster.error("Error", 'Failed to refresh account data');
|
Toaster.error("Error", 'Failed to refresh account data');
|
||||||
@@ -268,7 +273,20 @@ class _AccountRootPageState extends State<AccountRootPage> {
|
|||||||
_buildHeader(context, user),
|
_buildHeader(context, user),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
Text(user.username ?? user.userID, overflow: TextOverflow.ellipsis, style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20)),
|
Text(user.username ?? user.userID, overflow: TextOverflow.ellipsis, style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20)),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 8),
|
||||||
|
if (acc.tokenSend != null || acc.tokenAdmin != null)
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: UI.button(
|
||||||
|
text: 'UserID & Token kopieren',
|
||||||
|
onPressed: () => _showTokenModal(context, acc),
|
||||||
|
icon: FontAwesomeIcons.copy,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
..._buildCards(context, user),
|
..._buildCards(context, user),
|
||||||
SizedBox(height: 16),
|
SizedBox(height: 16),
|
||||||
_buildFooter(context, user),
|
_buildFooter(context, user),
|
||||||
@@ -403,7 +421,13 @@ class _AccountRootPageState extends State<AccountRootPage> {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
Navi.push(context, () => FilteredMessageViewPage(title: "All Messages", filter: MessageFilter(senderUserID: [user.userID])));
|
Navi.push(
|
||||||
|
context,
|
||||||
|
() => FilteredMessageViewPage(
|
||||||
|
title: "All Messages",
|
||||||
|
alertText: "All messages sent from your account",
|
||||||
|
filter: MessageFilter(senderUserID: [user.userID]),
|
||||||
|
));
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
@@ -460,14 +484,16 @@ class _AccountRootPageState extends State<AccountRootPage> {
|
|||||||
text: 'Logout',
|
text: 'Logout',
|
||||||
onPressed: _logout,
|
onPressed: _logout,
|
||||||
color: Colors.orange,
|
color: Colors.orange,
|
||||||
)),
|
),
|
||||||
|
),
|
||||||
const SizedBox(width: 8),
|
const SizedBox(width: 8),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: UI.button(
|
child: UI.button(
|
||||||
text: 'Delete Account',
|
text: 'Delete Account',
|
||||||
onPressed: _deleteAccount,
|
onPressed: _deleteAccount,
|
||||||
color: Colors.red,
|
color: Colors.red,
|
||||||
)),
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -507,9 +533,17 @@ class _AccountRootPageState extends State<AccountRootPage> {
|
|||||||
|
|
||||||
await acc.save();
|
await acc.save();
|
||||||
Toaster.success("Success", 'Successfully Created a new account');
|
Toaster.success("Success", 'Successfully Created a new account');
|
||||||
} catch (exc, trace) {
|
|
||||||
|
showDialog<void>(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => ShowTokenModal(account: acc, isAfterRegister: true),
|
||||||
|
);
|
||||||
|
} on APIException catch (exc, trace) {
|
||||||
|
if (!exc.toastShown) Toaster.error("Error", 'Failed to create user account');
|
||||||
ApplicationLog.error('Failed to create user account: ' + exc.toString(), trace: trace);
|
ApplicationLog.error('Failed to create user account: ' + exc.toString(), trace: trace);
|
||||||
|
} catch (exc, trace) {
|
||||||
Toaster.error("Error", 'Failed to create user account');
|
Toaster.error("Error", 'Failed to create user account');
|
||||||
|
ApplicationLog.error('Failed to create user account: ' + exc.toString(), trace: trace);
|
||||||
} finally {
|
} finally {
|
||||||
setState(() => loading = false);
|
setState(() => loading = false);
|
||||||
}
|
}
|
||||||
@@ -553,6 +587,9 @@ class _AccountRootPageState extends State<AccountRootPage> {
|
|||||||
//TODO clear messages/channels/etc in open views
|
//TODO clear messages/channels/etc in open views
|
||||||
acc.clear();
|
acc.clear();
|
||||||
await acc.save();
|
await acc.save();
|
||||||
|
} on APIException catch (exc, trace) {
|
||||||
|
if (!exc.toastShown) Toaster.error("Error", 'Failed to delete user');
|
||||||
|
ApplicationLog.error('Failed to delete user: ' + exc.toString(), trace: trace);
|
||||||
} catch (exc, trace) {
|
} catch (exc, trace) {
|
||||||
Toaster.error("Error", 'Failed to delete user');
|
Toaster.error("Error", 'Failed to delete user');
|
||||||
ApplicationLog.error('Failed to delete user: ' + exc.toString(), trace: trace);
|
ApplicationLog.error('Failed to delete user: ' + exc.toString(), trace: trace);
|
||||||
@@ -580,6 +617,9 @@ class _AccountRootPageState extends State<AccountRootPage> {
|
|||||||
Toaster.success("Success", 'Username changed');
|
Toaster.success("Success", 'Username changed');
|
||||||
|
|
||||||
_backgroundRefresh();
|
_backgroundRefresh();
|
||||||
|
} on APIException catch (exc, trace) {
|
||||||
|
if (!exc.toastShown) Toaster.error("Error", 'Failed to update username');
|
||||||
|
ApplicationLog.error('Failed to update username: ' + exc.toString(), trace: trace);
|
||||||
} catch (exc, trace) {
|
} catch (exc, trace) {
|
||||||
Toaster.error("Error", 'Failed to update username');
|
Toaster.error("Error", 'Failed to update username');
|
||||||
ApplicationLog.error('Failed to update username: ' + exc.toString(), trace: trace);
|
ApplicationLog.error('Failed to update username: ' + exc.toString(), trace: trace);
|
||||||
@@ -717,4 +757,11 @@ class _AccountRootPageState extends State<AccountRootPage> {
|
|||||||
|
|
||||||
return completer.future;
|
return completer.future;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _showTokenModal(BuildContext context, AppAuth acc) {
|
||||||
|
showDialog<void>(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => ShowTokenModal(account: acc, isAfterRegister: false),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:simplecloudnotifier/api/api_client.dart';
|
import 'package:simplecloudnotifier/api/api_client.dart';
|
||||||
|
import 'package:simplecloudnotifier/api/api_exception.dart';
|
||||||
import 'package:simplecloudnotifier/components/layout/scaffold.dart';
|
import 'package:simplecloudnotifier/components/layout/scaffold.dart';
|
||||||
import 'package:simplecloudnotifier/state/application_log.dart';
|
import 'package:simplecloudnotifier/state/application_log.dart';
|
||||||
import 'package:simplecloudnotifier/state/globals.dart';
|
import 'package:simplecloudnotifier/state/globals.dart';
|
||||||
@@ -162,9 +163,12 @@ class _AccountLoginPageState extends State<AccountLoginPage> {
|
|||||||
|
|
||||||
Toaster.success("Login", "Successfully logged in");
|
Toaster.success("Login", "Successfully logged in");
|
||||||
Navi.popToRoot(context);
|
Navi.popToRoot(context);
|
||||||
} catch (exc, trace) {
|
} on APIException catch (exc, trace) {
|
||||||
|
if (!exc.toastShown) Toaster.error("Error", 'Failed to verify token');
|
||||||
ApplicationLog.error('Failed to verify token: ' + exc.toString(), trace: trace);
|
ApplicationLog.error('Failed to verify token: ' + exc.toString(), trace: trace);
|
||||||
|
} catch (exc, trace) {
|
||||||
Toaster.error("Error", 'Failed to verify token');
|
Toaster.error("Error", 'Failed to verify token');
|
||||||
|
ApplicationLog.error('Failed to verify token: ' + exc.toString(), trace: trace);
|
||||||
} finally {
|
} finally {
|
||||||
setState(() => loading = false);
|
setState(() => loading = false);
|
||||||
}
|
}
|
||||||
|
|||||||
84
flutter/lib/pages/account/show_token_modal.dart
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
|
import 'package:simplecloudnotifier/components/badge_display/badge_display.dart';
|
||||||
|
import 'package:simplecloudnotifier/state/app_auth.dart';
|
||||||
|
import 'package:simplecloudnotifier/utils/toaster.dart';
|
||||||
|
import 'package:simplecloudnotifier/utils/ui.dart';
|
||||||
|
|
||||||
|
class ShowTokenModal extends StatelessWidget {
|
||||||
|
final AppAuth account;
|
||||||
|
final bool isAfterRegister;
|
||||||
|
|
||||||
|
const ShowTokenModal({Key? key, required this.account, required this.isAfterRegister}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
var alertText = "Use your UserID and Send-Token to send messages to your account.\n\nThe Admin-Token should not be shared.";
|
||||||
|
if (this.isAfterRegister) {
|
||||||
|
alertText = "These are your UserID and tokens.\n\nBackup your Admin-Token safely.\n\nUse UserId & Send-Token to send yourself messages.";
|
||||||
|
}
|
||||||
|
|
||||||
|
return AlertDialog(
|
||||||
|
title: const Text('UserID & Token'),
|
||||||
|
content: Container(
|
||||||
|
width: 9000,
|
||||||
|
height: 450,
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
|
children: [
|
||||||
|
BadgeDisplay(
|
||||||
|
text: alertText,
|
||||||
|
icon: null,
|
||||||
|
mode: BadgeMode.info,
|
||||||
|
textAlign: TextAlign.left,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
if (this.account.userID != null)
|
||||||
|
UI.metaCard(
|
||||||
|
context: context,
|
||||||
|
icon: FontAwesomeIcons.solidUser,
|
||||||
|
title: 'UserID',
|
||||||
|
values: [this.account.userID!],
|
||||||
|
iconActions: [(FontAwesomeIcons.copy, null, () => _copy('UserID', this.account.userID!))],
|
||||||
|
),
|
||||||
|
const SizedBox(height: 4),
|
||||||
|
if (this.account.tokenSend != null)
|
||||||
|
UI.metaCard(
|
||||||
|
context: context,
|
||||||
|
icon: FontAwesomeIcons.solidKey,
|
||||||
|
title: 'Send-Token',
|
||||||
|
values: [this.account.tokenSend!],
|
||||||
|
iconActions: [(FontAwesomeIcons.copy, null, () => _copy('Send-Token', this.account.tokenSend!))],
|
||||||
|
),
|
||||||
|
const SizedBox(height: 4),
|
||||||
|
if (this.account.tokenSend != null)
|
||||||
|
UI.metaCard(
|
||||||
|
context: context,
|
||||||
|
icon: FontAwesomeIcons.solidKey,
|
||||||
|
title: 'Admin-Token',
|
||||||
|
values: [this.account.tokenAdmin!],
|
||||||
|
iconActions: [(FontAwesomeIcons.copy, null, () => _copy('Admin-Token', this.account.tokenAdmin!))],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
actions: <Widget>[
|
||||||
|
TextButton(
|
||||||
|
child: const Text('Close'),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _copy(String txt, String v) {
|
||||||
|
Clipboard.setData(new ClipboardData(text: v));
|
||||||
|
Toaster.info("Clipboard", 'Copied ${txt} to Clipboard');
|
||||||
|
print('================= [CLIPBOARD] =================\n${v}\n================= [/CLIPBOARD] =================');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -144,7 +144,19 @@ class _ChannelRootPageState extends State<ChannelRootPage> with RouteAware {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
body: RefreshIndicator(
|
body: _buildList(context),
|
||||||
|
floatingActionButton: FloatingActionButton(
|
||||||
|
heroTag: 'fab_channel_list_qr',
|
||||||
|
onPressed: () {
|
||||||
|
Navi.push(context, () => ChannelScannerPage());
|
||||||
|
},
|
||||||
|
child: const Icon(FontAwesomeIcons.qrcode),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildList(BuildContext context) {
|
||||||
|
return RefreshIndicator(
|
||||||
onRefresh: () => Future.sync(
|
onRefresh: () => Future.sync(
|
||||||
() => _pagingController.refresh(),
|
() => _pagingController.refresh(),
|
||||||
),
|
),
|
||||||
@@ -165,14 +177,6 @@ class _ChannelRootPageState extends State<ChannelRootPage> with RouteAware {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
floatingActionButton: FloatingActionButton(
|
|
||||||
heroTag: 'fab_channel_list_qr',
|
|
||||||
onPressed: () {
|
|
||||||
Navi.push(context, () => ChannelScannerPage());
|
|
||||||
},
|
|
||||||
child: const Icon(FontAwesomeIcons.qrcode),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,10 +3,12 @@ import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
|||||||
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
|
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:simplecloudnotifier/api/api_client.dart';
|
import 'package:simplecloudnotifier/api/api_client.dart';
|
||||||
|
import 'package:simplecloudnotifier/components/badge_display/badge_display.dart';
|
||||||
import 'package:simplecloudnotifier/components/layout/scaffold.dart';
|
import 'package:simplecloudnotifier/components/layout/scaffold.dart';
|
||||||
import 'package:simplecloudnotifier/models/channel.dart';
|
import 'package:simplecloudnotifier/models/channel.dart';
|
||||||
import 'package:simplecloudnotifier/pages/channel_scanner/channel_scanner.dart';
|
import 'package:simplecloudnotifier/pages/channel_scanner/channel_scanner.dart';
|
||||||
import 'package:simplecloudnotifier/state/app_bar_state.dart';
|
import 'package:simplecloudnotifier/state/app_bar_state.dart';
|
||||||
|
import 'package:simplecloudnotifier/state/app_settings.dart';
|
||||||
import 'package:simplecloudnotifier/state/application_log.dart';
|
import 'package:simplecloudnotifier/state/application_log.dart';
|
||||||
import 'package:simplecloudnotifier/state/app_auth.dart';
|
import 'package:simplecloudnotifier/state/app_auth.dart';
|
||||||
import 'package:simplecloudnotifier/pages/channel_list/channel_list_item.dart';
|
import 'package:simplecloudnotifier/pages/channel_list/channel_list_item.dart';
|
||||||
@@ -121,7 +123,35 @@ class _ChannelListExtendedPageState extends State<ChannelListExtendedPage> with
|
|||||||
showShare: false,
|
showShare: false,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: EdgeInsets.fromLTRB(8, 4, 8, 4),
|
padding: EdgeInsets.fromLTRB(8, 4, 8, 4),
|
||||||
child: RefreshIndicator(
|
child: Column(
|
||||||
|
children: [
|
||||||
|
BadgeDisplay(
|
||||||
|
text: "All channels accessible from this account\n(Your own channels and subscribed channels)",
|
||||||
|
icon: null,
|
||||||
|
mode: BadgeMode.info,
|
||||||
|
textAlign: TextAlign.left,
|
||||||
|
closable: true,
|
||||||
|
extraPadding: EdgeInsets.fromLTRB(0, 0, 0, 16),
|
||||||
|
hidden: !AppSettings().showInfoAlerts,
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: _buildList(context),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
floatingActionButton: FloatingActionButton(
|
||||||
|
heroTag: 'fab_channel_list_extended-plus',
|
||||||
|
onPressed: () {
|
||||||
|
Navi.push(context, () => ChannelScannerPage());
|
||||||
|
},
|
||||||
|
child: const Icon(FontAwesomeIcons.plus),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildList(BuildContext context) {
|
||||||
|
return RefreshIndicator(
|
||||||
onRefresh: () => Future.sync(
|
onRefresh: () => Future.sync(
|
||||||
() => _pagingController.refresh(),
|
() => _pagingController.refresh(),
|
||||||
),
|
),
|
||||||
@@ -142,15 +172,6 @@ class _ChannelListExtendedPageState extends State<ChannelListExtendedPage> with
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
),
|
|
||||||
floatingActionButton: FloatingActionButton(
|
|
||||||
heroTag: 'fab_channel_list_extended-plus',
|
|
||||||
onPressed: () {
|
|
||||||
Navi.push(context, () => ChannelScannerPage());
|
|
||||||
},
|
|
||||||
child: const Icon(FontAwesomeIcons.plus),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:simplecloudnotifier/api/api_client.dart';
|
import 'package:simplecloudnotifier/api/api_client.dart';
|
||||||
|
import 'package:simplecloudnotifier/api/api_exception.dart';
|
||||||
import 'package:simplecloudnotifier/models/channel.dart';
|
import 'package:simplecloudnotifier/models/channel.dart';
|
||||||
import 'package:simplecloudnotifier/models/scn_message.dart';
|
import 'package:simplecloudnotifier/models/scn_message.dart';
|
||||||
import 'package:simplecloudnotifier/models/subscription.dart';
|
import 'package:simplecloudnotifier/models/subscription.dart';
|
||||||
@@ -220,6 +221,9 @@ class _ChannelListItemState extends State<ChannelListItem> {
|
|||||||
} else {
|
} else {
|
||||||
Toaster.success("Success", 'Requested widget.subscription to channel');
|
Toaster.success("Success", 'Requested widget.subscription to channel');
|
||||||
}
|
}
|
||||||
|
} on APIException catch (exc, trace) {
|
||||||
|
if (!exc.toastShown) Toaster.error("Error", 'Failed to subscribe to channel');
|
||||||
|
ApplicationLog.error('Failed to subscribe to channel: ' + exc.toString(), trace: trace);
|
||||||
} catch (exc, trace) {
|
} catch (exc, trace) {
|
||||||
Toaster.error("Error", 'Failed to subscribe to channel');
|
Toaster.error("Error", 'Failed to subscribe to channel');
|
||||||
ApplicationLog.error('Failed to subscribe to channel: ' + exc.toString(), trace: trace);
|
ApplicationLog.error('Failed to subscribe to channel: ' + exc.toString(), trace: trace);
|
||||||
@@ -238,6 +242,9 @@ class _ChannelListItemState extends State<ChannelListItem> {
|
|||||||
widget.onSubscriptionChanged.call(sub.channelID, null);
|
widget.onSubscriptionChanged.call(sub.channelID, null);
|
||||||
|
|
||||||
Toaster.success("Success", 'Unsubscribed from channel');
|
Toaster.success("Success", 'Unsubscribed from channel');
|
||||||
|
} on APIException catch (exc, trace) {
|
||||||
|
if (!exc.toastShown) Toaster.error("Error", 'Failed to unsubscribe from channel');
|
||||||
|
ApplicationLog.error('Failed to unsubscribe from channel: ' + exc.toString(), trace: trace);
|
||||||
} catch (exc, trace) {
|
} catch (exc, trace) {
|
||||||
Toaster.error("Error", 'Failed to unsubscribe from channel');
|
Toaster.error("Error", 'Failed to unsubscribe from channel');
|
||||||
ApplicationLog.error('Failed to unsubscribe from channel: ' + exc.toString(), trace: trace);
|
ApplicationLog.error('Failed to unsubscribe from channel: ' + exc.toString(), trace: trace);
|
||||||
@@ -256,6 +263,9 @@ class _ChannelListItemState extends State<ChannelListItem> {
|
|||||||
widget.onSubscriptionChanged.call(sub.channelID, newSub);
|
widget.onSubscriptionChanged.call(sub.channelID, newSub);
|
||||||
|
|
||||||
Toaster.success("Success", 'Unsubscribed from channel');
|
Toaster.success("Success", 'Unsubscribed from channel');
|
||||||
|
} on APIException catch (exc, trace) {
|
||||||
|
if (!exc.toastShown) Toaster.error("Error", 'Failed to unsubscribe from channel');
|
||||||
|
ApplicationLog.error('Failed to unsubscribe from channel: ' + exc.toString(), trace: trace);
|
||||||
} catch (exc, trace) {
|
} catch (exc, trace) {
|
||||||
Toaster.error("Error", 'Failed to unsubscribe from channel');
|
Toaster.error("Error", 'Failed to unsubscribe from channel');
|
||||||
ApplicationLog.error('Failed to unsubscribe from channel: ' + exc.toString(), trace: trace);
|
ApplicationLog.error('Failed to unsubscribe from channel: ' + exc.toString(), trace: trace);
|
||||||
@@ -274,6 +284,9 @@ class _ChannelListItemState extends State<ChannelListItem> {
|
|||||||
widget.onSubscriptionChanged.call(sub.channelID, newSub);
|
widget.onSubscriptionChanged.call(sub.channelID, newSub);
|
||||||
|
|
||||||
Toaster.success("Success", 'Subscribed to channel');
|
Toaster.success("Success", 'Subscribed to channel');
|
||||||
|
} on APIException catch (exc, trace) {
|
||||||
|
if (!exc.toastShown) Toaster.error("Error", 'Failed to subscribe to channel');
|
||||||
|
ApplicationLog.error('Failed to subscribe to channel: ' + exc.toString(), trace: trace);
|
||||||
} catch (exc, trace) {
|
} catch (exc, trace) {
|
||||||
Toaster.error("Error", 'Failed to subscribe to channel');
|
Toaster.error("Error", 'Failed to subscribe to channel');
|
||||||
ApplicationLog.error('Failed to subscribe to channel: ' + exc.toString(), trace: trace);
|
ApplicationLog.error('Failed to subscribe to channel: ' + exc.toString(), trace: trace);
|
||||||
|
|||||||
@@ -3,11 +3,13 @@ import 'dart:convert';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
import 'package:mobile_scanner/mobile_scanner.dart';
|
import 'package:mobile_scanner/mobile_scanner.dart';
|
||||||
|
import 'package:simplecloudnotifier/components/badge_display/badge_display.dart';
|
||||||
import 'package:simplecloudnotifier/components/layout/scaffold.dart';
|
import 'package:simplecloudnotifier/components/layout/scaffold.dart';
|
||||||
import 'package:simplecloudnotifier/models/scan_result.dart';
|
import 'package:simplecloudnotifier/models/scan_result.dart';
|
||||||
import 'package:simplecloudnotifier/pages/channel_scanner/channel_scanner_result_channelsubscribe.dart';
|
import 'package:simplecloudnotifier/pages/channel_scanner/channel_scanner_result_channelsubscribe.dart';
|
||||||
import 'package:simplecloudnotifier/pages/channel_scanner/channel_scanner_result_channelview.dart';
|
import 'package:simplecloudnotifier/pages/channel_scanner/channel_scanner_result_channelview.dart';
|
||||||
import 'package:simplecloudnotifier/pages/channel_scanner/channel_scanner_result_messagesend.dart';
|
import 'package:simplecloudnotifier/pages/channel_scanner/channel_scanner_result_messagesend.dart';
|
||||||
|
import 'package:simplecloudnotifier/state/app_settings.dart';
|
||||||
import 'package:simplecloudnotifier/utils/ui.dart';
|
import 'package:simplecloudnotifier/utils/ui.dart';
|
||||||
|
|
||||||
class ChannelScannerPage extends StatefulWidget {
|
class ChannelScannerPage extends StatefulWidget {
|
||||||
@@ -40,6 +42,16 @@ class _ChannelScannerPageState extends State<ChannelScannerPage> {
|
|||||||
padding: const EdgeInsets.fromLTRB(24, 16, 24, 16),
|
padding: const EdgeInsets.fromLTRB(24, 16, 24, 16),
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
|
SizedBox(height: 16),
|
||||||
|
BadgeDisplay(
|
||||||
|
text: "Scan the QR Code of an account to send messages to this account,\nor the QR Code of an channel to request a subscription to this channel.",
|
||||||
|
icon: null,
|
||||||
|
mode: BadgeMode.info,
|
||||||
|
textAlign: TextAlign.left,
|
||||||
|
closable: true,
|
||||||
|
extraPadding: EdgeInsets.fromLTRB(0, 0, 0, 16),
|
||||||
|
hidden: !AppSettings().showInfoAlerts,
|
||||||
|
),
|
||||||
SizedBox(height: 16),
|
SizedBox(height: 16),
|
||||||
if (scanResult == null) ...[
|
if (scanResult == null) ...[
|
||||||
Center(
|
Center(
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
|||||||
import 'package:qr_flutter/qr_flutter.dart';
|
import 'package:qr_flutter/qr_flutter.dart';
|
||||||
import 'package:share_plus/share_plus.dart';
|
import 'package:share_plus/share_plus.dart';
|
||||||
import 'package:simplecloudnotifier/api/api_client.dart';
|
import 'package:simplecloudnotifier/api/api_client.dart';
|
||||||
|
import 'package:simplecloudnotifier/api/api_exception.dart';
|
||||||
import 'package:simplecloudnotifier/components/error_display/error_display.dart';
|
import 'package:simplecloudnotifier/components/error_display/error_display.dart';
|
||||||
import 'package:simplecloudnotifier/components/layout/scaffold.dart';
|
import 'package:simplecloudnotifier/components/layout/scaffold.dart';
|
||||||
import 'package:simplecloudnotifier/models/channel.dart';
|
import 'package:simplecloudnotifier/models/channel.dart';
|
||||||
@@ -14,6 +15,7 @@ import 'package:simplecloudnotifier/pages/filtered_message_view/filtered_message
|
|||||||
import 'package:simplecloudnotifier/pages/subscription_view/subscription_view.dart';
|
import 'package:simplecloudnotifier/pages/subscription_view/subscription_view.dart';
|
||||||
import 'package:simplecloudnotifier/state/app_auth.dart';
|
import 'package:simplecloudnotifier/state/app_auth.dart';
|
||||||
import 'package:simplecloudnotifier/state/app_bar_state.dart';
|
import 'package:simplecloudnotifier/state/app_bar_state.dart';
|
||||||
|
import 'package:simplecloudnotifier/state/app_settings.dart';
|
||||||
import 'package:simplecloudnotifier/state/application_log.dart';
|
import 'package:simplecloudnotifier/state/application_log.dart';
|
||||||
import 'package:simplecloudnotifier/types/immediate_future.dart';
|
import 'package:simplecloudnotifier/types/immediate_future.dart';
|
||||||
import 'package:simplecloudnotifier/utils/dialogs.dart';
|
import 'package:simplecloudnotifier/utils/dialogs.dart';
|
||||||
@@ -181,12 +183,14 @@ class _ChannelViewPageState extends State<ChannelViewPage> {
|
|||||||
children: [
|
children: [
|
||||||
_buildQRCode(context),
|
_buildQRCode(context),
|
||||||
SizedBox(height: 8),
|
SizedBox(height: 8),
|
||||||
|
if (AppSettings().showExtendedAttributes)
|
||||||
UI.metaCard(
|
UI.metaCard(
|
||||||
context: context,
|
context: context,
|
||||||
icon: FontAwesomeIcons.solidIdCardClip,
|
icon: FontAwesomeIcons.solidIdCardClip,
|
||||||
title: 'ChannelID',
|
title: 'ChannelID',
|
||||||
values: [channel.channelID],
|
values: [channel.channelID],
|
||||||
),
|
),
|
||||||
|
if (AppSettings().showExtendedAttributes)
|
||||||
UI.metaCard(
|
UI.metaCard(
|
||||||
context: context,
|
context: context,
|
||||||
icon: FontAwesomeIcons.solidInputNumeric,
|
icon: FontAwesomeIcons.solidInputNumeric,
|
||||||
@@ -283,12 +287,14 @@ class _ChannelViewPageState extends State<ChannelViewPage> {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: [
|
children: [
|
||||||
SizedBox(height: 8),
|
SizedBox(height: 8),
|
||||||
|
if (AppSettings().showExtendedAttributes)
|
||||||
UI.metaCard(
|
UI.metaCard(
|
||||||
context: context,
|
context: context,
|
||||||
icon: FontAwesomeIcons.solidIdCardClip,
|
icon: FontAwesomeIcons.solidIdCardClip,
|
||||||
title: 'ChannelID',
|
title: 'ChannelID',
|
||||||
values: [channel.channelID],
|
values: [channel.channelID],
|
||||||
),
|
),
|
||||||
|
if (AppSettings().showExtendedAttributes)
|
||||||
UI.metaCard(
|
UI.metaCard(
|
||||||
context: context,
|
context: context,
|
||||||
icon: FontAwesomeIcons.solidInputNumeric,
|
icon: FontAwesomeIcons.solidInputNumeric,
|
||||||
@@ -305,7 +311,7 @@ class _ChannelViewPageState extends State<ChannelViewPage> {
|
|||||||
icon: FontAwesomeIcons.solidEnvelope,
|
icon: FontAwesomeIcons.solidEnvelope,
|
||||||
title: 'Messages',
|
title: 'Messages',
|
||||||
values: [channel.messagesSent.toString()],
|
values: [channel.messagesSent.toString()],
|
||||||
mainAction: (subscription != null && subscription!.confirmed) ? () => Navi.push(context, () => FilteredMessageViewPage(title: channel.displayName, filter: MessageFilter(channelIDs: [channel.channelID]))) : null,
|
mainAction: (subscription != null && subscription!.confirmed) ? () => Navi.push(context, () => FilteredMessageViewPage(title: channel.displayName, alertText: null, filter: MessageFilter(channelIDs: [channel.channelID]))) : null,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -344,12 +350,20 @@ class _ChannelViewPageState extends State<ChannelViewPage> {
|
|||||||
future: _futureOwner.future,
|
future: _futureOwner.future,
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
if (snapshot.hasData) {
|
if (snapshot.hasData) {
|
||||||
|
if (AppSettings().showExtendedAttributes)
|
||||||
return UI.metaCard(
|
return UI.metaCard(
|
||||||
context: context,
|
context: context,
|
||||||
icon: FontAwesomeIcons.solidUser,
|
icon: FontAwesomeIcons.solidUser,
|
||||||
title: 'Owner',
|
title: 'Owner',
|
||||||
values: [channelPreview!.ownerUserID + (isOwned ? ' (you)' : ''), if (snapshot.data?.username != null) snapshot.data!.username!],
|
values: [channelPreview!.ownerUserID + (isOwned ? ' (you)' : ''), if (snapshot.data?.username != null) snapshot.data!.username!],
|
||||||
);
|
);
|
||||||
|
else
|
||||||
|
return UI.metaCard(
|
||||||
|
context: context,
|
||||||
|
icon: FontAwesomeIcons.solidUser,
|
||||||
|
title: 'Owner',
|
||||||
|
values: [(snapshot.data?.username ?? channelPreview!.ownerUserID) + (isOwned ? ' (you)' : '')],
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
return UI.metaCard(
|
return UI.metaCard(
|
||||||
context: context,
|
context: context,
|
||||||
@@ -537,6 +551,9 @@ class _ChannelViewPageState extends State<ChannelViewPage> {
|
|||||||
});
|
});
|
||||||
|
|
||||||
widget.needsReload?.call();
|
widget.needsReload?.call();
|
||||||
|
} on APIException catch (exc, trace) {
|
||||||
|
ApplicationLog.error('Failed to save DisplayName: ' + exc.toString(), trace: trace);
|
||||||
|
if (!exc.toastShown) Toaster.error("Error", 'Failed to save DisplayName');
|
||||||
} catch (exc, trace) {
|
} catch (exc, trace) {
|
||||||
ApplicationLog.error('Failed to save DisplayName: ' + exc.toString(), trace: trace);
|
ApplicationLog.error('Failed to save DisplayName: ' + exc.toString(), trace: trace);
|
||||||
Toaster.error("Error", 'Failed to save DisplayName');
|
Toaster.error("Error", 'Failed to save DisplayName');
|
||||||
@@ -569,9 +586,12 @@ class _ChannelViewPageState extends State<ChannelViewPage> {
|
|||||||
});
|
});
|
||||||
|
|
||||||
widget.needsReload?.call();
|
widget.needsReload?.call();
|
||||||
|
} on APIException catch (exc, trace) {
|
||||||
|
ApplicationLog.error('Failed to save DescriptionName: ' + exc.toString(), trace: trace);
|
||||||
|
if (!exc.toastShown) Toaster.error("Error", 'Failed to save description');
|
||||||
} catch (exc, trace) {
|
} catch (exc, trace) {
|
||||||
ApplicationLog.error('Failed to save DescriptionName: ' + exc.toString(), trace: trace);
|
ApplicationLog.error('Failed to save DescriptionName: ' + exc.toString(), trace: trace);
|
||||||
Toaster.error("Error", 'Failed to save DescriptionName');
|
Toaster.error("Error", 'Failed to save description');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -589,6 +609,9 @@ class _ChannelViewPageState extends State<ChannelViewPage> {
|
|||||||
} else {
|
} else {
|
||||||
Toaster.success("Success", 'Requested subscription to channel');
|
Toaster.success("Success", 'Requested subscription to channel');
|
||||||
}
|
}
|
||||||
|
} on APIException catch (exc, trace) {
|
||||||
|
if (!exc.toastShown) Toaster.error("Error", 'Failed to subscribe to channel');
|
||||||
|
ApplicationLog.error('Failed to subscribe to channel: ' + exc.toString(), trace: trace);
|
||||||
} catch (exc, trace) {
|
} catch (exc, trace) {
|
||||||
Toaster.error("Error", 'Failed to subscribe to channel');
|
Toaster.error("Error", 'Failed to subscribe to channel');
|
||||||
ApplicationLog.error('Failed to subscribe to channel: ' + exc.toString(), trace: trace);
|
ApplicationLog.error('Failed to subscribe to channel: ' + exc.toString(), trace: trace);
|
||||||
@@ -612,6 +635,9 @@ class _ChannelViewPageState extends State<ChannelViewPage> {
|
|||||||
await _initStateAsync(false);
|
await _initStateAsync(false);
|
||||||
|
|
||||||
Toaster.success("Success", 'Unsubscribed from channel');
|
Toaster.success("Success", 'Unsubscribed from channel');
|
||||||
|
} on APIException catch (exc, trace) {
|
||||||
|
if (!exc.toastShown) Toaster.error("Error", 'Failed to unsubscribe from channel');
|
||||||
|
ApplicationLog.error('Failed to unsubscribe from channel: ' + exc.toString(), trace: trace);
|
||||||
} catch (exc, trace) {
|
} catch (exc, trace) {
|
||||||
Toaster.error("Error", 'Failed to unsubscribe from channel');
|
Toaster.error("Error", 'Failed to unsubscribe from channel');
|
||||||
ApplicationLog.error('Failed to unsubscribe from channel: ' + exc.toString(), trace: trace);
|
ApplicationLog.error('Failed to unsubscribe from channel: ' + exc.toString(), trace: trace);
|
||||||
@@ -630,6 +656,9 @@ class _ChannelViewPageState extends State<ChannelViewPage> {
|
|||||||
await _initStateAsync(false);
|
await _initStateAsync(false);
|
||||||
|
|
||||||
Toaster.success("Success", 'Unsubscribed from channel');
|
Toaster.success("Success", 'Unsubscribed from channel');
|
||||||
|
} on APIException catch (exc, trace) {
|
||||||
|
if (!exc.toastShown) Toaster.error("Error", 'Failed to unsubscribe from channel');
|
||||||
|
ApplicationLog.error('Failed to unsubscribe from channel: ' + exc.toString(), trace: trace);
|
||||||
} catch (exc, trace) {
|
} catch (exc, trace) {
|
||||||
Toaster.error("Error", 'Failed to unsubscribe from channel');
|
Toaster.error("Error", 'Failed to unsubscribe from channel');
|
||||||
ApplicationLog.error('Failed to unsubscribe from channel: ' + exc.toString(), trace: trace);
|
ApplicationLog.error('Failed to unsubscribe from channel: ' + exc.toString(), trace: trace);
|
||||||
@@ -648,6 +677,9 @@ class _ChannelViewPageState extends State<ChannelViewPage> {
|
|||||||
await _initStateAsync(false);
|
await _initStateAsync(false);
|
||||||
|
|
||||||
Toaster.success("Success", 'Subscribed to channel');
|
Toaster.success("Success", 'Subscribed to channel');
|
||||||
|
} on APIException catch (exc, trace) {
|
||||||
|
if (!exc.toastShown) Toaster.error("Error", 'Failed to subscribe to channel');
|
||||||
|
ApplicationLog.error('Failed to subscribe to channel: ' + exc.toString(), trace: trace);
|
||||||
} catch (exc, trace) {
|
} catch (exc, trace) {
|
||||||
Toaster.error("Error", 'Failed to subscribe to channel');
|
Toaster.error("Error", 'Failed to subscribe to channel');
|
||||||
ApplicationLog.error('Failed to subscribe to channel: ' + exc.toString(), trace: trace);
|
ApplicationLog.error('Failed to subscribe to channel: ' + exc.toString(), trace: trace);
|
||||||
@@ -664,6 +696,9 @@ class _ChannelViewPageState extends State<ChannelViewPage> {
|
|||||||
await _initStateAsync(false);
|
await _initStateAsync(false);
|
||||||
|
|
||||||
Toaster.success("Success", 'Subscription succesfully revoked');
|
Toaster.success("Success", 'Subscription succesfully revoked');
|
||||||
|
} on APIException catch (exc, trace) {
|
||||||
|
if (!exc.toastShown) Toaster.error("Error", 'Failed to revoke subscription');
|
||||||
|
ApplicationLog.error('Failed to revoke subscription: ' + exc.toString(), trace: trace);
|
||||||
} catch (exc, trace) {
|
} catch (exc, trace) {
|
||||||
Toaster.error("Error", 'Failed to revoke subscription');
|
Toaster.error("Error", 'Failed to revoke subscription');
|
||||||
ApplicationLog.error('Failed to revoke subscription: ' + exc.toString(), trace: trace);
|
ApplicationLog.error('Failed to revoke subscription: ' + exc.toString(), trace: trace);
|
||||||
@@ -680,6 +715,9 @@ class _ChannelViewPageState extends State<ChannelViewPage> {
|
|||||||
await _initStateAsync(false);
|
await _initStateAsync(false);
|
||||||
|
|
||||||
Toaster.success("Success", 'Subscription succesfully confirmed');
|
Toaster.success("Success", 'Subscription succesfully confirmed');
|
||||||
|
} on APIException catch (exc, trace) {
|
||||||
|
if (!exc.toastShown) Toaster.error("Error", 'Failed to confirm subscription');
|
||||||
|
ApplicationLog.error('Failed to confirm subscription: ' + exc.toString(), trace: trace);
|
||||||
} catch (exc, trace) {
|
} catch (exc, trace) {
|
||||||
Toaster.error("Error", 'Failed to confirm subscription');
|
Toaster.error("Error", 'Failed to confirm subscription');
|
||||||
ApplicationLog.error('Failed to confirm subscription: ' + exc.toString(), trace: trace);
|
ApplicationLog.error('Failed to confirm subscription: ' + exc.toString(), trace: trace);
|
||||||
@@ -696,6 +734,9 @@ class _ChannelViewPageState extends State<ChannelViewPage> {
|
|||||||
await _initStateAsync(false);
|
await _initStateAsync(false);
|
||||||
|
|
||||||
Toaster.success("Success", 'Subscription request succesfully denied');
|
Toaster.success("Success", 'Subscription request succesfully denied');
|
||||||
|
} on APIException catch (exc, trace) {
|
||||||
|
if (!exc.toastShown) Toaster.error("Error", 'Failed to deny subscription');
|
||||||
|
ApplicationLog.error('Failed to deny subscription: ' + exc.toString(), trace: trace);
|
||||||
} catch (exc, trace) {
|
} catch (exc, trace) {
|
||||||
Toaster.error("Error", 'Failed to deny subscription');
|
Toaster.error("Error", 'Failed to deny subscription');
|
||||||
ApplicationLog.error('Failed to deny subscription: ' + exc.toString(), trace: trace);
|
ApplicationLog.error('Failed to deny subscription: ' + exc.toString(), trace: trace);
|
||||||
|
|||||||
@@ -2,8 +2,10 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
|
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:simplecloudnotifier/api/api_client.dart';
|
import 'package:simplecloudnotifier/api/api_client.dart';
|
||||||
|
import 'package:simplecloudnotifier/components/badge_display/badge_display.dart';
|
||||||
import 'package:simplecloudnotifier/components/layout/scaffold.dart';
|
import 'package:simplecloudnotifier/components/layout/scaffold.dart';
|
||||||
import 'package:simplecloudnotifier/models/client.dart';
|
import 'package:simplecloudnotifier/models/client.dart';
|
||||||
|
import 'package:simplecloudnotifier/state/app_settings.dart';
|
||||||
import 'package:simplecloudnotifier/state/application_log.dart';
|
import 'package:simplecloudnotifier/state/application_log.dart';
|
||||||
import 'package:simplecloudnotifier/state/app_auth.dart';
|
import 'package:simplecloudnotifier/state/app_auth.dart';
|
||||||
import 'package:simplecloudnotifier/pages/client_list/client_list_item.dart';
|
import 'package:simplecloudnotifier/pages/client_list/client_list_item.dart';
|
||||||
@@ -69,7 +71,28 @@ class _ClientListPageState extends State<ClientListPage> {
|
|||||||
showShare: false,
|
showShare: false,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: EdgeInsets.fromLTRB(8, 4, 8, 4),
|
padding: EdgeInsets.fromLTRB(8, 4, 8, 4),
|
||||||
child: RefreshIndicator(
|
child: Column(
|
||||||
|
children: [
|
||||||
|
BadgeDisplay(
|
||||||
|
text: "All clients connected with this account",
|
||||||
|
icon: null,
|
||||||
|
mode: BadgeMode.info,
|
||||||
|
textAlign: TextAlign.left,
|
||||||
|
closable: true,
|
||||||
|
extraPadding: EdgeInsets.fromLTRB(0, 0, 0, 16),
|
||||||
|
hidden: !AppSettings().showInfoAlerts,
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: _buildList(context),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildList(BuildContext context) {
|
||||||
|
return RefreshIndicator(
|
||||||
onRefresh: () => Future.sync(
|
onRefresh: () => Future.sync(
|
||||||
() => _pagingController.refresh(),
|
() => _pagingController.refresh(),
|
||||||
),
|
),
|
||||||
@@ -79,8 +102,6 @@ class _ClientListPageState extends State<ClientListPage> {
|
|||||||
itemBuilder: (context, item, index) => ClientListItem(item: item),
|
itemBuilder: (context, item, index) => ClientListItem(item: item),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
|
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
|
||||||
import 'package:simplecloudnotifier/api/api_client.dart';
|
import 'package:simplecloudnotifier/api/api_client.dart';
|
||||||
|
import 'package:simplecloudnotifier/components/badge_display/badge_display.dart';
|
||||||
import 'package:simplecloudnotifier/components/layout/scaffold.dart';
|
import 'package:simplecloudnotifier/components/layout/scaffold.dart';
|
||||||
import 'package:simplecloudnotifier/models/channel.dart';
|
import 'package:simplecloudnotifier/models/channel.dart';
|
||||||
import 'package:simplecloudnotifier/models/scn_message.dart';
|
import 'package:simplecloudnotifier/models/scn_message.dart';
|
||||||
@@ -17,11 +18,13 @@ class FilteredMessageViewPage extends StatefulWidget {
|
|||||||
const FilteredMessageViewPage({
|
const FilteredMessageViewPage({
|
||||||
required this.title,
|
required this.title,
|
||||||
required this.filter,
|
required this.filter,
|
||||||
|
required this.alertText,
|
||||||
super.key,
|
super.key,
|
||||||
});
|
});
|
||||||
|
|
||||||
final String title;
|
final String title;
|
||||||
final MessageFilter filter;
|
final MessageFilter filter;
|
||||||
|
final String? alertText;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<FilteredMessageViewPage> createState() => _FilteredMessageViewPageState();
|
State<FilteredMessageViewPage> createState() => _FilteredMessageViewPageState();
|
||||||
@@ -87,18 +90,40 @@ class _FilteredMessageViewPageState extends State<FilteredMessageViewPage> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
Widget child = _buildMessageList(context);
|
||||||
|
|
||||||
|
if (widget.alertText != null) {
|
||||||
|
child = Column(
|
||||||
|
children: [
|
||||||
|
BadgeDisplay(
|
||||||
|
text: widget.alertText!,
|
||||||
|
icon: null,
|
||||||
|
mode: BadgeMode.info,
|
||||||
|
textAlign: TextAlign.left,
|
||||||
|
closable: true,
|
||||||
|
extraPadding: EdgeInsets.fromLTRB(0, 0, 0, 16),
|
||||||
|
hidden: !AppSettings().showInfoAlerts,
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: child,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return SCNScaffold(
|
return SCNScaffold(
|
||||||
title: this.widget.title,
|
title: this.widget.title,
|
||||||
showSearch: false,
|
showSearch: false,
|
||||||
showShare: false,
|
showShare: false,
|
||||||
child: _buildMessageList(context),
|
child: Padding(
|
||||||
|
padding: EdgeInsets.fromLTRB(8, 4, 8, 4),
|
||||||
|
child: child,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildMessageList(BuildContext context) {
|
Widget _buildMessageList(BuildContext context) {
|
||||||
return Padding(
|
return RefreshIndicator(
|
||||||
padding: EdgeInsets.fromLTRB(8, 4, 8, 4),
|
|
||||||
child: RefreshIndicator(
|
|
||||||
onRefresh: () => Future.sync(
|
onRefresh: () => Future.sync(
|
||||||
() => _pagingController.refresh(),
|
() => _pagingController.refresh(),
|
||||||
),
|
),
|
||||||
@@ -114,7 +139,6 @@ class _FilteredMessageViewPageState extends State<FilteredMessageViewPage> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ class _KeyTokenCreateDialogState extends State<KeyTokenCreateDialog> {
|
|||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
title: const Text('Create new key'),
|
title: const Text('Create new key'),
|
||||||
content: Container(
|
content: Container(
|
||||||
width: 0,
|
width: 9000,
|
||||||
height: 400,
|
height: 400,
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
child: Column(
|
child: Column(
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ import 'package:flutter/services.dart';
|
|||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
import 'package:simplecloudnotifier/components/badge_display/badge_display.dart';
|
import 'package:simplecloudnotifier/components/badge_display/badge_display.dart';
|
||||||
import 'package:simplecloudnotifier/models/keytoken.dart';
|
import 'package:simplecloudnotifier/models/keytoken.dart';
|
||||||
|
import 'package:simplecloudnotifier/state/app_auth.dart';
|
||||||
|
import 'package:simplecloudnotifier/state/app_settings.dart';
|
||||||
import 'package:simplecloudnotifier/utils/toaster.dart';
|
import 'package:simplecloudnotifier/utils/toaster.dart';
|
||||||
import 'package:simplecloudnotifier/utils/ui.dart';
|
import 'package:simplecloudnotifier/utils/ui.dart';
|
||||||
|
|
||||||
@@ -18,15 +20,32 @@ class KeyTokenCreatedModal extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
final acc = AppAuth();
|
||||||
|
|
||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
title: const Text('A new key was created'),
|
title: const Text('A new key was created'),
|
||||||
content: Container(
|
content: Container(
|
||||||
width: 0,
|
width: 9000,
|
||||||
height: 350,
|
height: 350,
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: [
|
children: [
|
||||||
|
const BadgeDisplay(
|
||||||
|
text: "Please copy and save the token now, it cannot be retrieved later.",
|
||||||
|
icon: null,
|
||||||
|
mode: BadgeMode.warn,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
if (acc.userID != null)
|
||||||
|
UI.metaCard(
|
||||||
|
context: context,
|
||||||
|
icon: FontAwesomeIcons.solidIdCardClip,
|
||||||
|
title: 'UserID',
|
||||||
|
values: [acc.userID!],
|
||||||
|
iconActions: [(FontAwesomeIcons.copy, null, () => _copy(acc.userID!))],
|
||||||
|
),
|
||||||
|
if (AppSettings().showExtendedAttributes)
|
||||||
UI.metaCard(
|
UI.metaCard(
|
||||||
context: context,
|
context: context,
|
||||||
icon: FontAwesomeIcons.solidIdCardClip,
|
icon: FontAwesomeIcons.solidIdCardClip,
|
||||||
@@ -45,19 +64,12 @@ class KeyTokenCreatedModal extends StatelessWidget {
|
|||||||
title: 'Permissions',
|
title: 'Permissions',
|
||||||
values: _formatPermissions(keytoken.permissions),
|
values: _formatPermissions(keytoken.permissions),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 16),
|
|
||||||
const BadgeDisplay(
|
|
||||||
text: "Please copy and save the token now, it cannot be retrieved later.",
|
|
||||||
icon: null,
|
|
||||||
mode: BadgeMode.warn,
|
|
||||||
),
|
|
||||||
const SizedBox(height: 4),
|
|
||||||
UI.metaCard(
|
UI.metaCard(
|
||||||
context: context,
|
context: context,
|
||||||
icon: FontAwesomeIcons.solidKey,
|
icon: FontAwesomeIcons.solidKey,
|
||||||
title: 'Token',
|
title: 'Token',
|
||||||
values: [tokenValue.substring(0, 12) + '...'],
|
values: [tokenValue],
|
||||||
iconActions: [(FontAwesomeIcons.copy, null, _copy)],
|
iconActions: [(FontAwesomeIcons.copy, null, () => _copy(tokenValue))],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -89,9 +101,9 @@ class KeyTokenCreatedModal extends StatelessWidget {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _copy() {
|
void _copy(String v) {
|
||||||
Clipboard.setData(new ClipboardData(text: tokenValue));
|
Clipboard.setData(new ClipboardData(text: v));
|
||||||
Toaster.info("Clipboard", 'Copied text to Clipboard');
|
Toaster.info("Clipboard", 'Copied text to Clipboard');
|
||||||
print('================= [CLIPBOARD] =================\n${tokenValue}\n================= [/CLIPBOARD] =================');
|
print('================= [CLIPBOARD] =================\n${v}\n================= [/CLIPBOARD] =================');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,10 +3,12 @@ import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
|||||||
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
|
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:simplecloudnotifier/api/api_client.dart';
|
import 'package:simplecloudnotifier/api/api_client.dart';
|
||||||
|
import 'package:simplecloudnotifier/components/badge_display/badge_display.dart';
|
||||||
import 'package:simplecloudnotifier/components/layout/scaffold.dart';
|
import 'package:simplecloudnotifier/components/layout/scaffold.dart';
|
||||||
import 'package:simplecloudnotifier/models/keytoken.dart';
|
import 'package:simplecloudnotifier/models/keytoken.dart';
|
||||||
import 'package:simplecloudnotifier/pages/keytoken_list/keytoken_create_modal.dart';
|
import 'package:simplecloudnotifier/pages/keytoken_list/keytoken_create_modal.dart';
|
||||||
import 'package:simplecloudnotifier/pages/keytoken_list/keytoken_created_modal.dart';
|
import 'package:simplecloudnotifier/pages/keytoken_list/keytoken_created_modal.dart';
|
||||||
|
import 'package:simplecloudnotifier/state/app_settings.dart';
|
||||||
import 'package:simplecloudnotifier/state/application_log.dart';
|
import 'package:simplecloudnotifier/state/application_log.dart';
|
||||||
import 'package:simplecloudnotifier/state/app_auth.dart';
|
import 'package:simplecloudnotifier/state/app_auth.dart';
|
||||||
import 'package:simplecloudnotifier/pages/keytoken_list/keytoken_list_item.dart';
|
import 'package:simplecloudnotifier/pages/keytoken_list/keytoken_list_item.dart';
|
||||||
@@ -72,16 +74,21 @@ class _KeyTokenListPageState extends State<KeyTokenListPage> {
|
|||||||
showShare: false,
|
showShare: false,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: EdgeInsets.fromLTRB(8, 4, 8, 4),
|
padding: EdgeInsets.fromLTRB(8, 4, 8, 4),
|
||||||
child: RefreshIndicator(
|
child: Column(
|
||||||
onRefresh: () => Future.sync(
|
children: [
|
||||||
() => _pagingController.refresh(),
|
BadgeDisplay(
|
||||||
),
|
text: "These are your keys.\nKeys can be used to send messages and access your account.\n\nKeys can have different sets of permissions, the Admin-Key has full-access to your account",
|
||||||
child: PagedListView<int, KeyToken>(
|
icon: null,
|
||||||
pagingController: _pagingController,
|
mode: BadgeMode.info,
|
||||||
builderDelegate: PagedChildBuilderDelegate<KeyToken>(
|
textAlign: TextAlign.left,
|
||||||
itemBuilder: (context, item, index) => KeyTokenListItem(item: item, needsReload: _fullRefresh),
|
closable: true,
|
||||||
),
|
extraPadding: EdgeInsets.fromLTRB(0, 0, 0, 16),
|
||||||
|
hidden: !AppSettings().showInfoAlerts,
|
||||||
),
|
),
|
||||||
|
Expanded(
|
||||||
|
child: _buildList(context),
|
||||||
|
)
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
floatingActionButton: FloatingActionButton(
|
floatingActionButton: FloatingActionButton(
|
||||||
@@ -97,6 +104,20 @@ class _KeyTokenListPageState extends State<KeyTokenListPage> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget _buildList(BuildContext context) {
|
||||||
|
return RefreshIndicator(
|
||||||
|
onRefresh: () => Future.sync(
|
||||||
|
() => _pagingController.refresh(),
|
||||||
|
),
|
||||||
|
child: PagedListView<int, KeyToken>(
|
||||||
|
pagingController: _pagingController,
|
||||||
|
builderDelegate: PagedChildBuilderDelegate<KeyToken>(
|
||||||
|
itemBuilder: (context, item, index) => KeyTokenListItem(item: item, needsReload: _fullRefresh),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
void _created(KeyToken token, String tokValue) {
|
void _created(KeyToken token, String tokValue) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_pagingController.itemList?.insert(0, token);
|
_pagingController.itemList?.insert(0, token);
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ class KeyTokenListItem extends StatelessWidget {
|
|||||||
SizedBox(width: 4),
|
SizedBox(width: 4),
|
||||||
GestureDetector(
|
GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
Navi.push(context, () => FilteredMessageViewPage(title: item.name, filter: MessageFilter(usedKeys: [item.keytokenID])));
|
Navi.push(context, () => FilteredMessageViewPage(title: item.name, alertText: 'All message sent with the key \'${item.name}\'', filter: MessageFilter(usedKeys: [item.keytokenID])));
|
||||||
},
|
},
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(8),
|
padding: const EdgeInsets.all(8),
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ class _EditKeyTokenChannelsDialogState extends State<EditKeyTokenChannelsDialog>
|
|||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
title: const Text('Channels'),
|
title: const Text('Channels'),
|
||||||
content: Container(
|
content: Container(
|
||||||
width: 0,
|
width: 9000,
|
||||||
height: 400,
|
height: 400,
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ class _EditKeyTokenPermissionsDialogState extends State<EditKeyTokenPermissionsD
|
|||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
title: const Text('Permissions'),
|
title: const Text('Permissions'),
|
||||||
content: Container(
|
content: Container(
|
||||||
width: 0,
|
width: 9000,
|
||||||
height: 400,
|
height: 400,
|
||||||
child: ListView.builder(
|
child: ListView.builder(
|
||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
import 'package:simplecloudnotifier/api/api_client.dart';
|
import 'package:simplecloudnotifier/api/api_client.dart';
|
||||||
|
import 'package:simplecloudnotifier/api/api_exception.dart';
|
||||||
import 'package:simplecloudnotifier/components/error_display/error_display.dart';
|
import 'package:simplecloudnotifier/components/error_display/error_display.dart';
|
||||||
import 'package:simplecloudnotifier/components/layout/scaffold.dart';
|
import 'package:simplecloudnotifier/components/layout/scaffold.dart';
|
||||||
import 'package:simplecloudnotifier/models/channel.dart';
|
import 'package:simplecloudnotifier/models/channel.dart';
|
||||||
@@ -200,6 +201,7 @@ class _KeyTokenViewPageState extends State<KeyTokenViewPage> {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: [
|
children: [
|
||||||
SizedBox(height: 8),
|
SizedBox(height: 8),
|
||||||
|
if (AppSettings().showExtendedAttributes)
|
||||||
UI.metaCard(
|
UI.metaCard(
|
||||||
context: context,
|
context: context,
|
||||||
icon: FontAwesomeIcons.solidIdCardClip,
|
icon: FontAwesomeIcons.solidIdCardClip,
|
||||||
@@ -230,7 +232,7 @@ class _KeyTokenViewPageState extends State<KeyTokenViewPage> {
|
|||||||
title: 'Messages',
|
title: 'Messages',
|
||||||
values: [keytoken.messagesSent.toString()],
|
values: [keytoken.messagesSent.toString()],
|
||||||
mainAction: () {
|
mainAction: () {
|
||||||
Navi.push(context, () => FilteredMessageViewPage(title: keytoken.name, filter: MessageFilter(usedKeys: [keytoken.keytokenID])));
|
Navi.push(context, () => FilteredMessageViewPage(title: keytoken.name, alertText: 'All message sent with the key \'${keytoken.name}\'', filter: MessageFilter(usedKeys: [keytoken.keytokenID])));
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
..._buildPermissionCard(context, true, keytoken.toPreview()),
|
..._buildPermissionCard(context, true, keytoken.toPreview()),
|
||||||
@@ -249,6 +251,7 @@ class _KeyTokenViewPageState extends State<KeyTokenViewPage> {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: [
|
children: [
|
||||||
SizedBox(height: 8),
|
SizedBox(height: 8),
|
||||||
|
if (AppSettings().showExtendedAttributes)
|
||||||
UI.metaCard(
|
UI.metaCard(
|
||||||
context: context,
|
context: context,
|
||||||
icon: FontAwesomeIcons.solidIdCardClip,
|
icon: FontAwesomeIcons.solidIdCardClip,
|
||||||
@@ -269,12 +272,20 @@ class _KeyTokenViewPageState extends State<KeyTokenViewPage> {
|
|||||||
future: _futureOwner.future,
|
future: _futureOwner.future,
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
if (snapshot.hasData) {
|
if (snapshot.hasData) {
|
||||||
|
if (AppSettings().showExtendedAttributes)
|
||||||
return UI.metaCard(
|
return UI.metaCard(
|
||||||
context: context,
|
context: context,
|
||||||
icon: FontAwesomeIcons.solidUser,
|
icon: FontAwesomeIcons.solidUser,
|
||||||
title: 'Owner',
|
title: 'Owner',
|
||||||
values: [keytokenPreview!.ownerUserID + (isOwned ? ' (you)' : ''), if (snapshot.data?.username != null) snapshot.data!.username!],
|
values: [keytokenPreview!.ownerUserID + (isOwned ? ' (you)' : ''), if (snapshot.data?.username != null) snapshot.data!.username!],
|
||||||
);
|
);
|
||||||
|
else
|
||||||
|
return UI.metaCard(
|
||||||
|
context: context,
|
||||||
|
icon: FontAwesomeIcons.solidUser,
|
||||||
|
title: 'Owner',
|
||||||
|
values: [(snapshot.data?.username ?? keytokenPreview!.ownerUserID) + (isOwned ? ' (you)' : '')],
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
return UI.metaCard(
|
return UI.metaCard(
|
||||||
context: context,
|
context: context,
|
||||||
@@ -543,6 +554,9 @@ class _KeyTokenViewPageState extends State<KeyTokenViewPage> {
|
|||||||
Toaster.info('Logout', 'Successfully deleted the key');
|
Toaster.info('Logout', 'Successfully deleted the key');
|
||||||
|
|
||||||
Navi.pop(context);
|
Navi.pop(context);
|
||||||
|
} on APIException catch (exc, trace) {
|
||||||
|
ApplicationLog.error('Failed to delete key: ' + exc.toString(), trace: trace);
|
||||||
|
if (!exc.toastShown) Toaster.error("Error", 'Failed to delete key');
|
||||||
} catch (exc, trace) {
|
} catch (exc, trace) {
|
||||||
Toaster.error("Error", 'Failed to delete key');
|
Toaster.error("Error", 'Failed to delete key');
|
||||||
ApplicationLog.error('Failed to delete key: ' + exc.toString(), trace: trace);
|
ApplicationLog.error('Failed to delete key: ' + exc.toString(), trace: trace);
|
||||||
@@ -563,6 +577,9 @@ class _KeyTokenViewPageState extends State<KeyTokenViewPage> {
|
|||||||
Toaster.info("Success", "Key updated");
|
Toaster.info("Success", "Key updated");
|
||||||
|
|
||||||
widget.needsReload?.call();
|
widget.needsReload?.call();
|
||||||
|
} on APIException catch (exc, trace) {
|
||||||
|
ApplicationLog.error('Failed to update key: ' + exc.toString(), trace: trace);
|
||||||
|
if (!exc.toastShown) Toaster.error("Error", 'Failed to update key');
|
||||||
} catch (exc, trace) {
|
} catch (exc, trace) {
|
||||||
ApplicationLog.error('Failed to update key: ' + exc.toString(), trace: trace);
|
ApplicationLog.error('Failed to update key: ' + exc.toString(), trace: trace);
|
||||||
Toaster.error("Error", 'Failed to update key');
|
Toaster.error("Error", 'Failed to update key');
|
||||||
@@ -583,6 +600,9 @@ class _KeyTokenViewPageState extends State<KeyTokenViewPage> {
|
|||||||
Toaster.info("Success", "Key updated");
|
Toaster.info("Success", "Key updated");
|
||||||
|
|
||||||
widget.needsReload?.call();
|
widget.needsReload?.call();
|
||||||
|
} on APIException catch (exc, trace) {
|
||||||
|
ApplicationLog.error('Failed to update key: ' + exc.toString(), trace: trace);
|
||||||
|
if (!exc.toastShown) Toaster.error("Error", 'Failed to update key');
|
||||||
} catch (exc, trace) {
|
} catch (exc, trace) {
|
||||||
ApplicationLog.error('Failed to update key: ' + exc.toString(), trace: trace);
|
ApplicationLog.error('Failed to update key: ' + exc.toString(), trace: trace);
|
||||||
Toaster.error("Error", 'Failed to update key');
|
Toaster.error("Error", 'Failed to update key');
|
||||||
@@ -603,6 +623,9 @@ class _KeyTokenViewPageState extends State<KeyTokenViewPage> {
|
|||||||
Toaster.info("Success", "Key updated");
|
Toaster.info("Success", "Key updated");
|
||||||
|
|
||||||
widget.needsReload?.call();
|
widget.needsReload?.call();
|
||||||
|
} on APIException catch (exc, trace) {
|
||||||
|
ApplicationLog.error('Failed to update key: ' + exc.toString(), trace: trace);
|
||||||
|
if (!exc.toastShown) Toaster.error("Error", 'Failed to update key');
|
||||||
} catch (exc, trace) {
|
} catch (exc, trace) {
|
||||||
ApplicationLog.error('Failed to update key: ' + exc.toString(), trace: trace);
|
ApplicationLog.error('Failed to update key: ' + exc.toString(), trace: trace);
|
||||||
Toaster.error("Error", 'Failed to update key');
|
Toaster.error("Error", 'Failed to update key');
|
||||||
|
|||||||
@@ -141,6 +141,8 @@ class _MessageViewPageState extends State<MessageViewPage> {
|
|||||||
Widget _buildMessageView(BuildContext context, SCNMessage message, ChannelPreview? channel, KeyTokenPreview? token, UserPreview? user) {
|
Widget _buildMessageView(BuildContext context, SCNMessage message, ChannelPreview? channel, KeyTokenPreview? token, UserPreview? user) {
|
||||||
final userAccUserID = context.select<AppAuth, String?>((v) => v.userID);
|
final userAccUserID = context.select<AppAuth, String?>((v) => v.userID);
|
||||||
|
|
||||||
|
var cfg = AppSettings();
|
||||||
|
|
||||||
final child = Padding(
|
final child = Padding(
|
||||||
padding: const EdgeInsets.fromLTRB(24, 16, 24, 16),
|
padding: const EdgeInsets.fromLTRB(24, 16, 24, 16),
|
||||||
child: Column(
|
child: Column(
|
||||||
@@ -150,6 +152,13 @@ class _MessageViewPageState extends State<MessageViewPage> {
|
|||||||
SizedBox(height: 8),
|
SizedBox(height: 8),
|
||||||
if (message.content != null) ..._buildMessageContent(context, message),
|
if (message.content != null) ..._buildMessageContent(context, message),
|
||||||
SizedBox(height: 8),
|
SizedBox(height: 8),
|
||||||
|
if (cfg.showExtendedAttributes)
|
||||||
|
UI.metaCard(
|
||||||
|
context: context,
|
||||||
|
icon: FontAwesomeIcons.solidIdCardClip,
|
||||||
|
title: 'MessageID',
|
||||||
|
values: [message.messageID, if (message.userMessageID != null) message.userMessageID!],
|
||||||
|
),
|
||||||
if (message.senderName != null)
|
if (message.senderName != null)
|
||||||
UI.metaCard(
|
UI.metaCard(
|
||||||
context: context,
|
context: context,
|
||||||
@@ -157,9 +166,10 @@ class _MessageViewPageState extends State<MessageViewPage> {
|
|||||||
title: 'Sender',
|
title: 'Sender',
|
||||||
values: [message.senderName!],
|
values: [message.senderName!],
|
||||||
mainAction: () => {
|
mainAction: () => {
|
||||||
Navi.push(context, () => FilteredMessageViewPage(title: message.senderName!, filter: MessageFilter(senderNames: [message.senderName!])))
|
Navi.push(context, () => FilteredMessageViewPage(title: message.senderName!, alertText: 'All message sent from \'${message.senderName!}\'', filter: MessageFilter(senderNames: [message.senderName!])))
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
if (cfg.showExtendedAttributes)
|
||||||
UI.metaCard(
|
UI.metaCard(
|
||||||
context: context,
|
context: context,
|
||||||
icon: FontAwesomeIcons.solidGearCode,
|
icon: FontAwesomeIcons.solidGearCode,
|
||||||
@@ -169,21 +179,29 @@ class _MessageViewPageState extends State<MessageViewPage> {
|
|||||||
if (message.senderUserID == userAccUserID) {
|
if (message.senderUserID == userAccUserID) {
|
||||||
Navi.push(context, () => KeyTokenViewPage(keytokenID: message.usedKeyID, preloadedData: null, needsReload: null));
|
Navi.push(context, () => KeyTokenViewPage(keytokenID: message.usedKeyID, preloadedData: null, needsReload: null));
|
||||||
} else {
|
} else {
|
||||||
Navi.push(context, () => FilteredMessageViewPage(title: token?.name ?? message.usedKeyID, filter: MessageFilter(usedKeys: [message.usedKeyID])));
|
Navi.push(context, () => FilteredMessageViewPage(title: token?.name ?? message.usedKeyID, alertText: 'All message sent with the specified key', filter: MessageFilter(usedKeys: [message.usedKeyID])));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
if (!cfg.showExtendedAttributes && token != null)
|
||||||
|
UI.metaCard(
|
||||||
|
context: context,
|
||||||
|
icon: FontAwesomeIcons.solidGearCode,
|
||||||
|
title: 'KeyToken',
|
||||||
|
values: [token.name],
|
||||||
|
mainAction: () {
|
||||||
|
if (message.senderUserID == userAccUserID) {
|
||||||
|
Navi.push(context, () => KeyTokenViewPage(keytokenID: message.usedKeyID, preloadedData: null, needsReload: null));
|
||||||
|
} else {
|
||||||
|
Navi.push(context, () => FilteredMessageViewPage(title: token.name, alertText: 'All message sent with key \'${token.name}\'', filter: MessageFilter(usedKeys: [message.usedKeyID])));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
UI.metaCard(
|
|
||||||
context: context,
|
|
||||||
icon: FontAwesomeIcons.solidIdCardClip,
|
|
||||||
title: 'MessageID',
|
|
||||||
values: [message.messageID, message.userMessageID ?? ''],
|
|
||||||
),
|
|
||||||
UI.metaCard(
|
UI.metaCard(
|
||||||
context: context,
|
context: context,
|
||||||
icon: FontAwesomeIcons.solidSnake,
|
icon: FontAwesomeIcons.solidSnake,
|
||||||
title: 'Channel',
|
title: 'Channel',
|
||||||
values: [message.channelID, channel?.displayName ?? message.channelInternalName],
|
values: [if (cfg.showExtendedAttributes) message.channelID, channel?.displayName ?? message.channelInternalName],
|
||||||
mainAction: (channel != null)
|
mainAction: (channel != null)
|
||||||
? () {
|
? () {
|
||||||
Navi.push(context, () => ChannelViewPage(channelID: channel.channelID, preloadedData: null, needsReload: null));
|
Navi.push(context, () => ChannelViewPage(channelID: channel.channelID, preloadedData: null, needsReload: null));
|
||||||
@@ -196,19 +214,28 @@ class _MessageViewPageState extends State<MessageViewPage> {
|
|||||||
title: 'Timestamp',
|
title: 'Timestamp',
|
||||||
values: [message.timestamp],
|
values: [message.timestamp],
|
||||||
),
|
),
|
||||||
|
if (cfg.showExtendedAttributes)
|
||||||
UI.metaCard(
|
UI.metaCard(
|
||||||
context: context,
|
context: context,
|
||||||
icon: FontAwesomeIcons.solidUser,
|
icon: FontAwesomeIcons.solidUser,
|
||||||
title: 'User',
|
title: 'User',
|
||||||
values: [user?.userID ?? message.senderUserID, user?.username ?? ''],
|
values: [user?.userID ?? message.senderUserID, if (user?.username != null) user?.username ?? ''],
|
||||||
mainAction: () => Navi.push(context, () => FilteredMessageViewPage(title: user?.username ?? message.senderUserID, filter: MessageFilter(senderUserID: [message.senderUserID]))),
|
mainAction: () => Navi.push(context, () => FilteredMessageViewPage(title: user?.username ?? message.senderUserID, alertText: 'All message sent by the specified account', filter: MessageFilter(senderUserID: [message.senderUserID]))),
|
||||||
|
),
|
||||||
|
if (!cfg.showExtendedAttributes)
|
||||||
|
UI.metaCard(
|
||||||
|
context: context,
|
||||||
|
icon: FontAwesomeIcons.solidUser,
|
||||||
|
title: 'User',
|
||||||
|
values: [user?.username ?? user?.userID ?? message.senderUserID],
|
||||||
|
mainAction: () => Navi.push(context, () => FilteredMessageViewPage(title: user?.username ?? message.senderUserID, alertText: 'All message sent by the specified account', filter: MessageFilter(senderUserID: [message.senderUserID]))),
|
||||||
),
|
),
|
||||||
UI.metaCard(
|
UI.metaCard(
|
||||||
context: context,
|
context: context,
|
||||||
icon: FontAwesomeIcons.solidBolt,
|
icon: FontAwesomeIcons.solidBolt,
|
||||||
title: 'Priority',
|
title: 'Priority',
|
||||||
values: [_prettyPrintPriority(message.priority)],
|
values: [_prettyPrintPriority(message.priority)],
|
||||||
mainAction: () => Navi.push(context, () => FilteredMessageViewPage(title: "Priority ${message.priority}", filter: MessageFilter(priority: [message.priority]))),
|
mainAction: () => Navi.push(context, () => FilteredMessageViewPage(title: "Priority ${message.priority}", alertText: 'All message sent with priority ' + _prettyPrintPriority(message.priority), filter: MessageFilter(priority: [message.priority]))),
|
||||||
),
|
),
|
||||||
if (message.senderUserID == userAccUserID)
|
if (message.senderUserID == userAccUserID)
|
||||||
UI.button(
|
UI.button(
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
|||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:qr_flutter/qr_flutter.dart';
|
import 'package:qr_flutter/qr_flutter.dart';
|
||||||
import 'package:simplecloudnotifier/api/api_client.dart';
|
import 'package:simplecloudnotifier/api/api_client.dart';
|
||||||
|
import 'package:simplecloudnotifier/api/api_exception.dart';
|
||||||
import 'package:simplecloudnotifier/components/error_display/error_display.dart';
|
import 'package:simplecloudnotifier/components/error_display/error_display.dart';
|
||||||
import 'package:simplecloudnotifier/state/application_log.dart';
|
import 'package:simplecloudnotifier/state/application_log.dart';
|
||||||
import 'package:simplecloudnotifier/state/globals.dart';
|
import 'package:simplecloudnotifier/state/globals.dart';
|
||||||
@@ -289,6 +290,9 @@ class _SendRootPageState extends State<SendRootPage> {
|
|||||||
_msgTitle.clear();
|
_msgTitle.clear();
|
||||||
_msgContent.clear();
|
_msgContent.clear();
|
||||||
});
|
});
|
||||||
|
} on APIException catch (e, stackTrace) {
|
||||||
|
if (!e.toastShown) Toaster.error("Error", 'Failed to send message: ${e.toString()}');
|
||||||
|
ApplicationLog.error('Failed to send message', trace: stackTrace);
|
||||||
} catch (e, stackTrace) {
|
} catch (e, stackTrace) {
|
||||||
Toaster.error("Error", 'Failed to send message: ${e.toString()}');
|
Toaster.error("Error", 'Failed to send message: ${e.toString()}');
|
||||||
ApplicationLog.error('Failed to send message', trace: stackTrace);
|
ApplicationLog.error('Failed to send message', trace: stackTrace);
|
||||||
@@ -308,6 +312,9 @@ class _SendRootPageState extends State<SendRootPage> {
|
|||||||
_msgTitle.clear();
|
_msgTitle.clear();
|
||||||
_msgContent.clear();
|
_msgContent.clear();
|
||||||
});
|
});
|
||||||
|
} on APIException catch (e, stackTrace) {
|
||||||
|
if (!e.toastShown) Toaster.error("Error", 'Failed to send message: ${e.toString()}');
|
||||||
|
ApplicationLog.error('Failed to send message', trace: stackTrace);
|
||||||
} catch (e, stackTrace) {
|
} catch (e, stackTrace) {
|
||||||
Toaster.error("Error", 'Failed to send message: ${e.toString()}');
|
Toaster.error("Error", 'Failed to send message: ${e.toString()}');
|
||||||
ApplicationLog.error('Failed to send message', trace: stackTrace);
|
ApplicationLog.error('Failed to send message', trace: stackTrace);
|
||||||
|
|||||||
@@ -2,8 +2,10 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
|
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:simplecloudnotifier/api/api_client.dart';
|
import 'package:simplecloudnotifier/api/api_client.dart';
|
||||||
|
import 'package:simplecloudnotifier/components/badge_display/badge_display.dart';
|
||||||
import 'package:simplecloudnotifier/components/layout/scaffold.dart';
|
import 'package:simplecloudnotifier/components/layout/scaffold.dart';
|
||||||
import 'package:simplecloudnotifier/models/sender_name_statistics.dart';
|
import 'package:simplecloudnotifier/models/sender_name_statistics.dart';
|
||||||
|
import 'package:simplecloudnotifier/state/app_settings.dart';
|
||||||
import 'package:simplecloudnotifier/state/application_log.dart';
|
import 'package:simplecloudnotifier/state/application_log.dart';
|
||||||
import 'package:simplecloudnotifier/state/app_auth.dart';
|
import 'package:simplecloudnotifier/state/app_auth.dart';
|
||||||
import 'package:simplecloudnotifier/pages/sender_list/sender_list_item.dart';
|
import 'package:simplecloudnotifier/pages/sender_list/sender_list_item.dart';
|
||||||
@@ -69,7 +71,28 @@ class _SenderListPageState extends State<SenderListPage> {
|
|||||||
showShare: false,
|
showShare: false,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: EdgeInsets.fromLTRB(8, 4, 8, 4),
|
padding: EdgeInsets.fromLTRB(8, 4, 8, 4),
|
||||||
child: RefreshIndicator(
|
child: Column(
|
||||||
|
children: [
|
||||||
|
BadgeDisplay(
|
||||||
|
text: "All sender used to send messages to this account",
|
||||||
|
icon: null,
|
||||||
|
mode: BadgeMode.info,
|
||||||
|
textAlign: TextAlign.left,
|
||||||
|
closable: true,
|
||||||
|
extraPadding: EdgeInsets.fromLTRB(0, 0, 0, 16),
|
||||||
|
hidden: !AppSettings().showInfoAlerts,
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: _buildList(context),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildList(BuildContext context) {
|
||||||
|
return RefreshIndicator(
|
||||||
onRefresh: () => Future.sync(
|
onRefresh: () => Future.sync(
|
||||||
() => _pagingController.refresh(),
|
() => _pagingController.refresh(),
|
||||||
),
|
),
|
||||||
@@ -79,8 +102,6 @@ class _SenderListPageState extends State<SenderListPage> {
|
|||||||
itemBuilder: (context, item, index) => SenderListItem(item: item),
|
itemBuilder: (context, item, index) => SenderListItem(item: item),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ class SenderListItem extends StatelessWidget {
|
|||||||
color: Theme.of(context).cardTheme.color,
|
color: Theme.of(context).cardTheme.color,
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
Navi.push(context, () => FilteredMessageViewPage(title: item.name, filter: MessageFilter(senderNames: [item.name])));
|
Navi.push(context, () => FilteredMessageViewPage(title: item.name, alertText: 'All message sent from \'${item.name!}\'', filter: MessageFilter(senderNames: [item.name])));
|
||||||
},
|
},
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(8),
|
padding: const EdgeInsets.all(8),
|
||||||
@@ -71,7 +71,7 @@ class SenderListItem extends StatelessWidget {
|
|||||||
SizedBox(width: 4),
|
SizedBox(width: 4),
|
||||||
GestureDetector(
|
GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
Navi.push(context, () => FilteredMessageViewPage(title: item.name, filter: MessageFilter(senderNames: [item.name])));
|
Navi.push(context, () => FilteredMessageViewPage(title: item.name, alertText: 'All message sent from \'${item.name!}\'', filter: MessageFilter(senderNames: [item.name])));
|
||||||
},
|
},
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(8),
|
padding: const EdgeInsets.all(8),
|
||||||
|
|||||||
@@ -146,6 +146,18 @@ class _SettingsRootPageState extends State<SettingsRootPage> {
|
|||||||
title: Text('Refresh messages on app resume'),
|
title: Text('Refresh messages on app resume'),
|
||||||
onToggle: (value) => AppSettings().update((p) => p.alwaysBackgroundRefreshMessageListOnLifecycleResume = !p.alwaysBackgroundRefreshMessageListOnLifecycleResume),
|
onToggle: (value) => AppSettings().update((p) => p.alwaysBackgroundRefreshMessageListOnLifecycleResume = !p.alwaysBackgroundRefreshMessageListOnLifecycleResume),
|
||||||
),
|
),
|
||||||
|
SettingsTile.switchTile(
|
||||||
|
initialValue: cfg.showInfoAlerts,
|
||||||
|
leading: Icon(FontAwesomeIcons.solidCircleInfo),
|
||||||
|
title: Text('Show various helpful info boxes'),
|
||||||
|
onToggle: (value) => AppSettings().update((p) => p.showInfoAlerts = !p.showInfoAlerts),
|
||||||
|
),
|
||||||
|
SettingsTile.switchTile(
|
||||||
|
initialValue: cfg.showExtendedAttributes,
|
||||||
|
leading: Icon(FontAwesomeIcons.solidSheetPlastic),
|
||||||
|
title: Text('Show all attributes of entities'),
|
||||||
|
onToggle: (value) => AppSettings().update((p) => p.showExtendedAttributes = !p.showExtendedAttributes),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
SettingsSection(
|
SettingsSection(
|
||||||
@@ -177,7 +189,7 @@ class _SettingsRootPageState extends State<SettingsRootPage> {
|
|||||||
value: Column(
|
value: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(GitStamp.sha.substring(0, 7) + ' +' + Globals().buildNumber),
|
Text('${GitStamp.sha.substring(0, GitStamp.sha.length.clamp(0, 7))} +${Globals().buildNumber}'),
|
||||||
Text("( " + cfg.dateFormat.dateFormat().format(DateTime.parse(GitStamp.buildDateTime).toLocal()) + " )", style: TextStyle(fontStyle: FontStyle.italic)),
|
Text("( " + cfg.dateFormat.dateFormat().format(DateTime.parse(GitStamp.buildDateTime).toLocal()) + " )", style: TextStyle(fontStyle: FontStyle.italic)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -2,15 +2,41 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
|
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:simplecloudnotifier/api/api_client.dart';
|
import 'package:simplecloudnotifier/api/api_client.dart';
|
||||||
|
import 'package:simplecloudnotifier/components/badge_display/badge_display.dart';
|
||||||
|
import 'package:simplecloudnotifier/components/filter_chips/filter_chips.dart';
|
||||||
import 'package:simplecloudnotifier/components/layout/scaffold.dart';
|
import 'package:simplecloudnotifier/components/layout/scaffold.dart';
|
||||||
import 'package:simplecloudnotifier/models/channel.dart';
|
import 'package:simplecloudnotifier/models/channel.dart';
|
||||||
import 'package:simplecloudnotifier/models/subscription.dart';
|
import 'package:simplecloudnotifier/models/subscription.dart';
|
||||||
import 'package:simplecloudnotifier/models/user.dart';
|
import 'package:simplecloudnotifier/models/user.dart';
|
||||||
|
import 'package:simplecloudnotifier/state/app_settings.dart';
|
||||||
import 'package:simplecloudnotifier/state/application_log.dart';
|
import 'package:simplecloudnotifier/state/application_log.dart';
|
||||||
import 'package:simplecloudnotifier/state/app_auth.dart';
|
import 'package:simplecloudnotifier/state/app_auth.dart';
|
||||||
import 'package:simplecloudnotifier/pages/subscription_list/subscription_list_item.dart';
|
import 'package:simplecloudnotifier/pages/subscription_list/subscription_list_item.dart';
|
||||||
import 'package:simplecloudnotifier/state/scn_data_cache.dart';
|
import 'package:simplecloudnotifier/state/scn_data_cache.dart';
|
||||||
|
|
||||||
|
enum SubscriptionListFilter {
|
||||||
|
ALL,
|
||||||
|
INACTIVE,
|
||||||
|
OWN,
|
||||||
|
EXTERNAL,
|
||||||
|
INCOMING;
|
||||||
|
|
||||||
|
SubscriptionFilter toAPIFilter() {
|
||||||
|
switch (this) {
|
||||||
|
case ALL:
|
||||||
|
return SubscriptionFilter.ALL;
|
||||||
|
case INACTIVE:
|
||||||
|
return SubscriptionFilter.OWNED_INACTIVE;
|
||||||
|
case OWN:
|
||||||
|
return SubscriptionFilter.OWNED_ACTIVE;
|
||||||
|
case EXTERNAL:
|
||||||
|
return SubscriptionFilter.EXTERNAL_ALL;
|
||||||
|
case INCOMING:
|
||||||
|
return SubscriptionFilter.INCOMING_ALL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class SubscriptionListPage extends StatefulWidget {
|
class SubscriptionListPage extends StatefulWidget {
|
||||||
const SubscriptionListPage({super.key});
|
const SubscriptionListPage({super.key});
|
||||||
|
|
||||||
@@ -24,6 +50,8 @@ class _SubscriptionListPageState extends State<SubscriptionListPage> {
|
|||||||
final userCache = Map<String, UserPreview>();
|
final userCache = Map<String, UserPreview>();
|
||||||
final channelCache = Map<String, ChannelPreview>();
|
final channelCache = Map<String, ChannelPreview>();
|
||||||
|
|
||||||
|
SubscriptionListFilter filter = SubscriptionListFilter.ALL;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
@@ -58,7 +86,7 @@ class _SubscriptionListPageState extends State<SubscriptionListPage> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final items = (await APIClient.getSubscriptionList(acc)).toList();
|
final items = (await APIClient.getSubscriptionList(acc, filter.toAPIFilter())).toList();
|
||||||
|
|
||||||
items.sort((a, b) => -1 * a.timestampCreated.compareTo(b.timestampCreated));
|
items.sort((a, b) => -1 * a.timestampCreated.compareTo(b.timestampCreated));
|
||||||
|
|
||||||
@@ -93,7 +121,44 @@ class _SubscriptionListPageState extends State<SubscriptionListPage> {
|
|||||||
showShare: false,
|
showShare: false,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: EdgeInsets.fromLTRB(8, 4, 8, 4),
|
padding: EdgeInsets.fromLTRB(8, 4, 8, 4),
|
||||||
child: RefreshIndicator(
|
child: Column(
|
||||||
|
children: [
|
||||||
|
BadgeDisplay(
|
||||||
|
text: "These are subscriptions to individual Channels\n\nThey contain to your own channels, subscriptions to foreign channels and subscriptions of other users to your channels (active and requested).",
|
||||||
|
icon: null,
|
||||||
|
mode: BadgeMode.info,
|
||||||
|
textAlign: TextAlign.left,
|
||||||
|
closable: true,
|
||||||
|
extraPadding: EdgeInsets.fromLTRB(0, 0, 0, 16),
|
||||||
|
hidden: !AppSettings().showInfoAlerts,
|
||||||
|
),
|
||||||
|
FilterChips<SubscriptionListFilter>(
|
||||||
|
options: [
|
||||||
|
(SubscriptionListFilter.ALL, 'All'),
|
||||||
|
(SubscriptionListFilter.OWN, 'Own'),
|
||||||
|
(SubscriptionListFilter.EXTERNAL, 'External'),
|
||||||
|
(SubscriptionListFilter.INCOMING, 'Incoming'),
|
||||||
|
(SubscriptionListFilter.INACTIVE, 'Inactive'),
|
||||||
|
],
|
||||||
|
value: filter,
|
||||||
|
onChanged: (newFilter) {
|
||||||
|
setState(() {
|
||||||
|
filter = newFilter;
|
||||||
|
_pagingController.refresh();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: _buildList(context),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildList(BuildContext context) {
|
||||||
|
return RefreshIndicator(
|
||||||
onRefresh: () => Future.sync(
|
onRefresh: () => Future.sync(
|
||||||
() => _pagingController.refresh(),
|
() => _pagingController.refresh(),
|
||||||
),
|
),
|
||||||
@@ -103,8 +168,6 @@ class _SubscriptionListPageState extends State<SubscriptionListPage> {
|
|||||||
itemBuilder: (context, item, index) => SubscriptionListItem(item: item, userCache: userCache, channelCache: channelCache, needsReload: fullRefresh),
|
itemBuilder: (context, item, index) => SubscriptionListItem(item: item, userCache: userCache, channelCache: channelCache, needsReload: fullRefresh),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
import 'package:simplecloudnotifier/api/api_client.dart';
|
import 'package:simplecloudnotifier/api/api_client.dart';
|
||||||
|
import 'package:simplecloudnotifier/api/api_exception.dart';
|
||||||
import 'package:simplecloudnotifier/components/error_display/error_display.dart';
|
import 'package:simplecloudnotifier/components/error_display/error_display.dart';
|
||||||
import 'package:simplecloudnotifier/components/layout/scaffold.dart';
|
import 'package:simplecloudnotifier/components/layout/scaffold.dart';
|
||||||
import 'package:simplecloudnotifier/models/channel.dart';
|
import 'package:simplecloudnotifier/models/channel.dart';
|
||||||
@@ -168,6 +169,7 @@ class _SubscriptionViewPageState extends State<SubscriptionViewPage> {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: [
|
children: [
|
||||||
SizedBox(height: 8),
|
SizedBox(height: 8),
|
||||||
|
if (AppSettings().showExtendedAttributes)
|
||||||
UI.metaCard(
|
UI.metaCard(
|
||||||
context: context,
|
context: context,
|
||||||
icon: FontAwesomeIcons.solidIdCardClip,
|
icon: FontAwesomeIcons.solidIdCardClip,
|
||||||
@@ -201,6 +203,7 @@ class _SubscriptionViewPageState extends State<SubscriptionViewPage> {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: [
|
children: [
|
||||||
SizedBox(height: 8),
|
SizedBox(height: 8),
|
||||||
|
if (AppSettings().showExtendedAttributes)
|
||||||
UI.metaCard(
|
UI.metaCard(
|
||||||
context: context,
|
context: context,
|
||||||
icon: FontAwesomeIcons.solidIdCardClip,
|
icon: FontAwesomeIcons.solidIdCardClip,
|
||||||
@@ -236,6 +239,7 @@ class _SubscriptionViewPageState extends State<SubscriptionViewPage> {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: [
|
children: [
|
||||||
SizedBox(height: 8),
|
SizedBox(height: 8),
|
||||||
|
if (AppSettings().showExtendedAttributes)
|
||||||
UI.metaCard(
|
UI.metaCard(
|
||||||
context: context,
|
context: context,
|
||||||
icon: FontAwesomeIcons.solidIdCardClip,
|
icon: FontAwesomeIcons.solidIdCardClip,
|
||||||
@@ -271,12 +275,20 @@ class _SubscriptionViewPageState extends State<SubscriptionViewPage> {
|
|||||||
future: _futureChannelOwner.future,
|
future: _futureChannelOwner.future,
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
if (snapshot.hasData) {
|
if (snapshot.hasData) {
|
||||||
|
if (AppSettings().showExtendedAttributes)
|
||||||
return UI.metaCard(
|
return UI.metaCard(
|
||||||
context: context,
|
context: context,
|
||||||
icon: FontAwesomeIcons.solidUser,
|
icon: FontAwesomeIcons.solidUser,
|
||||||
title: 'Channel Owner',
|
title: 'Channel Owner',
|
||||||
values: [subscription.channelOwnerUserID + (isSelf ? ' (you)' : ''), if (snapshot.data?.username != null) snapshot.data!.username!],
|
values: [subscription.channelOwnerUserID + (isSelf ? ' (you)' : ''), if (snapshot.data?.username != null) snapshot.data!.username!],
|
||||||
);
|
);
|
||||||
|
else
|
||||||
|
return UI.metaCard(
|
||||||
|
context: context,
|
||||||
|
icon: FontAwesomeIcons.solidUser,
|
||||||
|
title: 'Channel Owner',
|
||||||
|
values: [(snapshot.data?.username ?? subscription.channelOwnerUserID) + (isSelf ? ' (you)' : '')],
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
return UI.metaCard(
|
return UI.metaCard(
|
||||||
context: context,
|
context: context,
|
||||||
@@ -298,12 +310,20 @@ class _SubscriptionViewPageState extends State<SubscriptionViewPage> {
|
|||||||
future: _futureSubscriber.future,
|
future: _futureSubscriber.future,
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
if (snapshot.hasData) {
|
if (snapshot.hasData) {
|
||||||
|
if (AppSettings().showExtendedAttributes)
|
||||||
return UI.metaCard(
|
return UI.metaCard(
|
||||||
context: context,
|
context: context,
|
||||||
icon: FontAwesomeIcons.solidUser,
|
icon: FontAwesomeIcons.solidUser,
|
||||||
title: 'Subscriber',
|
title: 'Subscriber',
|
||||||
values: [subscription.subscriberUserID + (isSelf ? ' (you)' : ''), if (snapshot.data?.username != null) snapshot.data!.username!],
|
values: [subscription.subscriberUserID + (isSelf ? ' (you)' : ''), if (snapshot.data?.username != null) snapshot.data!.username!],
|
||||||
);
|
);
|
||||||
|
else
|
||||||
|
return UI.metaCard(
|
||||||
|
context: context,
|
||||||
|
icon: FontAwesomeIcons.solidUser,
|
||||||
|
title: 'Subscriber',
|
||||||
|
values: [(snapshot.data?.username ?? subscription.subscriberUserID) + (isSelf ? ' (you)' : '')],
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
return UI.metaCard(
|
return UI.metaCard(
|
||||||
context: context,
|
context: context,
|
||||||
@@ -321,6 +341,7 @@ class _SubscriptionViewPageState extends State<SubscriptionViewPage> {
|
|||||||
future: _futureChannel.future,
|
future: _futureChannel.future,
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
if (snapshot.hasData) {
|
if (snapshot.hasData) {
|
||||||
|
if (AppSettings().showExtendedAttributes)
|
||||||
return UI.metaCard(
|
return UI.metaCard(
|
||||||
context: context,
|
context: context,
|
||||||
icon: FontAwesomeIcons.solidSnake,
|
icon: FontAwesomeIcons.solidSnake,
|
||||||
@@ -328,6 +349,14 @@ class _SubscriptionViewPageState extends State<SubscriptionViewPage> {
|
|||||||
values: [subscription.channelID, snapshot.data!.displayName],
|
values: [subscription.channelID, snapshot.data!.displayName],
|
||||||
mainAction: () => Navi.push(context, () => ChannelViewPage(channelID: subscription.channelID, preloadedData: null, needsReload: null)),
|
mainAction: () => Navi.push(context, () => ChannelViewPage(channelID: subscription.channelID, preloadedData: null, needsReload: null)),
|
||||||
);
|
);
|
||||||
|
else
|
||||||
|
return UI.metaCard(
|
||||||
|
context: context,
|
||||||
|
icon: FontAwesomeIcons.solidSnake,
|
||||||
|
title: 'Channel',
|
||||||
|
values: [snapshot.data!.displayName],
|
||||||
|
mainAction: () => Navi.push(context, () => ChannelViewPage(channelID: subscription.channelID, preloadedData: null, needsReload: null)),
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
return UI.metaCard(
|
return UI.metaCard(
|
||||||
context: context,
|
context: context,
|
||||||
@@ -407,6 +436,9 @@ class _SubscriptionViewPageState extends State<SubscriptionViewPage> {
|
|||||||
await _initStateAsync(false);
|
await _initStateAsync(false);
|
||||||
|
|
||||||
Toaster.success("Success", 'Subscription succesfully confirmed');
|
Toaster.success("Success", 'Subscription succesfully confirmed');
|
||||||
|
} on APIException catch (exc, trace) {
|
||||||
|
if (!exc.toastShown) Toaster.error("Error", 'Failed to confirm subscription');
|
||||||
|
ApplicationLog.error('Failed to confirm subscription: ' + exc.toString(), trace: trace);
|
||||||
} catch (exc, trace) {
|
} catch (exc, trace) {
|
||||||
Toaster.error("Error", 'Failed to confirm subscription');
|
Toaster.error("Error", 'Failed to confirm subscription');
|
||||||
ApplicationLog.error('Failed to confirm subscription: ' + exc.toString(), trace: trace);
|
ApplicationLog.error('Failed to confirm subscription: ' + exc.toString(), trace: trace);
|
||||||
@@ -429,6 +461,9 @@ class _SubscriptionViewPageState extends State<SubscriptionViewPage> {
|
|||||||
|
|
||||||
Toaster.success("Success", 'Unsubscribed from channel');
|
Toaster.success("Success", 'Unsubscribed from channel');
|
||||||
Navi.pop(context);
|
Navi.pop(context);
|
||||||
|
} on APIException catch (exc, trace) {
|
||||||
|
if (!exc.toastShown) Toaster.error("Error", 'Failed to unsubscribe from channel');
|
||||||
|
ApplicationLog.error('Failed to unsubscribe from channel: ' + exc.toString(), trace: trace);
|
||||||
} catch (exc, trace) {
|
} catch (exc, trace) {
|
||||||
Toaster.error("Error", 'Failed to unsubscribe from channel');
|
Toaster.error("Error", 'Failed to unsubscribe from channel');
|
||||||
ApplicationLog.error('Failed to unsubscribe from channel: ' + exc.toString(), trace: trace);
|
ApplicationLog.error('Failed to unsubscribe from channel: ' + exc.toString(), trace: trace);
|
||||||
@@ -447,6 +482,9 @@ class _SubscriptionViewPageState extends State<SubscriptionViewPage> {
|
|||||||
await _initStateAsync(false);
|
await _initStateAsync(false);
|
||||||
|
|
||||||
Toaster.success("Success", 'Unsubscribed from channel');
|
Toaster.success("Success", 'Unsubscribed from channel');
|
||||||
|
} on APIException catch (exc, trace) {
|
||||||
|
if (!exc.toastShown) Toaster.error("Error", 'Failed to unsubscribe from channel');
|
||||||
|
ApplicationLog.error('Failed to unsubscribe from channel: ' + exc.toString(), trace: trace);
|
||||||
} catch (exc, trace) {
|
} catch (exc, trace) {
|
||||||
Toaster.error("Error", 'Failed to unsubscribe from channel');
|
Toaster.error("Error", 'Failed to unsubscribe from channel');
|
||||||
ApplicationLog.error('Failed to unsubscribe from channel: ' + exc.toString(), trace: trace);
|
ApplicationLog.error('Failed to unsubscribe from channel: ' + exc.toString(), trace: trace);
|
||||||
@@ -465,6 +503,9 @@ class _SubscriptionViewPageState extends State<SubscriptionViewPage> {
|
|||||||
await _initStateAsync(false);
|
await _initStateAsync(false);
|
||||||
|
|
||||||
Toaster.success("Success", 'Subscribed to channel');
|
Toaster.success("Success", 'Subscribed to channel');
|
||||||
|
} on APIException catch (exc, trace) {
|
||||||
|
if (!exc.toastShown) Toaster.error("Error", 'Failed to subscribe to channel');
|
||||||
|
ApplicationLog.error('Failed to subscribe to channel: ' + exc.toString(), trace: trace);
|
||||||
} catch (exc, trace) {
|
} catch (exc, trace) {
|
||||||
Toaster.error("Error", 'Failed to subscribe to channel');
|
Toaster.error("Error", 'Failed to subscribe to channel');
|
||||||
ApplicationLog.error('Failed to subscribe to channel: ' + exc.toString(), trace: trace);
|
ApplicationLog.error('Failed to subscribe to channel: ' + exc.toString(), trace: trace);
|
||||||
|
|||||||
@@ -56,6 +56,8 @@ class AppSettings extends ChangeNotifier {
|
|||||||
bool alwaysBackgroundRefreshMessageListOnLifecycleResume = true;
|
bool alwaysBackgroundRefreshMessageListOnLifecycleResume = true;
|
||||||
AppSettingsDateFormat dateFormat = AppSettingsDateFormat.ISO;
|
AppSettingsDateFormat dateFormat = AppSettingsDateFormat.ISO;
|
||||||
int messagePreviewLength = 3;
|
int messagePreviewLength = 3;
|
||||||
|
bool showInfoAlerts = true;
|
||||||
|
bool showExtendedAttributes = false;
|
||||||
|
|
||||||
AppNotificationSettings notification0 = AppNotificationSettings();
|
AppNotificationSettings notification0 = AppNotificationSettings();
|
||||||
AppNotificationSettings notification1 = AppNotificationSettings();
|
AppNotificationSettings notification1 = AppNotificationSettings();
|
||||||
@@ -80,6 +82,8 @@ class AppSettings extends ChangeNotifier {
|
|||||||
alwaysBackgroundRefreshMessageListOnLifecycleResume = true;
|
alwaysBackgroundRefreshMessageListOnLifecycleResume = true;
|
||||||
dateFormat = AppSettingsDateFormat.ISO;
|
dateFormat = AppSettingsDateFormat.ISO;
|
||||||
messagePreviewLength = 3;
|
messagePreviewLength = 3;
|
||||||
|
showInfoAlerts = true;
|
||||||
|
showExtendedAttributes = false;
|
||||||
|
|
||||||
notification0 = AppNotificationSettings();
|
notification0 = AppNotificationSettings();
|
||||||
notification1 = AppNotificationSettings();
|
notification1 = AppNotificationSettings();
|
||||||
@@ -97,6 +101,8 @@ class AppSettings extends ChangeNotifier {
|
|||||||
alwaysBackgroundRefreshMessageListOnLifecycleResume = Globals().sharedPrefs.getBool('settings.alwaysBackgroundRefreshMessageListOnLifecycleResume') ?? alwaysBackgroundRefreshMessageListOnLifecycleResume;
|
alwaysBackgroundRefreshMessageListOnLifecycleResume = Globals().sharedPrefs.getBool('settings.alwaysBackgroundRefreshMessageListOnLifecycleResume') ?? alwaysBackgroundRefreshMessageListOnLifecycleResume;
|
||||||
dateFormat = AppSettingsDateFormat.parse(Globals().sharedPrefs.getString('settings.dateFormat')) ?? dateFormat;
|
dateFormat = AppSettingsDateFormat.parse(Globals().sharedPrefs.getString('settings.dateFormat')) ?? dateFormat;
|
||||||
messagePreviewLength = Globals().sharedPrefs.getInt('settings.messagePreviewLength') ?? messagePreviewLength;
|
messagePreviewLength = Globals().sharedPrefs.getInt('settings.messagePreviewLength') ?? messagePreviewLength;
|
||||||
|
showInfoAlerts = Globals().sharedPrefs.getBool('settings.showInfoAlerts') ?? showInfoAlerts;
|
||||||
|
showExtendedAttributes = Globals().sharedPrefs.getBool('settings.showExtendedAttributes') ?? showExtendedAttributes;
|
||||||
|
|
||||||
notification0 = AppNotificationSettings.load(Globals().sharedPrefs, 'settings.notification0');
|
notification0 = AppNotificationSettings.load(Globals().sharedPrefs, 'settings.notification0');
|
||||||
notification1 = AppNotificationSettings.load(Globals().sharedPrefs, 'settings.notification1');
|
notification1 = AppNotificationSettings.load(Globals().sharedPrefs, 'settings.notification1');
|
||||||
@@ -112,6 +118,8 @@ class AppSettings extends ChangeNotifier {
|
|||||||
await Globals().sharedPrefs.setBool('settings.alwaysBackgroundRefreshMessageListOnLifecycleResume', alwaysBackgroundRefreshMessageListOnLifecycleResume);
|
await Globals().sharedPrefs.setBool('settings.alwaysBackgroundRefreshMessageListOnLifecycleResume', alwaysBackgroundRefreshMessageListOnLifecycleResume);
|
||||||
await Globals().sharedPrefs.setString('settings.dateFormat', dateFormat.key);
|
await Globals().sharedPrefs.setString('settings.dateFormat', dateFormat.key);
|
||||||
await Globals().sharedPrefs.setInt('settings.messagePreviewLength', messagePreviewLength);
|
await Globals().sharedPrefs.setInt('settings.messagePreviewLength', messagePreviewLength);
|
||||||
|
await Globals().sharedPrefs.setBool('settings.showInfoAlerts', showInfoAlerts);
|
||||||
|
await Globals().sharedPrefs.setBool('settings.showExtendedAttributes', showExtendedAttributes);
|
||||||
|
|
||||||
await notification0.save(Globals().sharedPrefs, 'settings.notification0');
|
await notification0.save(Globals().sharedPrefs, 'settings.notification0');
|
||||||
await notification1.save(Globals().sharedPrefs, 'settings.notification1');
|
await notification1.save(Globals().sharedPrefs, 'settings.notification1');
|
||||||
@@ -152,14 +160,7 @@ class AppSettings extends ChangeNotifier {
|
|||||||
|
|
||||||
class AppNotificationSettings {
|
class AppNotificationSettings {
|
||||||
// Immutable
|
// Immutable
|
||||||
AppNotificationSettings({
|
AppNotificationSettings({this.enableLights = false, this.enableVibration = true, this.playSound = true, this.sound = null, this.silent = false, this.timeoutAfter = null});
|
||||||
this.enableLights = false,
|
|
||||||
this.enableVibration = true,
|
|
||||||
this.playSound = true,
|
|
||||||
this.sound = null,
|
|
||||||
this.silent = false,
|
|
||||||
this.timeoutAfter = null,
|
|
||||||
});
|
|
||||||
|
|
||||||
final bool enableLights;
|
final bool enableLights;
|
||||||
final bool enableVibration;
|
final bool enableVibration;
|
||||||
@@ -198,14 +199,7 @@ class AppNotificationSettings {
|
|||||||
final silent = prefs.getBool('${prefix}.silent') ?? def.silent;
|
final silent = prefs.getBool('${prefix}.silent') ?? def.silent;
|
||||||
final timeoutAfter = _decode(prefs.getString('${prefix}.timeoutAfter'), def.timeoutAfter);
|
final timeoutAfter = _decode(prefs.getString('${prefix}.timeoutAfter'), def.timeoutAfter);
|
||||||
|
|
||||||
return AppNotificationSettings(
|
return AppNotificationSettings(enableLights: enableLights, enableVibration: enableVibration, playSound: playSound, sound: sound, silent: silent, timeoutAfter: timeoutAfter);
|
||||||
enableLights: enableLights,
|
|
||||||
enableVibration: enableVibration,
|
|
||||||
playSound: playSound,
|
|
||||||
sound: sound,
|
|
||||||
silent: silent,
|
|
||||||
timeoutAfter: timeoutAfter,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1,2 @@
|
|||||||
|
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
|
||||||
#include "ephemeral/Flutter-Generated.xcconfig"
|
#include "ephemeral/Flutter-Generated.xcconfig"
|
||||||
|
|||||||
@@ -1 +1,2 @@
|
|||||||
|
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
|
||||||
#include "ephemeral/Flutter-Generated.xcconfig"
|
#include "ephemeral/Flutter-Generated.xcconfig"
|
||||||
|
|||||||
@@ -21,12 +21,14 @@
|
|||||||
/* End PBXAggregateTarget section */
|
/* End PBXAggregateTarget section */
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
|
30051E098E5DDBD2E1D16F95 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 260FDBA879E00B3BD57336B6 /* Pods_RunnerTests.framework */; };
|
||||||
331C80D8294CF71000263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C80D7294CF71000263BE5 /* RunnerTests.swift */; };
|
331C80D8294CF71000263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C80D7294CF71000263BE5 /* RunnerTests.swift */; };
|
||||||
335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; };
|
335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; };
|
||||||
33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC10F02044A3C60003C045 /* AppDelegate.swift */; };
|
33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC10F02044A3C60003C045 /* AppDelegate.swift */; };
|
||||||
33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; };
|
33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; };
|
||||||
33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; };
|
33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; };
|
||||||
33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; };
|
33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; };
|
||||||
|
D6E1D80C6733E06BC2484012 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 71450153D8FB1F125629A01B /* Pods_Runner.framework */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXContainerItemProxy section */
|
/* Begin PBXContainerItemProxy section */
|
||||||
@@ -60,11 +62,12 @@
|
|||||||
/* End PBXCopyFilesBuildPhase section */
|
/* End PBXCopyFilesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
|
260FDBA879E00B3BD57336B6 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
331C80D5294CF71000263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
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 = "<group>"; };
|
331C80D7294CF71000263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = "<group>"; };
|
||||||
333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = "<group>"; };
|
333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = "<group>"; };
|
||||||
335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = "<group>"; };
|
335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = "<group>"; };
|
||||||
33CC10ED2044A3C60003C045 /* simplecloudnotifier.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "simplecloudnotifier.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
33CC10ED2044A3C60003C045 /* simplecloudnotifier.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = simplecloudnotifier.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||||
33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = "<group>"; };
|
33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = "<group>"; };
|
||||||
33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = "<group>"; };
|
33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = "<group>"; };
|
||||||
@@ -76,8 +79,15 @@
|
|||||||
33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = "<group>"; };
|
33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = "<group>"; };
|
||||||
33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = "<group>"; };
|
33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = "<group>"; };
|
||||||
33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = "<group>"; };
|
33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = "<group>"; };
|
||||||
|
71450153D8FB1F125629A01B /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
71DA993D9EDD2A4A54234FF2 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
|
||||||
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = "<group>"; };
|
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = "<group>"; };
|
||||||
|
9496FF8D8B46D4619EDAA5EF /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = "<group>"; };
|
||||||
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = "<group>"; };
|
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = "<group>"; };
|
||||||
|
B9F3F9EB590C25EBDAE05E03 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
|
||||||
|
BF6145095420650A6CCA9EE3 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = "<group>"; };
|
||||||
|
C0E65636E0666802F744A5E3 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
|
||||||
|
C71F9C04DE64EB26EF8E0E58 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
@@ -85,6 +95,7 @@
|
|||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
30051E098E5DDBD2E1D16F95 /* Pods_RunnerTests.framework in Frameworks */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@@ -92,12 +103,27 @@
|
|||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
D6E1D80C6733E06BC2484012 /* Pods_Runner.framework in Frameworks */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
/* End PBXFrameworksBuildPhase section */
|
/* End PBXFrameworksBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXGroup section */
|
/* Begin PBXGroup section */
|
||||||
|
25379216233BB0105FDA3DD4 /* Pods */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
C0E65636E0666802F744A5E3 /* Pods-Runner.debug.xcconfig */,
|
||||||
|
71DA993D9EDD2A4A54234FF2 /* Pods-Runner.release.xcconfig */,
|
||||||
|
B9F3F9EB590C25EBDAE05E03 /* Pods-Runner.profile.xcconfig */,
|
||||||
|
C71F9C04DE64EB26EF8E0E58 /* Pods-RunnerTests.debug.xcconfig */,
|
||||||
|
BF6145095420650A6CCA9EE3 /* Pods-RunnerTests.release.xcconfig */,
|
||||||
|
9496FF8D8B46D4619EDAA5EF /* Pods-RunnerTests.profile.xcconfig */,
|
||||||
|
);
|
||||||
|
name = Pods;
|
||||||
|
path = Pods;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
331C80D6294CF71000263BE5 /* RunnerTests */ = {
|
331C80D6294CF71000263BE5 /* RunnerTests */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -125,6 +151,7 @@
|
|||||||
331C80D6294CF71000263BE5 /* RunnerTests */,
|
331C80D6294CF71000263BE5 /* RunnerTests */,
|
||||||
33CC10EE2044A3C60003C045 /* Products */,
|
33CC10EE2044A3C60003C045 /* Products */,
|
||||||
D73912EC22F37F3D000D13A0 /* Frameworks */,
|
D73912EC22F37F3D000D13A0 /* Frameworks */,
|
||||||
|
25379216233BB0105FDA3DD4 /* Pods */,
|
||||||
);
|
);
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
@@ -175,6 +202,8 @@
|
|||||||
D73912EC22F37F3D000D13A0 /* Frameworks */ = {
|
D73912EC22F37F3D000D13A0 /* Frameworks */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
71450153D8FB1F125629A01B /* Pods_Runner.framework */,
|
||||||
|
260FDBA879E00B3BD57336B6 /* Pods_RunnerTests.framework */,
|
||||||
);
|
);
|
||||||
name = Frameworks;
|
name = Frameworks;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -186,6 +215,7 @@
|
|||||||
isa = PBXNativeTarget;
|
isa = PBXNativeTarget;
|
||||||
buildConfigurationList = 331C80DE294CF71000263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */;
|
buildConfigurationList = 331C80DE294CF71000263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */;
|
||||||
buildPhases = (
|
buildPhases = (
|
||||||
|
DA445DDFEB72AB2901C75BCA /* [CP] Check Pods Manifest.lock */,
|
||||||
331C80D1294CF70F00263BE5 /* Sources */,
|
331C80D1294CF70F00263BE5 /* Sources */,
|
||||||
331C80D2294CF70F00263BE5 /* Frameworks */,
|
331C80D2294CF70F00263BE5 /* Frameworks */,
|
||||||
331C80D3294CF70F00263BE5 /* Resources */,
|
331C80D3294CF70F00263BE5 /* Resources */,
|
||||||
@@ -204,11 +234,14 @@
|
|||||||
isa = PBXNativeTarget;
|
isa = PBXNativeTarget;
|
||||||
buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */;
|
buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */;
|
||||||
buildPhases = (
|
buildPhases = (
|
||||||
|
27E4C9B69EF1878B4DAFB474 /* [CP] Check Pods Manifest.lock */,
|
||||||
33CC10E92044A3C60003C045 /* Sources */,
|
33CC10E92044A3C60003C045 /* Sources */,
|
||||||
33CC10EA2044A3C60003C045 /* Frameworks */,
|
33CC10EA2044A3C60003C045 /* Frameworks */,
|
||||||
33CC10EB2044A3C60003C045 /* Resources */,
|
33CC10EB2044A3C60003C045 /* Resources */,
|
||||||
33CC110E2044A8840003C045 /* Bundle Framework */,
|
33CC110E2044A8840003C045 /* Bundle Framework */,
|
||||||
3399D490228B24CF009A79C7 /* ShellScript */,
|
3399D490228B24CF009A79C7 /* ShellScript */,
|
||||||
|
A4B4F505F9548B10CBCD5F0A /* [CP] Embed Pods Frameworks */,
|
||||||
|
B2787524EFDFEFCFFDA32C4E /* [CP] Copy Pods Resources */,
|
||||||
);
|
);
|
||||||
buildRules = (
|
buildRules = (
|
||||||
);
|
);
|
||||||
@@ -227,7 +260,7 @@
|
|||||||
isa = PBXProject;
|
isa = PBXProject;
|
||||||
attributes = {
|
attributes = {
|
||||||
LastSwiftUpdateCheck = 0920;
|
LastSwiftUpdateCheck = 0920;
|
||||||
LastUpgradeCheck = 1430;
|
LastUpgradeCheck = 1510;
|
||||||
ORGANIZATIONNAME = "";
|
ORGANIZATIONNAME = "";
|
||||||
TargetAttributes = {
|
TargetAttributes = {
|
||||||
331C80D4294CF70F00263BE5 = {
|
331C80D4294CF70F00263BE5 = {
|
||||||
@@ -290,6 +323,28 @@
|
|||||||
/* End PBXResourcesBuildPhase section */
|
/* End PBXResourcesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXShellScriptBuildPhase section */
|
/* Begin PBXShellScriptBuildPhase section */
|
||||||
|
27E4C9B69EF1878B4DAFB474 /* [CP] Check Pods Manifest.lock */ = {
|
||||||
|
isa = PBXShellScriptBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
inputFileListPaths = (
|
||||||
|
);
|
||||||
|
inputPaths = (
|
||||||
|
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
||||||
|
"${PODS_ROOT}/Manifest.lock",
|
||||||
|
);
|
||||||
|
name = "[CP] Check Pods Manifest.lock";
|
||||||
|
outputFileListPaths = (
|
||||||
|
);
|
||||||
|
outputPaths = (
|
||||||
|
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
shellPath = /bin/sh;
|
||||||
|
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||||
|
showEnvVarsInLog = 0;
|
||||||
|
};
|
||||||
3399D490228B24CF009A79C7 /* ShellScript */ = {
|
3399D490228B24CF009A79C7 /* ShellScript */ = {
|
||||||
isa = PBXShellScriptBuildPhase;
|
isa = PBXShellScriptBuildPhase;
|
||||||
alwaysOutOfDate = 1;
|
alwaysOutOfDate = 1;
|
||||||
@@ -328,6 +383,62 @@
|
|||||||
shellPath = /bin/sh;
|
shellPath = /bin/sh;
|
||||||
shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire";
|
shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire";
|
||||||
};
|
};
|
||||||
|
A4B4F505F9548B10CBCD5F0A /* [CP] Embed Pods Frameworks */ = {
|
||||||
|
isa = PBXShellScriptBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
inputFileListPaths = (
|
||||||
|
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
|
||||||
|
);
|
||||||
|
name = "[CP] Embed Pods Frameworks";
|
||||||
|
outputFileListPaths = (
|
||||||
|
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
shellPath = /bin/sh;
|
||||||
|
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
|
||||||
|
showEnvVarsInLog = 0;
|
||||||
|
};
|
||||||
|
B2787524EFDFEFCFFDA32C4E /* [CP] Copy Pods Resources */ = {
|
||||||
|
isa = PBXShellScriptBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
inputFileListPaths = (
|
||||||
|
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist",
|
||||||
|
);
|
||||||
|
name = "[CP] Copy Pods Resources";
|
||||||
|
outputFileListPaths = (
|
||||||
|
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist",
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
shellPath = /bin/sh;
|
||||||
|
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n";
|
||||||
|
showEnvVarsInLog = 0;
|
||||||
|
};
|
||||||
|
DA445DDFEB72AB2901C75BCA /* [CP] Check Pods Manifest.lock */ = {
|
||||||
|
isa = PBXShellScriptBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
inputFileListPaths = (
|
||||||
|
);
|
||||||
|
inputPaths = (
|
||||||
|
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
||||||
|
"${PODS_ROOT}/Manifest.lock",
|
||||||
|
);
|
||||||
|
name = "[CP] Check Pods Manifest.lock";
|
||||||
|
outputFileListPaths = (
|
||||||
|
);
|
||||||
|
outputPaths = (
|
||||||
|
"$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt",
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
shellPath = /bin/sh;
|
||||||
|
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||||
|
showEnvVarsInLog = 0;
|
||||||
|
};
|
||||||
/* End PBXShellScriptBuildPhase section */
|
/* End PBXShellScriptBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXSourcesBuildPhase section */
|
/* Begin PBXSourcesBuildPhase section */
|
||||||
@@ -379,6 +490,7 @@
|
|||||||
/* Begin XCBuildConfiguration section */
|
/* Begin XCBuildConfiguration section */
|
||||||
331C80DB294CF71000263BE5 /* Debug */ = {
|
331C80DB294CF71000263BE5 /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
|
baseConfigurationReference = C71F9C04DE64EB26EF8E0E58 /* Pods-RunnerTests.debug.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||||
CURRENT_PROJECT_VERSION = 1;
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
@@ -393,6 +505,7 @@
|
|||||||
};
|
};
|
||||||
331C80DC294CF71000263BE5 /* Release */ = {
|
331C80DC294CF71000263BE5 /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
|
baseConfigurationReference = BF6145095420650A6CCA9EE3 /* Pods-RunnerTests.release.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||||
CURRENT_PROJECT_VERSION = 1;
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
@@ -407,6 +520,7 @@
|
|||||||
};
|
};
|
||||||
331C80DD294CF71000263BE5 /* Profile */ = {
|
331C80DD294CF71000263BE5 /* Profile */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
|
baseConfigurationReference = 9496FF8D8B46D4619EDAA5EF /* Pods-RunnerTests.profile.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||||
CURRENT_PROJECT_VERSION = 1;
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
@@ -457,7 +571,7 @@
|
|||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.14;
|
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||||
MTL_ENABLE_DEBUG_INFO = NO;
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
SDKROOT = macosx;
|
SDKROOT = macosx;
|
||||||
SWIFT_COMPILATION_MODE = wholemodule;
|
SWIFT_COMPILATION_MODE = wholemodule;
|
||||||
@@ -536,7 +650,7 @@
|
|||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.14;
|
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||||
MTL_ENABLE_DEBUG_INFO = YES;
|
MTL_ENABLE_DEBUG_INFO = YES;
|
||||||
ONLY_ACTIVE_ARCH = YES;
|
ONLY_ACTIVE_ARCH = YES;
|
||||||
SDKROOT = macosx;
|
SDKROOT = macosx;
|
||||||
@@ -583,7 +697,7 @@
|
|||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.14;
|
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||||
MTL_ENABLE_DEBUG_INFO = NO;
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
SDKROOT = macosx;
|
SDKROOT = macosx;
|
||||||
SWIFT_COMPILATION_MODE = wholemodule;
|
SWIFT_COMPILATION_MODE = wholemodule;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<Scheme
|
<Scheme
|
||||||
LastUpgradeVersion = "1430"
|
LastUpgradeVersion = "1510"
|
||||||
version = "1.3">
|
version = "1.3">
|
||||||
<BuildAction
|
<BuildAction
|
||||||
parallelizeBuildables = "YES"
|
parallelizeBuildables = "YES"
|
||||||
@@ -59,6 +59,7 @@
|
|||||||
ignoresPersistentStateOnLaunch = "NO"
|
ignoresPersistentStateOnLaunch = "NO"
|
||||||
debugDocumentVersioning = "YES"
|
debugDocumentVersioning = "YES"
|
||||||
debugServiceExtension = "internal"
|
debugServiceExtension = "internal"
|
||||||
|
enableGPUValidationMode = "1"
|
||||||
allowLocationSimulation = "YES">
|
allowLocationSimulation = "YES">
|
||||||
<BuildableProductRunnable
|
<BuildableProductRunnable
|
||||||
runnableDebuggingMode = "0">
|
runnableDebuggingMode = "0">
|
||||||
|
|||||||
@@ -4,4 +4,7 @@
|
|||||||
<FileRef
|
<FileRef
|
||||||
location = "group:Runner.xcodeproj">
|
location = "group:Runner.xcodeproj">
|
||||||
</FileRef>
|
</FileRef>
|
||||||
|
<FileRef
|
||||||
|
location = "group:Pods/Pods.xcodeproj">
|
||||||
|
</FileRef>
|
||||||
</Workspace>
|
</Workspace>
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
import Cocoa
|
import Cocoa
|
||||||
import FlutterMacOS
|
import FlutterMacOS
|
||||||
|
|
||||||
@NSApplicationMain
|
@main
|
||||||
class AppDelegate: FlutterAppDelegate {
|
class AppDelegate: FlutterAppDelegate {
|
||||||
override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
|
override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,23 +5,18 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: _fe_analyzer_shared
|
name: _fe_analyzer_shared
|
||||||
sha256: "16e298750b6d0af7ce8a3ba7c18c69c3785d11b15ec83f6dcd0ad2a0009b3cab"
|
sha256: "0b2f2bd91ba804e53a61d757b986f89f1f9eaed5b11e4b2f5a2468d86d6c9fc7"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "76.0.0"
|
version: "67.0.0"
|
||||||
_flutterfire_internals:
|
_flutterfire_internals:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: _flutterfire_internals
|
name: _flutterfire_internals
|
||||||
sha256: de9ecbb3ddafd446095f7e833c853aff2fa1682b017921fe63a833f9d6f0e422
|
sha256: ff0a84a2734d9e1089f8aedd5c0af0061b82fb94e95260d943404e0ef2134b11
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.54"
|
version: "1.3.59"
|
||||||
_macros:
|
|
||||||
dependency: transitive
|
|
||||||
description: dart
|
|
||||||
source: sdk
|
|
||||||
version: "0.3.3"
|
|
||||||
action_slider:
|
action_slider:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@@ -34,18 +29,18 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: analyzer
|
name: analyzer
|
||||||
sha256: "1f14db053a8c23e260789e9b0980fa27f2680dd640932cae5e1137cce0e46e1e"
|
sha256: "37577842a27e4338429a1cbc32679d508836510b056f1eedf0c8d20e39c1383d"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.11.0"
|
version: "6.4.1"
|
||||||
archive:
|
archive:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: archive
|
name: archive
|
||||||
sha256: "7dcbd0f87fe5f61cb28da39a1a8b70dbc106e2fe0516f7836eb7bb2948481a12"
|
sha256: "2fde1607386ab523f7a36bb3e7edb43bd58e6edaf2ffb29d8a6d578b297fdbbd"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.0.5"
|
version: "4.0.7"
|
||||||
args:
|
args:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -66,18 +61,18 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: asn1lib
|
name: asn1lib
|
||||||
sha256: e02d018628c870ef2d7f03e33f9ad179d89ff6ec52ca6c56bcb80bcef979867f
|
sha256: "9a8f69025044eb466b9b60ef3bc3ac99b4dc6c158ae9c56d25eeccf5bc56d024"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.6.2"
|
version: "1.6.5"
|
||||||
async:
|
async:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: async
|
name: async
|
||||||
sha256: d2872f9c19731c2e5f10444b14686eb7cc85c76274bd6c16e1816bff9a3bab63
|
sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.12.0"
|
version: "2.13.0"
|
||||||
boolean_selector:
|
boolean_selector:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -90,10 +85,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: build
|
name: build
|
||||||
sha256: cef23f1eda9b57566c81e2133d196f8e3df48f244b317368d65c5943d91148f0
|
sha256: "80184af8b6cb3e5c1c4ec6d8544d27711700bc3e6d2efad04238c7b5290889f0"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.4.2"
|
version: "2.4.1"
|
||||||
build_config:
|
build_config:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -106,34 +101,34 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: build_daemon
|
name: build_daemon
|
||||||
sha256: "8e928697a82be082206edb0b9c99c5a4ad6bc31c9e9b8b2f291ae65cd4a25daa"
|
sha256: "409002f1adeea601018715d613115cfaf0e31f512cb80ae4534c79867ae2363d"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.0.4"
|
version: "4.1.0"
|
||||||
build_resolvers:
|
build_resolvers:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: build_resolvers
|
name: build_resolvers
|
||||||
sha256: b9e4fda21d846e192628e7a4f6deda6888c36b5b69ba02ff291a01fd529140f0
|
sha256: "339086358431fa15d7eca8b6a36e5d783728cf025e559b834f4609a1fcfb7b0a"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.4.4"
|
version: "2.4.2"
|
||||||
build_runner:
|
build_runner:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
name: build_runner
|
name: build_runner
|
||||||
sha256: "058fe9dce1de7d69c4b84fada934df3e0153dd000758c4d65964d0166779aa99"
|
sha256: "028819cfb90051c6b5440c7e574d1896f8037e3c96cf17aaeb054c9311cfbf4d"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.4.15"
|
version: "2.4.13"
|
||||||
build_runner_core:
|
build_runner_core:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: build_runner_core
|
name: build_runner_core
|
||||||
sha256: "22e3aa1c80e0ada3722fe5b63fd43d9c8990759d0a2cf489c8c5d7b2bdebc021"
|
sha256: f8126682b87a7282a339b871298cc12009cb67109cfa1614d6436fb0289193e0
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "8.0.0"
|
version: "7.3.2"
|
||||||
built_collection:
|
built_collection:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -146,10 +141,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: built_value
|
name: built_value
|
||||||
sha256: ea90e81dc4a25a043d9bee692d20ed6d1c4a1662a28c03a96417446c093ed6b4
|
sha256: a30f0a0e38671e89a492c44d005b5545b830a961575bbd8336d42869ff71066d
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "8.9.5"
|
version: "8.12.0"
|
||||||
characters:
|
characters:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -162,10 +157,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: checked_yaml
|
name: checked_yaml
|
||||||
sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff
|
sha256: "959525d3162f249993882720d52b7e0c833978df229be20702b33d48d91de70f"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.3"
|
version: "2.0.4"
|
||||||
cli_util:
|
cli_util:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -186,10 +181,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: code_builder
|
name: code_builder
|
||||||
sha256: "0ec10bf4a89e4c613960bf1e8b42c64127021740fb21640c29c909826a5eea3e"
|
sha256: "11654819532ba94c34de52ff5feb52bd81cba1de00ef2ed622fd50295f9d4243"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.10.1"
|
version: "4.11.0"
|
||||||
collection:
|
collection:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -210,18 +205,18 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: cross_file
|
name: cross_file
|
||||||
sha256: "7caf6a750a0c04effbb52a676dce9a4a592e10ad35c34d6d2d0e4811160d5670"
|
sha256: "942a4791cd385a68ccb3b32c71c427aba508a1bb949b86dff2adbe4049f16239"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.3.4+2"
|
version: "0.3.5"
|
||||||
crypto:
|
crypto:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: crypto
|
name: crypto
|
||||||
sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855"
|
sha256: c8ea0233063ba03258fbcf2ca4d6dadfefe14f02fab57702265467a19f27fadf
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.6"
|
version: "3.0.7"
|
||||||
cupertino_icons:
|
cupertino_icons:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@@ -234,10 +229,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: dart_style
|
name: dart_style
|
||||||
sha256: "7306ab8a2359a48d22310ad823521d723acfed60ee1f7e37388e8986853b6820"
|
sha256: "99e066ce75c89d6b29903d788a7bb9369cf754f7b24bf70bf4b6d6d6b26853b9"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.8"
|
version: "2.3.6"
|
||||||
dbus:
|
dbus:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -250,18 +245,18 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: device_info_plus
|
name: device_info_plus
|
||||||
sha256: "306b78788d1bb569edb7c55d622953c2414ca12445b41c9117963e03afc5c513"
|
sha256: "98f28b42168cc509abc92f88518882fd58061ea372d7999aecc424345c7bff6a"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "11.3.3"
|
version: "11.5.0"
|
||||||
device_info_plus_platform_interface:
|
device_info_plus_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: device_info_plus_platform_interface
|
name: device_info_plus_platform_interface
|
||||||
sha256: "0b04e02b30791224b31969eb1b50d723498f402971bff3630bca2ba839bd1ed2"
|
sha256: e1ea89119e34903dca74b883d0dd78eb762814f97fb6c76f35e9ff74d261a18f
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "7.0.2"
|
version: "7.0.3"
|
||||||
encrypt:
|
encrypt:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -282,10 +277,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: fake_async
|
name: fake_async
|
||||||
sha256: "6a95e56b2449df2273fd8c45a662d6947ce1ebb7aafe80e550a3f68297f3cacc"
|
sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.2"
|
version: "1.3.3"
|
||||||
ffi:
|
ffi:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -306,50 +301,50 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: firebase_core
|
name: firebase_core
|
||||||
sha256: "017d17d9915670e6117497e640b2859e0b868026ea36bf3a57feb28c3b97debe"
|
sha256: "7be63a3f841fc9663342f7f3a011a42aef6a61066943c90b1c434d79d5c995c5"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.13.0"
|
version: "3.15.2"
|
||||||
firebase_core_platform_interface:
|
firebase_core_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: firebase_core_platform_interface
|
name: firebase_core_platform_interface
|
||||||
sha256: d7253d255ff10f85cfd2adaba9ac17bae878fa3ba577462451163bd9f1d1f0bf
|
sha256: cccb4f572325dc14904c02fcc7db6323ad62ba02536833dddb5c02cac7341c64
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.4.0"
|
version: "6.0.2"
|
||||||
firebase_core_web:
|
firebase_core_web:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: firebase_core_web
|
name: firebase_core_web
|
||||||
sha256: "129a34d1e0fb62e2b488d988a1fc26cc15636357e50944ffee2862efe8929b23"
|
sha256: "0ed0dc292e8f9ac50992e2394e9d336a0275b6ae400d64163fdf0a8a8b556c37"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.22.0"
|
version: "2.24.1"
|
||||||
firebase_messaging:
|
firebase_messaging:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: firebase_messaging
|
name: firebase_messaging
|
||||||
sha256: "5f8918848ee0c8eb172fc7698619b2bcd7dda9ade8b93522c6297dd8f9178356"
|
sha256: "60be38574f8b5658e2f22b7e311ff2064bea835c248424a383783464e8e02fcc"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "15.2.5"
|
version: "15.2.10"
|
||||||
firebase_messaging_platform_interface:
|
firebase_messaging_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: firebase_messaging_platform_interface
|
name: firebase_messaging_platform_interface
|
||||||
sha256: "0bbea00680249595fc896e7313a2bd90bd55be6e0abbe8b9a39d81b6b306acb6"
|
sha256: "685e1771b3d1f9c8502771ccc9f91485b376ffe16d553533f335b9183ea99754"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.6.5"
|
version: "4.6.10"
|
||||||
firebase_messaging_web:
|
firebase_messaging_web:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: firebase_messaging_web
|
name: firebase_messaging_web
|
||||||
sha256: ffb392ce2a7e8439cd0a9a80e3c702194e73c927e5c7b4f0adf6faa00b245b17
|
sha256: "0d1be17bc89ed3ff5001789c92df678b2e963a51b6fa2bdb467532cc9dbed390"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.10.5"
|
version: "3.10.10"
|
||||||
fixnum:
|
fixnum:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -362,10 +357,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: fl_chart
|
name: fl_chart
|
||||||
sha256: "74959b99b92b9eebeed1a4049426fd67c4abc3c5a0f4d12e2877097d6a11ae08"
|
sha256: "5276944c6ffc975ae796569a826c38a62d2abcf264e26b88fa6f482e107f4237"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.69.2"
|
version: "0.70.2"
|
||||||
flutter:
|
flutter:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description: flutter
|
description: flutter
|
||||||
@@ -375,18 +370,18 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: flutter_launcher_icons
|
name: flutter_launcher_icons
|
||||||
sha256: bfa04787c85d80ecb3f8777bde5fc10c3de809240c48fa061a2c2bf15ea5211c
|
sha256: "10f13781741a2e3972126fae08393d3c4e01fa4cd7473326b94b72cf594195e7"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.14.3"
|
version: "0.14.4"
|
||||||
flutter_lazy_indexed_stack:
|
flutter_lazy_indexed_stack:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: flutter_lazy_indexed_stack
|
name: flutter_lazy_indexed_stack
|
||||||
sha256: e5529b516890475465c8c34b23d611e9c46b23c745c08edf471d1b6f899f5c9f
|
sha256: "3e905c0f130538f686e4e07bb8d0bc0dee6890366c65da199fb356aab52e0bff"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.0.6"
|
version: "0.0.7"
|
||||||
flutter_lints:
|
flutter_lints:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
@@ -456,10 +451,10 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: git_stamp
|
name: git_stamp
|
||||||
sha256: eddda29d15136503af57b5d927393fab2e7fe9660d4dc9ae418eb69c3f542c30
|
sha256: "25b123a0fd214c5d87f2a32f990771da76d2f24d66f6767cc190e174e3670fdd"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.10.0"
|
version: "5.10.1"
|
||||||
glob:
|
glob:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -504,10 +499,10 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: http
|
name: http
|
||||||
sha256: fe7ab022b76f3034adc518fb6ea04a82387620e19977665ea18d30a1cf43442f
|
sha256: bb2ce4590bc2667c96f318d68cac1b5a7987ec819351d32b1c987239a815e007
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.0"
|
version: "1.5.0"
|
||||||
http_multi_server:
|
http_multi_server:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -528,10 +523,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: iconsax_flutter
|
name: iconsax_flutter
|
||||||
sha256: "95b65699da8ea98f87c5d232f06b0debaaf1ec1332b697e4d90969ec9a93037d"
|
sha256: d14b4cec8586025ac15276bdd40f6eea308cb85748135965bb6255f14beb2564
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.0"
|
version: "1.0.1"
|
||||||
image:
|
image:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -552,10 +547,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: in_app_purchase_android
|
name: in_app_purchase_android
|
||||||
sha256: fd76e5612da6facadcfe8a3477da092908227260a9f6ec7db9a66dd989c69b02
|
sha256: "2d0e2d27b93bd7457526419d7feb07baf5608d733ecf6cdcd2e3b03ea7248915"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.4.0+2"
|
version: "0.4.0+6"
|
||||||
in_app_purchase_platform_interface:
|
in_app_purchase_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -568,10 +563,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: in_app_purchase_storekit
|
name: in_app_purchase_storekit
|
||||||
sha256: "9c2b438aa8ef95ac1c1f5ab1aaace8d6edd0ba3745b8b8df832f7baa2e7492f7"
|
sha256: bfdb8d1859b6d19a55aba1046e3a860c631b6e96d36275a358e1caf8b62cfbde
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.4.1"
|
version: "0.4.6+1"
|
||||||
infinite_scroll_pagination:
|
infinite_scroll_pagination:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@@ -616,26 +611,26 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: leak_tracker
|
name: leak_tracker
|
||||||
sha256: c35baad643ba394b40aac41080300150a4f08fd0fd6a10378f8f7c6bc161acec
|
sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "10.0.8"
|
version: "11.0.2"
|
||||||
leak_tracker_flutter_testing:
|
leak_tracker_flutter_testing:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: leak_tracker_flutter_testing
|
name: leak_tracker_flutter_testing
|
||||||
sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573
|
sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.9"
|
version: "3.0.10"
|
||||||
leak_tracker_testing:
|
leak_tracker_testing:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: leak_tracker_testing
|
name: leak_tracker_testing
|
||||||
sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3"
|
sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.1"
|
version: "3.0.2"
|
||||||
lints:
|
lints:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -652,14 +647,6 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.0"
|
version: "1.3.0"
|
||||||
macros:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: macros
|
|
||||||
sha256: "1d9e801cd66f7ea3663c45fc708450db1fa57f988142c64289142c9b7ee80656"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "0.1.3-main.0"
|
|
||||||
matcher:
|
matcher:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -696,10 +683,10 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: mobile_scanner
|
name: mobile_scanner
|
||||||
sha256: "9cb9e371ee9b5b548714f9ab5fd33b530d799745c83d5729ecd1e8ab2935dbd1"
|
sha256: "0b466a0a8a211b366c2e87f3345715faef9b6011c7147556ad22f37de6ba3173"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.0.7"
|
version: "6.0.11"
|
||||||
mutex:
|
mutex:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@@ -728,18 +715,18 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: package_info_plus
|
name: package_info_plus
|
||||||
sha256: "7976bfe4c583170d6cdc7077e3237560b364149fcd268b5f53d95a991963b191"
|
sha256: "16eee997588c60225bda0488b6dcfac69280a6b7a3cf02c741895dd370a02968"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "8.3.0"
|
version: "8.3.1"
|
||||||
package_info_plus_platform_interface:
|
package_info_plus_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: package_info_plus_platform_interface
|
name: package_info_plus_platform_interface
|
||||||
sha256: "6c935fb612dff8e3cc9632c2b301720c77450a126114126ffaafe28d2e87956c"
|
sha256: "202a487f08836a592a6bd4f901ac69b3a8f146af552bbd14407b6b41e1c3f086"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.2.0"
|
version: "3.2.1"
|
||||||
path:
|
path:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@@ -760,18 +747,18 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_android
|
name: path_provider_android
|
||||||
sha256: "0ca7359dad67fd7063cb2892ab0c0737b2daafd807cf1acecd62374c8fae6c12"
|
sha256: e122c5ea805bb6773bb12ce667611265980940145be920cd09a4b0ec0285cb16
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.16"
|
version: "2.2.20"
|
||||||
path_provider_foundation:
|
path_provider_foundation:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_foundation
|
name: path_provider_foundation
|
||||||
sha256: "4843174df4d288f5e29185bd6e72a6fbdf5a4a4602717eed565497429f179942"
|
sha256: efaec349ddfc181528345c56f8eda9d6cccd71c177511b132c6a0ddaefaa2738
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.4.1"
|
version: "2.4.3"
|
||||||
path_provider_linux:
|
path_provider_linux:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -808,10 +795,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: petitparser
|
name: petitparser
|
||||||
sha256: "07c8f0b1913bcde1ff0d26e57ace2f3012ccbf2b204e070290dad3bb22797646"
|
sha256: "1a97266a94f7350d30ae522c0af07890c70b8e62c71e8e3920d1db4d23c057d1"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.1.0"
|
version: "7.0.1"
|
||||||
platform:
|
platform:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -840,26 +827,26 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: pool
|
name: pool
|
||||||
sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a"
|
sha256: "978783255c543aa3586a1b3c21f6e9d720eb315376a915872c61ef8b5c20177d"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.5.1"
|
version: "1.5.2"
|
||||||
posix:
|
posix:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: posix
|
name: posix
|
||||||
sha256: a0117dc2167805aa9125b82eee515cc891819bac2f538c83646d355b16f58b9a
|
sha256: "6323a5b0fa688b6a010df4905a56b00181479e6d10534cecfecede2aa55add61"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.0.1"
|
version: "6.0.3"
|
||||||
provider:
|
provider:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: provider
|
name: provider
|
||||||
sha256: "489024f942069c2920c844ee18bb3d467c69e48955a4f32d1677f71be103e310"
|
sha256: "4e82183fa20e5ca25703ead7e05de9e4cceed1fbd1eadc1ac3cb6f565a09f272"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.1.4"
|
version: "6.1.5+1"
|
||||||
pub_semver:
|
pub_semver:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -928,18 +915,18 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shared_preferences_android
|
name: shared_preferences_android
|
||||||
sha256: c2c8c46297b5d6a80bed7741ec1f2759742c77d272f1a1698176ae828f8e1a18
|
sha256: "34266009473bf71d748912da4bf62d439185226c03e01e2d9687bc65bbfcb713"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.4.9"
|
version: "2.4.15"
|
||||||
shared_preferences_foundation:
|
shared_preferences_foundation:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shared_preferences_foundation
|
name: shared_preferences_foundation
|
||||||
sha256: "6a52cfcdaeac77cad8c97b539ff688ccfc458c007b4db12be584fbe5c0e49e03"
|
sha256: "1c33a907142607c40a7542768ec9badfd16293bac51da3a4482623d15845f88b"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.5.4"
|
version: "2.5.5"
|
||||||
shared_preferences_linux:
|
shared_preferences_linux:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -984,10 +971,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shelf_web_socket
|
name: shelf_web_socket
|
||||||
sha256: "3632775c8e90d6c9712f883e633716432a27758216dfb61bd86a8321c0580925"
|
sha256: cc36c297b52866d203dbf9332263c94becc2fe0ceaa9681d07b6ef9807023b67
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.0"
|
version: "2.0.1"
|
||||||
sky_engine:
|
sky_engine:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description: flutter
|
description: flutter
|
||||||
@@ -1025,14 +1012,6 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.10.1"
|
version: "1.10.1"
|
||||||
sprintf:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: sprintf
|
|
||||||
sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "7.0.0"
|
|
||||||
stack_trace:
|
stack_trace:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -1077,10 +1056,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: test_api
|
name: test_api
|
||||||
sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd
|
sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.7.4"
|
version: "0.7.6"
|
||||||
timezone:
|
timezone:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -1101,10 +1080,10 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: toastification
|
name: toastification
|
||||||
sha256: "9713989549d60754fd0522425d1251501919cfb7bab4ffbbb36ef40de5ea72b9"
|
sha256: "69db2bff425b484007409650d8bcd5ed1ce2e9666293ece74dcd917dacf23112"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.2"
|
version: "3.0.3"
|
||||||
typed_data:
|
typed_data:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -1117,26 +1096,26 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: url_launcher
|
name: url_launcher
|
||||||
sha256: "9d06212b1362abc2f0f0d78e6f09f726608c74e3b9462e8368bb03314aa8d603"
|
sha256: f6a7e5c4835bb4e3026a04793a4199ca2d14c739ec378fdfe23fc8075d0439f8
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.3.1"
|
version: "6.3.2"
|
||||||
url_launcher_android:
|
url_launcher_android:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: url_launcher_android
|
name: url_launcher_android
|
||||||
sha256: "1d0eae19bd7606ef60fe69ef3b312a437a16549476c42321d5dc1506c9ca3bf4"
|
sha256: "5c8b6c2d89a78f5a1cca70a73d9d5f86c701b36b42f9c9dac7bad592113c28e9"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.3.15"
|
version: "6.3.24"
|
||||||
url_launcher_ios:
|
url_launcher_ios:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: url_launcher_ios
|
name: url_launcher_ios
|
||||||
sha256: "7f2022359d4c099eea7df3fdf739f7d3d3b9faf3166fb1dd390775176e0b76cb"
|
sha256: "6b63f1441e4f653ae799166a72b50b1767321ecc263a57aadf825a7a2a5477d9"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.3.3"
|
version: "6.3.5"
|
||||||
url_launcher_linux:
|
url_launcher_linux:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -1149,10 +1128,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: url_launcher_macos
|
name: url_launcher_macos
|
||||||
sha256: "17ba2000b847f334f16626a574c702b196723af2a289e7a93ffcb79acff855c2"
|
sha256: "8262208506252a3ed4ff5c0dc1e973d2c0e0ef337d0a074d35634da5d44397c9"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.2.2"
|
version: "3.2.4"
|
||||||
url_launcher_platform_interface:
|
url_launcher_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -1165,10 +1144,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: url_launcher_web
|
name: url_launcher_web
|
||||||
sha256: "3ba963161bd0fe395917ba881d320b9c4f6dd3c4a233da62ab18a5025c85f1e9"
|
sha256: "4bd2b7b4dc4d4d0b94e5babfffbca8eac1a126c7f3d6ecbc1a11013faa3abba2"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.4.0"
|
version: "2.4.1"
|
||||||
url_launcher_windows:
|
url_launcher_windows:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -1181,34 +1160,34 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: uuid
|
name: uuid
|
||||||
sha256: a5be9ef6618a7ac1e964353ef476418026db906c4facdedaa299b7a2e71690ff
|
sha256: a11b666489b1954e01d992f3d601b1804a33937b5a8fe677bd26b8a9f96f96e8
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.5.1"
|
version: "4.5.2"
|
||||||
vector_math:
|
vector_math:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: vector_math
|
name: vector_math
|
||||||
sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
|
sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.4"
|
version: "2.2.0"
|
||||||
vm_service:
|
vm_service:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: vm_service
|
name: vm_service
|
||||||
sha256: "0968250880a6c5fe7edc067ed0a13d4bae1577fe2771dcf3010d52c4a9d3ca14"
|
sha256: "45caa6c5917fa127b5dbcfbd1fa60b14e583afdc08bfc96dda38886ca252eb60"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "14.3.1"
|
version: "15.0.2"
|
||||||
watcher:
|
watcher:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: watcher
|
name: watcher
|
||||||
sha256: "69da27e49efa56a15f8afe8f4438c4ec02eff0a117df1b22ea4aad194fe1c104"
|
sha256: "592ab6e2892f67760543fb712ff0177f4ec76c031f02f5b4ff8d3fc5eb9fb61a"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.1"
|
version: "1.1.4"
|
||||||
web:
|
web:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -1221,26 +1200,26 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: web_socket
|
name: web_socket
|
||||||
sha256: "3c12d96c0c9a4eec095246debcea7b86c0324f22df69893d538fcc6f1b8cce83"
|
sha256: "34d64019aa8e36bf9842ac014bb5d2f5586ca73df5e4d9bf5c936975cae6982c"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.1.6"
|
version: "1.0.1"
|
||||||
web_socket_channel:
|
web_socket_channel:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: web_socket_channel
|
name: web_socket_channel
|
||||||
sha256: "0b8e2457400d8a859b7b2030786835a28a8e80836ef64402abef392ff4f1d0e5"
|
sha256: d645757fb0f4773d602444000a8131ff5d48c9e47adfe9772652dd1a4f2d45c8
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.2"
|
version: "3.0.3"
|
||||||
win32:
|
win32:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: win32
|
name: win32
|
||||||
sha256: dc6ecaa00a7c708e5b4d10ee7bec8c270e9276dfcab1783f57e9962d7884305f
|
sha256: d7cb55e04cd34096cd3a79b3330245f54cb96a370a1c27adb3c84b917de8b08e
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.12.0"
|
version: "5.15.0"
|
||||||
win32_registry:
|
win32_registry:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -1269,10 +1248,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: xml
|
name: xml
|
||||||
sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226
|
sha256: "971043b3a0d3da28727e40ed3e0b5d18b742fa5a68665cca88e74b7876d5e025"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.5.0"
|
version: "6.6.1"
|
||||||
yaml:
|
yaml:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -1282,5 +1261,5 @@ packages:
|
|||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.3"
|
version: "3.1.3"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=3.7.0 <4.0.0"
|
dart: ">=3.9.0 <4.0.0"
|
||||||
flutter: ">=3.27.0"
|
flutter: ">=3.35.0"
|
||||||
|
|||||||
@@ -2,10 +2,10 @@ name: simplecloudnotifier
|
|||||||
description: "Receive push messages"
|
description: "Receive push messages"
|
||||||
publish_to: 'none'
|
publish_to: 'none'
|
||||||
|
|
||||||
version: 2.0.1+492
|
version: 2.1.0+509
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: '>=3.2.6 <4.0.0'
|
sdk: '>=3.9.0 <4.0.0'
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
flutter:
|
flutter:
|
||||||
|
|||||||
2
scnserver/.gitignore
vendored
@@ -18,6 +18,8 @@ identifier.sqlite
|
|||||||
|
|
||||||
.idea/dataSources.xml
|
.idea/dataSources.xml
|
||||||
|
|
||||||
|
.idea/copilot*
|
||||||
|
|
||||||
.swaggobin
|
.swaggobin
|
||||||
|
|
||||||
scn_send.sh
|
scn_send.sh
|
||||||
|
|||||||
@@ -1,19 +1,20 @@
|
|||||||
package handler
|
package handler
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"blackforestbytes.com/simplecloudnotifier/api/apierr"
|
"blackforestbytes.com/simplecloudnotifier/api/apierr"
|
||||||
"blackforestbytes.com/simplecloudnotifier/api/ginresp"
|
"blackforestbytes.com/simplecloudnotifier/api/ginresp"
|
||||||
ct "blackforestbytes.com/simplecloudnotifier/db/cursortoken"
|
ct "blackforestbytes.com/simplecloudnotifier/db/cursortoken"
|
||||||
"blackforestbytes.com/simplecloudnotifier/logic"
|
"blackforestbytes.com/simplecloudnotifier/logic"
|
||||||
"blackforestbytes.com/simplecloudnotifier/models"
|
"blackforestbytes.com/simplecloudnotifier/models"
|
||||||
"database/sql"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"git.blackforestbytes.com/BlackForestBytes/goext/ginext"
|
"git.blackforestbytes.com/BlackForestBytes/goext/ginext"
|
||||||
"git.blackforestbytes.com/BlackForestBytes/goext/langext"
|
"git.blackforestbytes.com/BlackForestBytes/goext/langext"
|
||||||
"git.blackforestbytes.com/BlackForestBytes/goext/mathext"
|
"git.blackforestbytes.com/BlackForestBytes/goext/mathext"
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ListChannels swaggerdoc
|
// ListChannels swaggerdoc
|
||||||
@@ -487,7 +488,7 @@ func (h APIHandler) ListChannelMessages(pctx ginext.PreContext) ginext.HTTPRespo
|
|||||||
// @Failure 404 {object} ginresp.apiError "channel not found"
|
// @Failure 404 {object} ginresp.apiError "channel not found"
|
||||||
// @Failure 500 {object} ginresp.apiError "internal server error"
|
// @Failure 500 {object} ginresp.apiError "internal server error"
|
||||||
//
|
//
|
||||||
// @Router /api/v2/users/{uid}/channels/{cid} [PATCH]
|
// @Router /api/v2/users/{uid}/channels/{cid} [DELETE]
|
||||||
func (h APIHandler) DeleteChannel(pctx ginext.PreContext) ginext.HTTPResponse {
|
func (h APIHandler) DeleteChannel(pctx ginext.PreContext) ginext.HTTPResponse {
|
||||||
type uri struct {
|
type uri struct {
|
||||||
UserID models.UserID `uri:"uid" binding:"entityid"`
|
UserID models.UserID `uri:"uid" binding:"entityid"`
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
package handler
|
package handler
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
"blackforestbytes.com/simplecloudnotifier/api/apierr"
|
"blackforestbytes.com/simplecloudnotifier/api/apierr"
|
||||||
"blackforestbytes.com/simplecloudnotifier/api/ginresp"
|
"blackforestbytes.com/simplecloudnotifier/api/ginresp"
|
||||||
"blackforestbytes.com/simplecloudnotifier/logic"
|
"blackforestbytes.com/simplecloudnotifier/logic"
|
||||||
"blackforestbytes.com/simplecloudnotifier/models"
|
"blackforestbytes.com/simplecloudnotifier/models"
|
||||||
"git.blackforestbytes.com/BlackForestBytes/goext/ginext"
|
"git.blackforestbytes.com/BlackForestBytes/goext/ginext"
|
||||||
"net/http"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ListUserSenderNames swaggerdoc
|
// ListUserSenderNames swaggerdoc
|
||||||
@@ -23,7 +24,7 @@ import (
|
|||||||
// @Failure 404 {object} ginresp.apiError "message not found"
|
// @Failure 404 {object} ginresp.apiError "message not found"
|
||||||
// @Failure 500 {object} ginresp.apiError "internal server error"
|
// @Failure 500 {object} ginresp.apiError "internal server error"
|
||||||
//
|
//
|
||||||
// @Router /api/v2/users/{uid}/keys [GET]
|
// @Router /api/v2/users/{uid}/sender-names [GET]
|
||||||
func (h APIHandler) ListUserSenderNames(pctx ginext.PreContext) ginext.HTTPResponse {
|
func (h APIHandler) ListUserSenderNames(pctx ginext.PreContext) ginext.HTTPResponse {
|
||||||
type uri struct {
|
type uri struct {
|
||||||
UserID models.UserID `uri:"uid" binding:"entityid"`
|
UserID models.UserID `uri:"uid" binding:"entityid"`
|
||||||
|
|||||||
@@ -1,18 +1,19 @@
|
|||||||
package handler
|
package handler
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
"net/http"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"blackforestbytes.com/simplecloudnotifier/api/ginresp"
|
"blackforestbytes.com/simplecloudnotifier/api/ginresp"
|
||||||
"blackforestbytes.com/simplecloudnotifier/logic"
|
"blackforestbytes.com/simplecloudnotifier/logic"
|
||||||
"blackforestbytes.com/simplecloudnotifier/models"
|
"blackforestbytes.com/simplecloudnotifier/models"
|
||||||
"blackforestbytes.com/simplecloudnotifier/website"
|
"blackforestbytes.com/simplecloudnotifier/website"
|
||||||
"errors"
|
|
||||||
"git.blackforestbytes.com/BlackForestBytes/goext/ginext"
|
"git.blackforestbytes.com/BlackForestBytes/goext/ginext"
|
||||||
"git.blackforestbytes.com/BlackForestBytes/goext/rext"
|
"git.blackforestbytes.com/BlackForestBytes/goext/rext"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
"net/http"
|
|
||||||
"regexp"
|
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type WebsiteHandler struct {
|
type WebsiteHandler struct {
|
||||||
@@ -77,6 +78,18 @@ func (h WebsiteHandler) MessageSent(pctx ginext.PreContext) ginext.HTTPResponse
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h WebsiteHandler) PrivacyPolicy(pctx ginext.PreContext) ginext.HTTPResponse {
|
||||||
|
ctx, g, errResp := pctx.Start()
|
||||||
|
if errResp != nil {
|
||||||
|
return *errResp
|
||||||
|
}
|
||||||
|
defer ctx.Cancel()
|
||||||
|
|
||||||
|
return h.app.DoRequest(ctx, g, models.TLockNone, func(ctx *logic.AppContext, finishSuccess func(r ginext.HTTPResponse) ginext.HTTPResponse) ginext.HTTPResponse {
|
||||||
|
return h.serveAsset(g, "privacy_policy.html", true)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (h WebsiteHandler) FaviconIco(pctx ginext.PreContext) ginext.HTTPResponse {
|
func (h WebsiteHandler) FaviconIco(pctx ginext.PreContext) ginext.HTTPResponse {
|
||||||
ctx, g, errResp := pctx.Start()
|
ctx, g, errResp := pctx.Start()
|
||||||
if errResp != nil {
|
if errResp != nil {
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
"blackforestbytes.com/simplecloudnotifier/api/handler"
|
"blackforestbytes.com/simplecloudnotifier/api/handler"
|
||||||
"blackforestbytes.com/simplecloudnotifier/logic"
|
"blackforestbytes.com/simplecloudnotifier/logic"
|
||||||
"blackforestbytes.com/simplecloudnotifier/models"
|
"blackforestbytes.com/simplecloudnotifier/models"
|
||||||
"blackforestbytes.com/simplecloudnotifier/swagger"
|
"blackforestbytes.com/simplecloudnotifier/swagger"
|
||||||
"errors"
|
|
||||||
"git.blackforestbytes.com/BlackForestBytes/goext/ginext"
|
"git.blackforestbytes.com/BlackForestBytes/goext/ginext"
|
||||||
"github.com/gin-gonic/gin/binding"
|
"github.com/gin-gonic/gin/binding"
|
||||||
"github.com/go-playground/validator/v10"
|
"github.com/go-playground/validator/v10"
|
||||||
@@ -98,6 +99,10 @@ func (r *Router) Init(e *ginext.GinWrapper) error {
|
|||||||
frontend.GET("/message_sent.php").Handle(r.websiteHandler.MessageSent)
|
frontend.GET("/message_sent.php").Handle(r.websiteHandler.MessageSent)
|
||||||
frontend.GET("/message_sent.html").Handle(r.websiteHandler.MessageSent)
|
frontend.GET("/message_sent.html").Handle(r.websiteHandler.MessageSent)
|
||||||
|
|
||||||
|
frontend.GET("/privacy_policy").Handle(r.websiteHandler.PrivacyPolicy)
|
||||||
|
frontend.GET("/privacy_policy.php").Handle(r.websiteHandler.PrivacyPolicy)
|
||||||
|
frontend.GET("/privacy_policy.html").Handle(r.websiteHandler.PrivacyPolicy)
|
||||||
|
|
||||||
frontend.GET("/favicon.ico").Handle(r.websiteHandler.FaviconIco)
|
frontend.GET("/favicon.ico").Handle(r.websiteHandler.FaviconIco)
|
||||||
frontend.GET("/favicon.png").Handle(r.websiteHandler.FaviconPNG)
|
frontend.GET("/favicon.png").Handle(r.websiteHandler.FaviconPNG)
|
||||||
|
|
||||||
|
|||||||
@@ -1656,7 +1656,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"patch": {
|
"delete": {
|
||||||
"tags": [
|
"tags": [
|
||||||
"API-v2"
|
"API-v2"
|
||||||
],
|
],
|
||||||
@@ -1710,6 +1710,85 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"patch": {
|
||||||
|
"tags": [
|
||||||
|
"API-v2"
|
||||||
|
],
|
||||||
|
"summary": "(Partially) update a channel",
|
||||||
|
"operationId": "api-channels-update",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "UserID",
|
||||||
|
"name": "uid",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "ChannelID",
|
||||||
|
"name": "cid",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Send `true` to create a new subscribe_key",
|
||||||
|
"name": "subscribe_key",
|
||||||
|
"in": "body",
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Send `true` to create a new send_key",
|
||||||
|
"name": "send_key",
|
||||||
|
"in": "body",
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Change the cahnnel display-name (only chnages to lowercase/uppercase are allowed - internal_name must stay the same)",
|
||||||
|
"name": "display_name",
|
||||||
|
"in": "body",
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/models.ChannelWithSubscription"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "supplied values/parameters cannot be parsed / are invalid",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/ginresp.apiError"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"401": {
|
||||||
|
"description": "user is not authorized / has missing permissions",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/ginresp.apiError"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"404": {
|
||||||
|
"description": "channel not found",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/ginresp.apiError"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "internal server error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/ginresp.apiError"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/api/v2/users/{uid}/channels/{cid}/messages": {
|
"/api/v2/users/{uid}/channels/{cid}/messages": {
|
||||||
@@ -2122,11 +2201,12 @@
|
|||||||
},
|
},
|
||||||
"/api/v2/users/{uid}/keys": {
|
"/api/v2/users/{uid}/keys": {
|
||||||
"get": {
|
"get": {
|
||||||
|
"description": "The request must be done with an ADMIN key, the returned keys are without their token.",
|
||||||
"tags": [
|
"tags": [
|
||||||
"API-v2"
|
"API-v2"
|
||||||
],
|
],
|
||||||
"summary": "List sender-names (of allthe messages of this user)",
|
"summary": "List keys of the user",
|
||||||
"operationId": "api-usersendernames-list",
|
"operationId": "api-tokenkeys-list",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "string",
|
||||||
@@ -2461,6 +2541,56 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/api/v2/users/{uid}/sender-names": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"API-v2"
|
||||||
|
],
|
||||||
|
"summary": "List sender-names (of allthe messages of this user)",
|
||||||
|
"operationId": "api-usersendernames-list",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "UserID",
|
||||||
|
"name": "uid",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/handler.ListUserKeys.response"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "supplied values/parameters cannot be parsed / are invalid",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/ginresp.apiError"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"401": {
|
||||||
|
"description": "user is not authorized / has missing permissions",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/ginresp.apiError"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"404": {
|
||||||
|
"description": "message not found",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/ginresp.apiError"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "internal server error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/ginresp.apiError"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/api/v2/users/{uid}/subscriptions": {
|
"/api/v2/users/{uid}/subscriptions": {
|
||||||
"get": {
|
"get": {
|
||||||
"description": "The possible values for 'direction' are:\n- \"outgoing\" Subscriptions with the user as subscriber (= subscriptions he can use to read channels)\n- \"incoming\" Subscriptions to channels of this user (= incoming subscriptions and subscription requests)\n- \"both\" Combines \"outgoing\" and \"incoming\" (default)\n\nThe possible values for 'confirmation' are:\n- \"confirmed\" Confirmed (active) subscriptions\n- \"unconfirmed\" Unconfirmed (pending) subscriptions\n- \"all\" Combines \"confirmed\" and \"unconfirmed\" (default)\n\nThe possible values for 'external' are:\n- \"true\" Subscriptions with subscriber_user_id != channel_owner_user_id (subscriptions from other users)\n- \"false\" Subscriptions with subscriber_user_id == channel_owner_user_id (subscriptions from this user to his own channels)\n- \"all\" Combines \"external\" and \"internal\" (default)\n\nThe `subscriber_user_id` parameter can be used to additionally filter the subscriber_user_id (return subscribtions from a specific user)\n\nThe `channel_owner_user_id` parameter can be used to additionally filter the channel_owner_user_id (return subscribtions to a specific user)",
|
"description": "The possible values for 'direction' are:\n- \"outgoing\" Subscriptions with the user as subscriber (= subscriptions he can use to read channels)\n- \"incoming\" Subscriptions to channels of this user (= incoming subscriptions and subscription requests)\n- \"both\" Combines \"outgoing\" and \"incoming\" (default)\n\nThe possible values for 'confirmation' are:\n- \"confirmed\" Confirmed (active) subscriptions\n- \"unconfirmed\" Unconfirmed (pending) subscriptions\n- \"all\" Combines \"confirmed\" and \"unconfirmed\" (default)\n\nThe possible values for 'external' are:\n- \"true\" Subscriptions with subscriber_user_id != channel_owner_user_id (subscriptions from other users)\n- \"false\" Subscriptions with subscriber_user_id == channel_owner_user_id (subscriptions from this user to his own channels)\n- \"all\" Combines \"external\" and \"internal\" (default)\n\nThe `subscriber_user_id` parameter can be used to additionally filter the subscriber_user_id (return subscribtions from a specific user)\n\nThe `channel_owner_user_id` parameter can be used to additionally filter the channel_owner_user_id (return subscribtions to a specific user)",
|
||||||
|
|||||||
@@ -1954,6 +1954,43 @@ paths:
|
|||||||
tags:
|
tags:
|
||||||
- API-v2
|
- API-v2
|
||||||
/api/v2/users/{uid}/channels/{cid}:
|
/api/v2/users/{uid}/channels/{cid}:
|
||||||
|
delete:
|
||||||
|
operationId: api-channels-delete
|
||||||
|
parameters:
|
||||||
|
- description: UserID
|
||||||
|
in: path
|
||||||
|
name: uid
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
- description: ChannelID
|
||||||
|
in: path
|
||||||
|
name: cid
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/models.Channel'
|
||||||
|
"400":
|
||||||
|
description: supplied values/parameters cannot be parsed / are invalid
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/ginresp.apiError'
|
||||||
|
"401":
|
||||||
|
description: user is not authorized / has missing permissions
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/ginresp.apiError'
|
||||||
|
"404":
|
||||||
|
description: channel not found
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/ginresp.apiError'
|
||||||
|
"500":
|
||||||
|
description: internal server error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/ginresp.apiError'
|
||||||
|
summary: delete a channel (including all messages, subscriptions, etc)
|
||||||
|
tags:
|
||||||
|
- API-v2
|
||||||
get:
|
get:
|
||||||
operationId: api-channels-get
|
operationId: api-channels-get
|
||||||
parameters:
|
parameters:
|
||||||
@@ -1992,7 +2029,7 @@ paths:
|
|||||||
tags:
|
tags:
|
||||||
- API-v2
|
- API-v2
|
||||||
patch:
|
patch:
|
||||||
operationId: api-channels-delete
|
operationId: api-channels-update
|
||||||
parameters:
|
parameters:
|
||||||
- description: UserID
|
- description: UserID
|
||||||
in: path
|
in: path
|
||||||
@@ -2004,11 +2041,27 @@ paths:
|
|||||||
name: cid
|
name: cid
|
||||||
required: true
|
required: true
|
||||||
type: string
|
type: string
|
||||||
|
- description: Send `true` to create a new subscribe_key
|
||||||
|
in: body
|
||||||
|
name: subscribe_key
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- description: Send `true` to create a new send_key
|
||||||
|
in: body
|
||||||
|
name: send_key
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- description: Change the cahnnel display-name (only chnages to lowercase/uppercase
|
||||||
|
are allowed - internal_name must stay the same)
|
||||||
|
in: body
|
||||||
|
name: display_name
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
description: OK
|
description: OK
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/models.Channel'
|
$ref: '#/definitions/models.ChannelWithSubscription'
|
||||||
"400":
|
"400":
|
||||||
description: supplied values/parameters cannot be parsed / are invalid
|
description: supplied values/parameters cannot be parsed / are invalid
|
||||||
schema:
|
schema:
|
||||||
@@ -2025,7 +2078,7 @@ paths:
|
|||||||
description: internal server error
|
description: internal server error
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/ginresp.apiError'
|
$ref: '#/definitions/ginresp.apiError'
|
||||||
summary: delete a channel (including all messages, subscriptions, etc)
|
summary: (Partially) update a channel
|
||||||
tags:
|
tags:
|
||||||
- API-v2
|
- API-v2
|
||||||
/api/v2/users/{uid}/channels/{cid}/messages:
|
/api/v2/users/{uid}/channels/{cid}/messages:
|
||||||
@@ -2305,7 +2358,9 @@ paths:
|
|||||||
- API-v2
|
- API-v2
|
||||||
/api/v2/users/{uid}/keys:
|
/api/v2/users/{uid}/keys:
|
||||||
get:
|
get:
|
||||||
operationId: api-usersendernames-list
|
description: The request must be done with an ADMIN key, the returned keys are
|
||||||
|
without their token.
|
||||||
|
operationId: api-tokenkeys-list
|
||||||
parameters:
|
parameters:
|
||||||
- description: UserID
|
- description: UserID
|
||||||
in: path
|
in: path
|
||||||
@@ -2333,7 +2388,7 @@ paths:
|
|||||||
description: internal server error
|
description: internal server error
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/ginresp.apiError'
|
$ref: '#/definitions/ginresp.apiError'
|
||||||
summary: List sender-names (of allthe messages of this user)
|
summary: List keys of the user
|
||||||
tags:
|
tags:
|
||||||
- API-v2
|
- API-v2
|
||||||
post:
|
post:
|
||||||
@@ -2533,6 +2588,39 @@ paths:
|
|||||||
summary: Get the key currently used by this request
|
summary: Get the key currently used by this request
|
||||||
tags:
|
tags:
|
||||||
- API-v2
|
- API-v2
|
||||||
|
/api/v2/users/{uid}/sender-names:
|
||||||
|
get:
|
||||||
|
operationId: api-usersendernames-list
|
||||||
|
parameters:
|
||||||
|
- description: UserID
|
||||||
|
in: path
|
||||||
|
name: uid
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/handler.ListUserKeys.response'
|
||||||
|
"400":
|
||||||
|
description: supplied values/parameters cannot be parsed / are invalid
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/ginresp.apiError'
|
||||||
|
"401":
|
||||||
|
description: user is not authorized / has missing permissions
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/ginresp.apiError'
|
||||||
|
"404":
|
||||||
|
description: message not found
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/ginresp.apiError'
|
||||||
|
"500":
|
||||||
|
description: internal server error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/ginresp.apiError'
|
||||||
|
summary: List sender-names (of allthe messages of this user)
|
||||||
|
tags:
|
||||||
|
- API-v2
|
||||||
/api/v2/users/{uid}/subscriptions:
|
/api/v2/users/{uid}/subscriptions:
|
||||||
get:
|
get:
|
||||||
description: |-
|
description: |-
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
<form id="mainpnl">
|
<form id="mainpnl">
|
||||||
|
|
||||||
<a tabindex="-1" href="https://play.google.com/store/apps/details?id=com.blackforestbytes.simplecloudnotifier" class="button bordered edge-btn" id="tl_link1"><span class="icn-google-play"></span></a>
|
<a tabindex="-1" href="https://play.google.com/store/apps/details?id=com.blackforestbytes.simplecloudnotifier" class="button bordered edge-btn" id="tl_link1"><span class="icn-google-play"></span></a>
|
||||||
<a tabindex="-1" href="#" class="button bordered edge-btn" id="tl_link2"><span class="icn-app-store"></span></a>
|
<a tabindex="-1" href="https://apps.apple.com/us/app/simplecloudnotifier/id6455594868" class="button bordered edge-btn" id="tl_link2"><span class="icn-app-store"></span></a>
|
||||||
|
|
||||||
<a tabindex="-1" href="/api" class="button bordered edge-btn" id="tr_link">API</a>
|
<a tabindex="-1" href="/api" class="button bordered edge-btn" id="tr_link">API</a>
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
<div id="mainpnl">
|
<div id="mainpnl">
|
||||||
|
|
||||||
<a tabindex="-1" href="https://play.google.com/store/apps/details?id=com.blackforestbytes.simplecloudnotifier" class="button bordered edge-btn" id="tl_link1"><span class="icn-google-play"></span></a>
|
<a tabindex="-1" href="https://play.google.com/store/apps/details?id=com.blackforestbytes.simplecloudnotifier" class="button bordered edge-btn" id="tl_link1"><span class="icn-google-play"></span></a>
|
||||||
<a tabindex="-1" href="#" class="button bordered edge-btn" id="tl_link2"><span class="icn-app-store"></span></a>
|
<a tabindex="-1" href="https://apps.apple.com/us/app/simplecloudnotifier/id6455594868" class="button bordered edge-btn" id="tl_link2"><span class="icn-app-store"></span></a>
|
||||||
|
|
||||||
<a tabindex="-1" href="/" class="button bordered edge-btn" id="tr_link">Send</a>
|
<a tabindex="-1" href="/" class="button bordered edge-btn" id="tr_link">Send</a>
|
||||||
|
|
||||||
|
|||||||
54
scnserver/website/privacy_policy.html
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
{{template|header.[theme].html}}
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div id="copyinfo">
|
||||||
|
<a tabindex="-1" href="https://www.blackforestbytes.com">© blackforestbytes</a>
|
||||||
|
<a tabindex="-1" href="https://www.mikescher.com">made by Mike Schwörer</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{template|theme_switch.[theme].html}}
|
||||||
|
|
||||||
|
<div id="mainpnl">
|
||||||
|
|
||||||
|
<strong>Privacy Policy</strong>
|
||||||
|
<p>This privacy policy applies to the SimpleCloudNotifier app (hereby referred to as "Application") for mobile devices that was created by blackforestbytes GmbH (hereby referred to as "Service Provider") as a Free service. This service is intended for use "AS IS".</p>
|
||||||
|
<br>
|
||||||
|
<strong>What information does the Application obtain and how is it used?</strong>
|
||||||
|
<p>The Application does not obtain any information when you download and use it. Registration is not required to use the Application.</p>
|
||||||
|
<br>
|
||||||
|
<strong>Does the Application collect precise real time location information of the device?</strong>
|
||||||
|
<p>This Application does not collect precise information about the location of your mobile device.</p>
|
||||||
|
<br>
|
||||||
|
<strong>Do third parties see and/or have access to information obtained by the Application?</strong>
|
||||||
|
<p>Since the Application does not collect any information, no data is shared with third parties.</p>
|
||||||
|
<br>
|
||||||
|
<strong>What are my opt-out rights?</strong>
|
||||||
|
<p>You can stop all collection of information by the Application easily by uninstalling it. You may use the standard uninstall processes as may be available as part of your mobile device or via the mobile application marketplace or network.</p>
|
||||||
|
<br>
|
||||||
|
<strong>Children</strong>
|
||||||
|
<p>The Application is not used to knowingly solicit data from or market to children under the age of 13.</p>
|
||||||
|
<br>
|
||||||
|
<p>The Service Provider does not knowingly collect personally identifiable information from children. The Service Provider encourages all children to never submit any personally identifiable information through the Application and/or Services. The Service Provider encourage parents and legal guardians to monitor their children's Internet usage and to help enforce this Policy by instructing their children never to provide personally identifiable information through the Application and/or Services without their permission. If you have reason to believe that a child has provided personally identifiable information to the Service Provider through the Application and/or Services, please contact the Service Provider (playstore_scn@blackforestbytes.de) so that they will be able to take the necessary actions. You must also be at least 16 years of age to consent to the processing of your personally identifiable information in your country (in some countries we may allow your parent or guardian to do so on your behalf).</p>
|
||||||
|
<br>
|
||||||
|
<strong>Security</strong>
|
||||||
|
<p>The Service Provider is concerned about safeguarding the confidentiality of your information. However, since the Application does not collect any information, there is no risk of your data being accessed by unauthorized individuals.</p>
|
||||||
|
<br>
|
||||||
|
<strong>Changes</strong>
|
||||||
|
<p>This Privacy Policy may be updated from time to time for any reason. The Service Provider will notify you of any changes to their Privacy Policy by updating this page with the new Privacy Policy. You are advised to consult this Privacy Policy regularly for any changes, as continued use is deemed approval of all changes.</p>
|
||||||
|
<br>
|
||||||
|
<p>This privacy policy is effective as of 2025-11-10</p>
|
||||||
|
<br>
|
||||||
|
<strong>Your Consent</strong>
|
||||||
|
<p>By using the Application, you are consenting to the processing of your information as set forth in this Privacy Policy now and as amended by the Service Provider.</p>
|
||||||
|
<br><strong>Contact Us</strong>
|
||||||
|
<p>If you have any questions regarding privacy while using the Application, or have questions about the practices, please contact the Service Provider via email at playstore_scn@blackforestbytes.de.</p>
|
||||||
|
<hr>
|
||||||
|
<p>This privacy policy page was generated by <a href="https://app-privacy-policy-generator.nisrulz.com/" target="_blank" rel="noopener noreferrer">App Privacy Policy Generator</a></p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
BIN
store/appicon_2.0.png
Normal file
|
After Width: | Height: | Size: 90 KiB |
BIN
store/appicon_2.0_512x.png
Normal file
|
After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 85 KiB After Width: | Height: | Size: 158 KiB |
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 193 KiB |
|
Before Width: | Height: | Size: 55 KiB After Width: | Height: | Size: 77 KiB |
BIN
store/screenshot_4.png
Normal file
|
After Width: | Height: | Size: 53 KiB |
BIN
store/screenshot_old_1.png
Normal file
|
After Width: | Height: | Size: 85 KiB |
BIN
store/screenshot_old_2.png
Normal file
|
After Width: | Height: | Size: 46 KiB |
BIN
store/screenshot_old_3.png
Normal file
|
After Width: | Height: | Size: 55 KiB |