Compare commits
6 Commits
develop
...
flutter_ap
Author | SHA1 | Date | |
---|---|---|---|
9c53cc52e9
|
|||
e6709cd4af
|
|||
cdb92757aa
|
|||
3c5da802a7
|
|||
05e2fcf185
|
|||
8ebd95a4b8
|
6
android/.idea/AndroidProjectSystem.xml
generated
Normal file
6
android/.idea/AndroidProjectSystem.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="AndroidProjectSystem">
|
||||||
|
<option name="providerId" value="com.android.tools.idea.GradleProjectSystem" />
|
||||||
|
</component>
|
||||||
|
</project>
|
263
android/.idea/other.xml
generated
263
android/.idea/other.xml
generated
@@ -1,263 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="direct_access_persist.xml">
|
|
||||||
<option name="deviceSelectionList">
|
|
||||||
<list>
|
|
||||||
<PersistentDeviceSelectionData>
|
|
||||||
<option name="api" value="27" />
|
|
||||||
<option name="brand" value="DOCOMO" />
|
|
||||||
<option name="codename" value="F01L" />
|
|
||||||
<option name="id" value="F01L" />
|
|
||||||
<option name="manufacturer" value="FUJITSU" />
|
|
||||||
<option name="name" value="F-01L" />
|
|
||||||
<option name="screenDensity" value="360" />
|
|
||||||
<option name="screenX" value="720" />
|
|
||||||
<option name="screenY" value="1280" />
|
|
||||||
</PersistentDeviceSelectionData>
|
|
||||||
<PersistentDeviceSelectionData>
|
|
||||||
<option name="api" value="28" />
|
|
||||||
<option name="brand" value="DOCOMO" />
|
|
||||||
<option name="codename" value="SH-01L" />
|
|
||||||
<option name="id" value="SH-01L" />
|
|
||||||
<option name="manufacturer" value="SHARP" />
|
|
||||||
<option name="name" value="AQUOS sense2 SH-01L" />
|
|
||||||
<option name="screenDensity" value="480" />
|
|
||||||
<option name="screenX" value="1080" />
|
|
||||||
<option name="screenY" value="2160" />
|
|
||||||
</PersistentDeviceSelectionData>
|
|
||||||
<PersistentDeviceSelectionData>
|
|
||||||
<option name="api" value="31" />
|
|
||||||
<option name="brand" value="samsung" />
|
|
||||||
<option name="codename" value="a51" />
|
|
||||||
<option name="id" value="a51" />
|
|
||||||
<option name="manufacturer" value="Samsung" />
|
|
||||||
<option name="name" value="Galaxy A51" />
|
|
||||||
<option name="screenDensity" value="420" />
|
|
||||||
<option name="screenX" value="1080" />
|
|
||||||
<option name="screenY" value="2400" />
|
|
||||||
</PersistentDeviceSelectionData>
|
|
||||||
<PersistentDeviceSelectionData>
|
|
||||||
<option name="api" value="34" />
|
|
||||||
<option name="brand" value="google" />
|
|
||||||
<option name="codename" value="akita" />
|
|
||||||
<option name="id" value="akita" />
|
|
||||||
<option name="manufacturer" value="Google" />
|
|
||||||
<option name="name" value="Pixel 8a" />
|
|
||||||
<option name="screenDensity" value="420" />
|
|
||||||
<option name="screenX" value="1080" />
|
|
||||||
<option name="screenY" value="2400" />
|
|
||||||
</PersistentDeviceSelectionData>
|
|
||||||
<PersistentDeviceSelectionData>
|
|
||||||
<option name="api" value="33" />
|
|
||||||
<option name="brand" value="samsung" />
|
|
||||||
<option name="codename" value="b0q" />
|
|
||||||
<option name="id" value="b0q" />
|
|
||||||
<option name="manufacturer" value="Samsung" />
|
|
||||||
<option name="name" value="Galaxy S22 Ultra" />
|
|
||||||
<option name="screenDensity" value="600" />
|
|
||||||
<option name="screenX" value="1440" />
|
|
||||||
<option name="screenY" value="3088" />
|
|
||||||
</PersistentDeviceSelectionData>
|
|
||||||
<PersistentDeviceSelectionData>
|
|
||||||
<option name="api" value="32" />
|
|
||||||
<option name="brand" value="google" />
|
|
||||||
<option name="codename" value="bluejay" />
|
|
||||||
<option name="id" value="bluejay" />
|
|
||||||
<option name="manufacturer" value="Google" />
|
|
||||||
<option name="name" value="Pixel 6a" />
|
|
||||||
<option name="screenDensity" value="420" />
|
|
||||||
<option name="screenX" value="1080" />
|
|
||||||
<option name="screenY" value="2400" />
|
|
||||||
</PersistentDeviceSelectionData>
|
|
||||||
<PersistentDeviceSelectionData>
|
|
||||||
<option name="api" value="29" />
|
|
||||||
<option name="brand" value="samsung" />
|
|
||||||
<option name="codename" value="crownqlteue" />
|
|
||||||
<option name="id" value="crownqlteue" />
|
|
||||||
<option name="manufacturer" value="Samsung" />
|
|
||||||
<option name="name" value="Galaxy Note9" />
|
|
||||||
<option name="screenDensity" value="420" />
|
|
||||||
<option name="screenX" value="2220" />
|
|
||||||
<option name="screenY" value="1080" />
|
|
||||||
</PersistentDeviceSelectionData>
|
|
||||||
<PersistentDeviceSelectionData>
|
|
||||||
<option name="api" value="34" />
|
|
||||||
<option name="brand" value="samsung" />
|
|
||||||
<option name="codename" value="dm3q" />
|
|
||||||
<option name="id" value="dm3q" />
|
|
||||||
<option name="manufacturer" value="Samsung" />
|
|
||||||
<option name="name" value="Galaxy S23 Ultra" />
|
|
||||||
<option name="screenDensity" value="600" />
|
|
||||||
<option name="screenX" value="1440" />
|
|
||||||
<option name="screenY" value="3088" />
|
|
||||||
</PersistentDeviceSelectionData>
|
|
||||||
<PersistentDeviceSelectionData>
|
|
||||||
<option name="api" value="33" />
|
|
||||||
<option name="brand" value="google" />
|
|
||||||
<option name="codename" value="felix" />
|
|
||||||
<option name="id" value="felix" />
|
|
||||||
<option name="manufacturer" value="Google" />
|
|
||||||
<option name="name" value="Pixel Fold" />
|
|
||||||
<option name="screenDensity" value="420" />
|
|
||||||
<option name="screenX" value="2208" />
|
|
||||||
<option name="screenY" value="1840" />
|
|
||||||
</PersistentDeviceSelectionData>
|
|
||||||
<PersistentDeviceSelectionData>
|
|
||||||
<option name="api" value="33" />
|
|
||||||
<option name="brand" value="google" />
|
|
||||||
<option name="codename" value="felix_camera" />
|
|
||||||
<option name="id" value="felix_camera" />
|
|
||||||
<option name="manufacturer" value="Google" />
|
|
||||||
<option name="name" value="Pixel Fold (Camera-enabled)" />
|
|
||||||
<option name="screenDensity" value="420" />
|
|
||||||
<option name="screenX" value="2208" />
|
|
||||||
<option name="screenY" value="1840" />
|
|
||||||
</PersistentDeviceSelectionData>
|
|
||||||
<PersistentDeviceSelectionData>
|
|
||||||
<option name="api" value="33" />
|
|
||||||
<option name="brand" value="samsung" />
|
|
||||||
<option name="codename" value="gts8uwifi" />
|
|
||||||
<option name="id" value="gts8uwifi" />
|
|
||||||
<option name="manufacturer" value="Samsung" />
|
|
||||||
<option name="name" value="Galaxy Tab S8 Ultra" />
|
|
||||||
<option name="screenDensity" value="320" />
|
|
||||||
<option name="screenX" value="1848" />
|
|
||||||
<option name="screenY" value="2960" />
|
|
||||||
</PersistentDeviceSelectionData>
|
|
||||||
<PersistentDeviceSelectionData>
|
|
||||||
<option name="api" value="34" />
|
|
||||||
<option name="brand" value="google" />
|
|
||||||
<option name="codename" value="husky" />
|
|
||||||
<option name="id" value="husky" />
|
|
||||||
<option name="manufacturer" value="Google" />
|
|
||||||
<option name="name" value="Pixel 8 Pro" />
|
|
||||||
<option name="screenDensity" value="390" />
|
|
||||||
<option name="screenX" value="1008" />
|
|
||||||
<option name="screenY" value="2244" />
|
|
||||||
</PersistentDeviceSelectionData>
|
|
||||||
<PersistentDeviceSelectionData>
|
|
||||||
<option name="api" value="30" />
|
|
||||||
<option name="brand" value="motorola" />
|
|
||||||
<option name="codename" value="java" />
|
|
||||||
<option name="id" value="java" />
|
|
||||||
<option name="manufacturer" value="Motorola" />
|
|
||||||
<option name="name" value="G20" />
|
|
||||||
<option name="screenDensity" value="280" />
|
|
||||||
<option name="screenX" value="720" />
|
|
||||||
<option name="screenY" value="1600" />
|
|
||||||
</PersistentDeviceSelectionData>
|
|
||||||
<PersistentDeviceSelectionData>
|
|
||||||
<option name="api" value="33" />
|
|
||||||
<option name="brand" value="google" />
|
|
||||||
<option name="codename" value="lynx" />
|
|
||||||
<option name="id" value="lynx" />
|
|
||||||
<option name="manufacturer" value="Google" />
|
|
||||||
<option name="name" value="Pixel 7a" />
|
|
||||||
<option name="screenDensity" value="420" />
|
|
||||||
<option name="screenX" value="1080" />
|
|
||||||
<option name="screenY" value="2400" />
|
|
||||||
</PersistentDeviceSelectionData>
|
|
||||||
<PersistentDeviceSelectionData>
|
|
||||||
<option name="api" value="31" />
|
|
||||||
<option name="brand" value="google" />
|
|
||||||
<option name="codename" value="oriole" />
|
|
||||||
<option name="id" value="oriole" />
|
|
||||||
<option name="manufacturer" value="Google" />
|
|
||||||
<option name="name" value="Pixel 6" />
|
|
||||||
<option name="screenDensity" value="420" />
|
|
||||||
<option name="screenX" value="1080" />
|
|
||||||
<option name="screenY" value="2400" />
|
|
||||||
</PersistentDeviceSelectionData>
|
|
||||||
<PersistentDeviceSelectionData>
|
|
||||||
<option name="api" value="33" />
|
|
||||||
<option name="brand" value="google" />
|
|
||||||
<option name="codename" value="panther" />
|
|
||||||
<option name="id" value="panther" />
|
|
||||||
<option name="manufacturer" value="Google" />
|
|
||||||
<option name="name" value="Pixel 7" />
|
|
||||||
<option name="screenDensity" value="420" />
|
|
||||||
<option name="screenX" value="1080" />
|
|
||||||
<option name="screenY" value="2400" />
|
|
||||||
</PersistentDeviceSelectionData>
|
|
||||||
<PersistentDeviceSelectionData>
|
|
||||||
<option name="api" value="31" />
|
|
||||||
<option name="brand" value="samsung" />
|
|
||||||
<option name="codename" value="q2q" />
|
|
||||||
<option name="id" value="q2q" />
|
|
||||||
<option name="manufacturer" value="Samsung" />
|
|
||||||
<option name="name" value="Galaxy Z Fold3" />
|
|
||||||
<option name="screenDensity" value="420" />
|
|
||||||
<option name="screenX" value="1768" />
|
|
||||||
<option name="screenY" value="2208" />
|
|
||||||
</PersistentDeviceSelectionData>
|
|
||||||
<PersistentDeviceSelectionData>
|
|
||||||
<option name="api" value="34" />
|
|
||||||
<option name="brand" value="samsung" />
|
|
||||||
<option name="codename" value="q5q" />
|
|
||||||
<option name="id" value="q5q" />
|
|
||||||
<option name="manufacturer" value="Samsung" />
|
|
||||||
<option name="name" value="Galaxy Z Fold5" />
|
|
||||||
<option name="screenDensity" value="420" />
|
|
||||||
<option name="screenX" value="1812" />
|
|
||||||
<option name="screenY" value="2176" />
|
|
||||||
</PersistentDeviceSelectionData>
|
|
||||||
<PersistentDeviceSelectionData>
|
|
||||||
<option name="api" value="30" />
|
|
||||||
<option name="brand" value="google" />
|
|
||||||
<option name="codename" value="r11" />
|
|
||||||
<option name="id" value="r11" />
|
|
||||||
<option name="manufacturer" value="Google" />
|
|
||||||
<option name="name" value="Pixel Watch" />
|
|
||||||
<option name="screenDensity" value="320" />
|
|
||||||
<option name="screenX" value="384" />
|
|
||||||
<option name="screenY" value="384" />
|
|
||||||
<option name="type" value="WEAR_OS" />
|
|
||||||
</PersistentDeviceSelectionData>
|
|
||||||
<PersistentDeviceSelectionData>
|
|
||||||
<option name="api" value="30" />
|
|
||||||
<option name="brand" value="google" />
|
|
||||||
<option name="codename" value="redfin" />
|
|
||||||
<option name="id" value="redfin" />
|
|
||||||
<option name="manufacturer" value="Google" />
|
|
||||||
<option name="name" value="Pixel 5" />
|
|
||||||
<option name="screenDensity" value="440" />
|
|
||||||
<option name="screenX" value="1080" />
|
|
||||||
<option name="screenY" value="2340" />
|
|
||||||
</PersistentDeviceSelectionData>
|
|
||||||
<PersistentDeviceSelectionData>
|
|
||||||
<option name="api" value="34" />
|
|
||||||
<option name="brand" value="google" />
|
|
||||||
<option name="codename" value="shiba" />
|
|
||||||
<option name="id" value="shiba" />
|
|
||||||
<option name="manufacturer" value="Google" />
|
|
||||||
<option name="name" value="Pixel 8" />
|
|
||||||
<option name="screenDensity" value="420" />
|
|
||||||
<option name="screenX" value="1080" />
|
|
||||||
<option name="screenY" value="2400" />
|
|
||||||
</PersistentDeviceSelectionData>
|
|
||||||
<PersistentDeviceSelectionData>
|
|
||||||
<option name="api" value="33" />
|
|
||||||
<option name="brand" value="google" />
|
|
||||||
<option name="codename" value="tangorpro" />
|
|
||||||
<option name="id" value="tangorpro" />
|
|
||||||
<option name="manufacturer" value="Google" />
|
|
||||||
<option name="name" value="Pixel Tablet" />
|
|
||||||
<option name="screenDensity" value="320" />
|
|
||||||
<option name="screenX" value="1600" />
|
|
||||||
<option name="screenY" value="2560" />
|
|
||||||
</PersistentDeviceSelectionData>
|
|
||||||
<PersistentDeviceSelectionData>
|
|
||||||
<option name="api" value="29" />
|
|
||||||
<option name="brand" value="samsung" />
|
|
||||||
<option name="codename" value="x1q" />
|
|
||||||
<option name="id" value="x1q" />
|
|
||||||
<option name="manufacturer" value="Samsung" />
|
|
||||||
<option name="name" value="Galaxy S20" />
|
|
||||||
<option name="screenDensity" value="480" />
|
|
||||||
<option name="screenX" value="1440" />
|
|
||||||
<option name="screenY" value="3200" />
|
|
||||||
</PersistentDeviceSelectionData>
|
|
||||||
</list>
|
|
||||||
</option>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
17
android/.idea/runConfigurations.xml
generated
Normal file
17
android/.idea/runConfigurations.xml
generated
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="RunConfigurationProducerService">
|
||||||
|
<option name="ignoredProducers">
|
||||||
|
<set>
|
||||||
|
<option value="com.intellij.execution.junit.AbstractAllInDirectoryConfigurationProducer" />
|
||||||
|
<option value="com.intellij.execution.junit.AllInPackageConfigurationProducer" />
|
||||||
|
<option value="com.intellij.execution.junit.PatternConfigurationProducer" />
|
||||||
|
<option value="com.intellij.execution.junit.TestInClassConfigurationProducer" />
|
||||||
|
<option value="com.intellij.execution.junit.UniqueIdConfigurationProducer" />
|
||||||
|
<option value="com.intellij.execution.junit.testDiscovery.JUnitTestDiscoveryConfigurationProducer" />
|
||||||
|
<option value="org.jetbrains.kotlin.idea.junit.KotlinJUnitRunConfigurationProducer" />
|
||||||
|
<option value="org.jetbrains.kotlin.idea.junit.KotlinPatternConfigurationProducer" />
|
||||||
|
</set>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
</project>
|
@@ -30,6 +30,7 @@ android {
|
|||||||
targetCompatibility 1.8
|
targetCompatibility 1.8
|
||||||
sourceCompatibility 1.8
|
sourceCompatibility 1.8
|
||||||
}
|
}
|
||||||
|
namespace 'com.blackforestbytes.simplecloudnotifier'
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
package="com.blackforestbytes.simplecloudnotifier">
|
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||||
|
@@ -7,8 +7,8 @@ buildscript {
|
|||||||
jcenter()
|
jcenter()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:4.1.0'
|
classpath 'com.android.tools.build:gradle:8.9.1'
|
||||||
classpath 'com.google.gms:google-services:4.3.4'
|
classpath 'com.google.gms:google-services:4.3.10'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -14,3 +14,6 @@ org.gradle.jvmargs=-Xmx1536m
|
|||||||
|
|
||||||
android.useAndroidX=true
|
android.useAndroidX=true
|
||||||
android.enableJetifier=true
|
android.enableJetifier=true
|
||||||
|
android.defaults.buildfeatures.buildconfig=true
|
||||||
|
android.nonTransitiveRClass=false
|
||||||
|
android.nonFinalResIds=false
|
||||||
|
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
|
|||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-all.zip
|
||||||
|
2
flutter/.gitignore
vendored
2
flutter/.gitignore
vendored
@@ -5,6 +5,8 @@
|
|||||||
firepit-log.txt
|
firepit-log.txt
|
||||||
flutter_jank_*
|
flutter_jank_*
|
||||||
|
|
||||||
|
_releases/*
|
||||||
|
|
||||||
|
|
||||||
#######################################################################################################################
|
#######################################################################################################################
|
||||||
|
|
||||||
|
@@ -8,10 +8,17 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
run:
|
# runs app locally (linux)
|
||||||
flutter pub run build_runner build
|
run-linux:
|
||||||
_JAVA_OPTIONS="" flutter run
|
dart run build_runner build
|
||||||
|
_JAVA_OPTIONS="" flutter run -d linux
|
||||||
|
|
||||||
|
# runs app locally (web | not really supported)
|
||||||
|
run-linux:
|
||||||
|
dart run build_runner build
|
||||||
|
_JAVA_OPTIONS="" flutter run -d web
|
||||||
|
|
||||||
|
# runs on android device (must have network adb enabled teh correct IP)
|
||||||
run-android:
|
run-android:
|
||||||
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
|
||||||
@@ -37,8 +44,9 @@ fix:
|
|||||||
gen:
|
gen:
|
||||||
flutter pub run build_runner build
|
flutter pub run build_runner build
|
||||||
|
|
||||||
|
# run `make run` in another terminal (or another variant of flutter run)
|
||||||
autoreload:
|
autoreload:
|
||||||
@# run `make run` in another terminal (or another variant of flutter run)
|
@
|
||||||
@_utils/autoreload.sh
|
@_utils/autoreload.sh
|
||||||
|
|
||||||
icons:
|
icons:
|
||||||
@@ -47,3 +55,12 @@ icons:
|
|||||||
clean:
|
clean:
|
||||||
cd android && ./gradlew clean
|
cd android && ./gradlew clean
|
||||||
flutter clean
|
flutter clean
|
||||||
|
|
||||||
|
# upgrade all packages (add --major-versions even updates across new major versions)
|
||||||
|
# https://docs.flutter.dev/release/upgrade
|
||||||
|
# upgrading flutter can be done via `flutter upgrade`: https://docs.flutter.dev/release/upgrade
|
||||||
|
# android/gradle updates should be done via androidStudio: https://docs.flutter.dev/release/breaking-changes/android-java-gradle-migration-guide
|
||||||
|
upgrade:
|
||||||
|
flutter upgrade
|
||||||
|
flutter pub upgrade
|
||||||
|
flutter doctor
|
@@ -27,6 +27,13 @@
|
|||||||
|
|
||||||
- [ ] fix time format (in message-list, in card, top right) - midnight is shown as "24:05" instead of "00:05" - thats weird
|
- [ ] fix time format (in message-list, in card, top right) - midnight is shown as "24:05" instead of "00:05" - thats weird
|
||||||
|
|
||||||
|
- [ ] Add scrollbar
|
||||||
|
-> https://api.flutter.dev/flutter/material/Scrollbar-class.html
|
||||||
|
|
||||||
|
- [ ] you cant unsubscribe from foreign channel without completely loosing subscription.
|
||||||
|
perhaps subscriptions should have two cofirmed bool (both must be true to receive messages): confirmed-owner && confirmed-subscriber
|
||||||
|
Then the subscriber can unconfirm his half - without loosing the owner confirmation
|
||||||
|
|
||||||
-----
|
-----
|
||||||
|
|
||||||
# TODO iOS specific
|
# TODO iOS specific
|
||||||
|
4
flutter/android/.gitignore
vendored
4
flutter/android/.gitignore
vendored
@@ -11,3 +11,7 @@ GeneratedPluginRegistrant.java
|
|||||||
key.properties
|
key.properties
|
||||||
**/*.keystore
|
**/*.keystore
|
||||||
**/*.jks
|
**/*.jks
|
||||||
|
|
||||||
|
build/
|
||||||
|
|
||||||
|
app/.cxx/
|
@@ -34,7 +34,7 @@ if (keystorePropertiesFile.exists()) {
|
|||||||
android {
|
android {
|
||||||
namespace "com.blackforestbytes.simplecloudnotifier"
|
namespace "com.blackforestbytes.simplecloudnotifier"
|
||||||
compileSdkVersion flutter.compileSdkVersion
|
compileSdkVersion flutter.compileSdkVersion
|
||||||
ndkVersion flutter.ndkVersion
|
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)
|
||||||
|
|
||||||
compileOptions {
|
compileOptions {
|
||||||
coreLibraryDesugaringEnabled true
|
coreLibraryDesugaringEnabled true
|
||||||
|
@@ -1,16 +1,3 @@
|
|||||||
buildscript {
|
|
||||||
ext.kotlin_version = '1.7.10'
|
|
||||||
repositories {
|
|
||||||
google()
|
|
||||||
mavenCentral()
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
classpath 'com.android.tools.build:gradle:7.3.1'
|
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
@@ -23,7 +23,8 @@ pluginManagement {
|
|||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
|
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
|
||||||
id "com.android.application" version "7.3.0" apply false
|
id "com.android.application" version "8.9.1" apply false
|
||||||
|
id "org.jetbrains.kotlin.android" version "2.1.10" apply false
|
||||||
// START: FlutterFire Configuration
|
// START: FlutterFire Configuration
|
||||||
id "com.google.gms.google-services" version "4.3.15" apply false
|
id "com.google.gms.google-services" version "4.3.15" apply false
|
||||||
// END: FlutterFire Configuration
|
// END: FlutterFire Configuration
|
||||||
|
@@ -162,6 +162,20 @@ class APIClient {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Future<User> updateUser(TokenSource auth, String uid, {String? username, String? proToken}) async {
|
||||||
|
return await _request(
|
||||||
|
name: 'updateUser',
|
||||||
|
method: 'PATCH',
|
||||||
|
relURL: 'users/$uid',
|
||||||
|
jsonBody: {
|
||||||
|
if (username != null) 'username': username,
|
||||||
|
if (proToken != null) 'pro_token': proToken,
|
||||||
|
},
|
||||||
|
fn: User.fromJson,
|
||||||
|
authToken: auth.getToken(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
static Future<Client> addClient(TokenSource auth, String fcmToken, String agentModel, String agentVersion, String? name, String clientType) async {
|
static Future<Client> addClient(TokenSource auth, String fcmToken, String agentModel, String agentVersion, String? name, String clientType) async {
|
||||||
return await _request(
|
return await _request(
|
||||||
name: 'addClient',
|
name: 'addClient',
|
||||||
|
@@ -13,6 +13,7 @@ import 'package:simplecloudnotifier/state/application_log.dart';
|
|||||||
import 'package:simplecloudnotifier/state/globals.dart';
|
import 'package:simplecloudnotifier/state/globals.dart';
|
||||||
import 'package:simplecloudnotifier/state/app_auth.dart';
|
import 'package:simplecloudnotifier/state/app_auth.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/navi.dart';
|
import 'package:simplecloudnotifier/utils/navi.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';
|
||||||
@@ -359,13 +360,15 @@ class _AccountRootPageState extends State<AccountRootPage> {
|
|||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
UI.buttonIconOnly(
|
UI.buttonIconOnly(
|
||||||
onPressed: () {/*TODO*/},
|
onPressed: _changeUsername,
|
||||||
icon: FontAwesomeIcons.pen,
|
icon: FontAwesomeIcons.pen,
|
||||||
),
|
),
|
||||||
const SizedBox(height: 4),
|
const SizedBox(height: 4),
|
||||||
if (!user.isPro)
|
if (!user.isPro)
|
||||||
UI.buttonIconOnly(
|
UI.buttonIconOnly(
|
||||||
onPressed: () {/*TODO*/},
|
onPressed: () {
|
||||||
|
Toaster.info("Not Implemented", "Account Upgrading will be implemented in a later version"); // TODO
|
||||||
|
},
|
||||||
icon: FontAwesomeIcons.cartCircleArrowUp,
|
icon: FontAwesomeIcons.cartCircleArrowUp,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -502,4 +505,31 @@ class _AccountRootPageState extends State<AccountRootPage> {
|
|||||||
void _deleteAccount() async {
|
void _deleteAccount() async {
|
||||||
//TODO
|
//TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _changeUsername() async {
|
||||||
|
final acc = AppAuth();
|
||||||
|
if (!acc.isAuth()) return;
|
||||||
|
|
||||||
|
var newusername = await UIDialogs.showTextInput(context, 'Change your public username', 'Enter new username');
|
||||||
|
if (newusername == null) return;
|
||||||
|
|
||||||
|
newusername = newusername.trim();
|
||||||
|
if (newusername == '') {
|
||||||
|
Toaster.error("Error", 'Username cannot be empty');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
final user = await APIClient.updateUser(acc, acc.userID!, username: newusername);
|
||||||
|
setState(() {
|
||||||
|
futureUser = ImmediateFuture.ofValue(user);
|
||||||
|
});
|
||||||
|
Toaster.success("Success", 'Username changed');
|
||||||
|
|
||||||
|
_backgroundRefresh();
|
||||||
|
} catch (exc, trace) {
|
||||||
|
Toaster.error("Error", 'Failed to update username');
|
||||||
|
ApplicationLog.error('Failed to update username: ' + exc.toString(), trace: trace);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -547,7 +547,7 @@ class _ChannelViewPageState extends State<ChannelViewPage> {
|
|||||||
final acc = AppAuth();
|
final acc = AppAuth();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await APIClient.unconfirmSubscription(acc, widget.channelID, subscription!.subscriptionID);
|
await APIClient.unconfirmSubscription(acc, widget.channelID, sub.subscriptionID);
|
||||||
widget.needsReload?.call();
|
widget.needsReload?.call();
|
||||||
|
|
||||||
await _initStateAsync(false);
|
await _initStateAsync(false);
|
||||||
@@ -563,7 +563,7 @@ class _ChannelViewPageState extends State<ChannelViewPage> {
|
|||||||
final acc = AppAuth();
|
final acc = AppAuth();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await APIClient.confirmSubscription(acc, widget.channelID, subscription!.subscriptionID);
|
await APIClient.confirmSubscription(acc, widget.channelID, sub.subscriptionID);
|
||||||
widget.needsReload?.call();
|
widget.needsReload?.call();
|
||||||
|
|
||||||
await _initStateAsync(false);
|
await _initStateAsync(false);
|
||||||
@@ -579,7 +579,7 @@ class _ChannelViewPageState extends State<ChannelViewPage> {
|
|||||||
final acc = AppAuth();
|
final acc = AppAuth();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await APIClient.deleteSubscription(acc, widget.channelID, subscription!.subscriptionID);
|
await APIClient.deleteSubscription(acc, widget.channelID, sub.subscriptionID);
|
||||||
widget.needsReload?.call();
|
widget.needsReload?.call();
|
||||||
|
|
||||||
await _initStateAsync(false);
|
await _initStateAsync(false);
|
||||||
|
@@ -1,3 +1,5 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
@@ -6,11 +8,19 @@ import 'package:simplecloudnotifier/state/request_log.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';
|
||||||
|
|
||||||
class DebugRequestViewPage extends StatelessWidget {
|
class DebugRequestViewPage extends StatefulWidget {
|
||||||
final SCNRequest request;
|
final SCNRequest request;
|
||||||
|
|
||||||
DebugRequestViewPage({required this.request});
|
DebugRequestViewPage({required this.request});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<DebugRequestViewPage> createState() => _DebugRequestViewPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _DebugRequestViewPageState extends State<DebugRequestViewPage> {
|
||||||
|
Set<String> _monospaceMode = new Set();
|
||||||
|
Set<String> _prettyJson = new Set();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return SCNScaffold(
|
return SCNScaffold(
|
||||||
@@ -23,22 +33,22 @@ class DebugRequestViewPage extends StatelessWidget {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
...buildRow(context, "Name", request.name),
|
...buildRow(context, "name", "Name", widget.request.name),
|
||||||
...buildRow(context, "Timestamp (Start)", request.timestampStart.toString()),
|
...buildRow(context, "timestampStart", "Timestamp (Start)", widget.request.timestampStart.toString()),
|
||||||
...buildRow(context, "Timestamp (End)", request.timestampEnd.toString()),
|
...buildRow(context, "timestampEnd", "Timestamp (End)", widget.request.timestampEnd.toString()),
|
||||||
...buildRow(context, "Duration", request.timestampEnd.difference(request.timestampStart).toString()),
|
...buildRow(context, "duration", "Duration", widget.request.timestampEnd.difference(widget.request.timestampStart).toString()),
|
||||||
Divider(),
|
Divider(),
|
||||||
...buildRow(context, "Method", request.method),
|
...buildRow(context, "method", "Method", widget.request.method),
|
||||||
...buildRow(context, "URL", request.url),
|
...buildRow(context, "url", "URL", widget.request.url, mono: true),
|
||||||
if (request.requestHeaders.isNotEmpty) ...buildRow(context, "Request->Headers", request.requestHeaders.entries.map((v) => '${v.key} = ${v.value}').join('\n')),
|
if (widget.request.requestHeaders.isNotEmpty) ...buildRow(context, "request_headers", "Request->Headers", widget.request.requestHeaders.entries.map((v) => '${v.key} = ${v.value}').join('\n'), mono: true),
|
||||||
if (request.requestBody != '') ...buildRow(context, "Request->Body", request.requestBody),
|
if (widget.request.requestBody != '') ...buildRow(context, "request_body", "Request->Body", widget.request.requestBody, mono: true, json: true),
|
||||||
Divider(),
|
Divider(),
|
||||||
if (request.responseStatusCode != 0) ...buildRow(context, "Response->Statuscode", request.responseStatusCode.toString()),
|
if (widget.request.responseStatusCode != 0) ...buildRow(context, "response_statuscode", "Response->Statuscode", widget.request.responseStatusCode.toString()),
|
||||||
if (request.responseBody != '') ...buildRow(context, "Reponse->Body", request.responseBody),
|
if (widget.request.responseBody != '') ...buildRow(context, "response_body", "Reponse->Body", widget.request.responseBody, mono: true, json: true),
|
||||||
if (request.responseHeaders.isNotEmpty) ...buildRow(context, "Reponse->Headers", request.responseHeaders.entries.map((v) => '${v.key} = ${v.value}').join('\n')),
|
if (widget.request.responseHeaders.isNotEmpty) ...buildRow(context, "response_headers", "Reponse->Headers", widget.request.responseHeaders.entries.map((v) => '${v.key} = ${v.value}').join('\n'), mono: true, json: true),
|
||||||
Divider(),
|
Divider(),
|
||||||
if (request.error != '') ...buildRow(context, "Error", request.error),
|
if (widget.request.error != '') ...buildRow(context, "error", "Error", widget.request.error, mono: true),
|
||||||
if (request.stackTrace != '') ...buildRow(context, "Stacktrace", request.stackTrace),
|
if (widget.request.stackTrace != '') ...buildRow(context, "trace", "Stacktrace", widget.request.stackTrace, mono: true),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -46,7 +56,19 @@ class DebugRequestViewPage extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Widget> buildRow(BuildContext context, String title, String value) {
|
List<Widget> buildRow(BuildContext context, String key, String title, String value, {bool? json, bool? mono}) {
|
||||||
|
var isMono = _monospaceMode.contains(key);
|
||||||
|
var isJson = _prettyJson.contains(key);
|
||||||
|
|
||||||
|
if (isJson) {
|
||||||
|
try {
|
||||||
|
var jsonValue = jsonDecode(value);
|
||||||
|
value = JsonEncoder.withIndent(' ').convert(jsonValue);
|
||||||
|
} catch (e) {
|
||||||
|
value = ('Error parsing JSON: $e');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 0, horizontal: 8.0),
|
padding: const EdgeInsets.symmetric(vertical: 0, horizontal: 8.0),
|
||||||
@@ -64,19 +86,46 @@ class DebugRequestViewPage extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
icon: FontAwesomeIcons.copy,
|
icon: FontAwesomeIcons.copy,
|
||||||
),
|
),
|
||||||
|
if (mono == true)
|
||||||
|
UI.buttonIconOnly(
|
||||||
|
icon: isMono ? FontAwesomeIcons.lineColumns : FontAwesomeIcons.alignLeft,
|
||||||
|
onPressed: () {
|
||||||
|
setState(() {
|
||||||
|
_monospaceMode.contains(key) ? _monospaceMode.remove(key) : _monospaceMode.add(key);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
if (json == true)
|
||||||
|
UI.buttonIconOnly(
|
||||||
|
icon: isJson ? FontAwesomeIcons.bracketsRound : FontAwesomeIcons.bracketsCurly,
|
||||||
|
onPressed: () {
|
||||||
|
setState(() {
|
||||||
|
_prettyJson.contains(key) ? _prettyJson.remove(key) : _prettyJson.add(key);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Card.filled(
|
Card.filled(
|
||||||
shape: BeveledRectangleBorder(borderRadius: BorderRadius.circular(0)),
|
shape: BeveledRectangleBorder(borderRadius: BorderRadius.circular(0)),
|
||||||
color: request.type == 'SUCCESS' ? null : Theme.of(context).colorScheme.errorContainer,
|
color: widget.request.type == 'SUCCESS' ? null : Theme.of(context).colorScheme.errorContainer,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 2.0, horizontal: 6.0),
|
padding: const EdgeInsets.symmetric(vertical: 2.0, horizontal: 6.0),
|
||||||
child: SelectableText(
|
child: (isMono || isJson)
|
||||||
value,
|
? SingleChildScrollView(
|
||||||
minLines: 1,
|
scrollDirection: Axis.horizontal,
|
||||||
maxLines: 10,
|
child: SelectableText(
|
||||||
),
|
value,
|
||||||
|
minLines: 1,
|
||||||
|
maxLines: 10,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: SelectableText(
|
||||||
|
value,
|
||||||
|
minLines: 1,
|
||||||
|
maxLines: 10,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
|
29
flutter/lib/utils/dialogs.dart
Normal file
29
flutter/lib/utils/dialogs.dart
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class UIDialogs {
|
||||||
|
static Future<String?> showTextInput(BuildContext context, String title, String hintText) {
|
||||||
|
var _textFieldController = TextEditingController();
|
||||||
|
|
||||||
|
return showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => AlertDialog(
|
||||||
|
title: Text(title),
|
||||||
|
content: TextField(
|
||||||
|
autofocus: true,
|
||||||
|
controller: _textFieldController,
|
||||||
|
decoration: InputDecoration(hintText: hintText),
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
|
child: Text('Cancel'),
|
||||||
|
),
|
||||||
|
TextButton(
|
||||||
|
onPressed: () => Navigator.of(context).pop(_textFieldController.text),
|
||||||
|
child: Text('OK'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
@@ -11,7 +11,7 @@ dependencies:
|
|||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
|
||||||
flutter_launcher_icons: "^0.13.1"
|
flutter_launcher_icons: ^0.14.3
|
||||||
|
|
||||||
font_awesome_flutter: '>= 4.7.0'
|
font_awesome_flutter: '>= 4.7.0'
|
||||||
cupertino_icons: ^1.0.2
|
cupertino_icons: ^1.0.2
|
||||||
@@ -21,19 +21,19 @@ dependencies:
|
|||||||
qr_flutter: ^4.1.0
|
qr_flutter: ^4.1.0
|
||||||
url_launcher: ^6.2.4
|
url_launcher: ^6.2.4
|
||||||
infinite_scroll_pagination: ^4.0.0
|
infinite_scroll_pagination: ^4.0.0
|
||||||
intl: ^0.19.0
|
intl: ^0.20.2
|
||||||
path_provider: ^2.1.3
|
path_provider: ^2.1.3
|
||||||
hive_flutter: ^1.1.0
|
hive_flutter: ^1.1.0
|
||||||
package_info_plus: ^8.0.0
|
package_info_plus: ^8.0.0
|
||||||
xid: ^1.2.1
|
xid: ^1.2.1
|
||||||
flutter_lazy_indexed_stack: ^0.0.6
|
flutter_lazy_indexed_stack: ^0.0.6
|
||||||
firebase_core: ^2.32.0
|
firebase_core: ^3.13.0
|
||||||
firebase_messaging: ^14.9.4
|
firebase_messaging: ^15.2.5
|
||||||
device_info_plus: ^10.1.0
|
device_info_plus: ^11.3.0
|
||||||
toastification: ^2.0.0
|
toastification: ^3.0.1
|
||||||
uuid: ^4.4.0
|
uuid: ^4.4.0
|
||||||
share_plus: ^9.0.0
|
share_plus: ^10.1.4
|
||||||
flutter_local_notifications: ^17.1.2
|
flutter_local_notifications: ^17.2.3
|
||||||
|
|
||||||
|
|
||||||
path: any
|
path: any
|
||||||
@@ -47,7 +47,7 @@ dev_dependencies:
|
|||||||
flutter_test:
|
flutter_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
|
||||||
flutter_lints: ^4.0.0
|
flutter_lints: ^5.0.0
|
||||||
hive_generator: ^2.0.1
|
hive_generator: ^2.0.1
|
||||||
build_runner: ^2.1.4
|
build_runner: ^2.1.4
|
||||||
|
|
||||||
|
@@ -23,6 +23,7 @@ type ChannelPreview struct {
|
|||||||
InternalName string `json:"internal_name"`
|
InternalName string `json:"internal_name"`
|
||||||
DisplayName string `json:"display_name"`
|
DisplayName string `json:"display_name"`
|
||||||
DescriptionName *string `json:"description_name"`
|
DescriptionName *string `json:"description_name"`
|
||||||
|
MessagesSent int `json:"messages_sent"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c Channel) WithSubscription(sub *Subscription) ChannelWithSubscription {
|
func (c Channel) WithSubscription(sub *Subscription) ChannelWithSubscription {
|
||||||
@@ -39,5 +40,6 @@ func (c Channel) Preview() ChannelPreview {
|
|||||||
InternalName: c.InternalName,
|
InternalName: c.InternalName,
|
||||||
DisplayName: c.DisplayName,
|
DisplayName: c.DisplayName,
|
||||||
DescriptionName: c.DescriptionName,
|
DescriptionName: c.DescriptionName,
|
||||||
|
MessagesSent: c.MessagesSent,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -11,7 +11,7 @@ type User struct {
|
|||||||
TimestampLastRead *SCNTime `db:"timestamp_lastread" json:"timestamp_lastread"`
|
TimestampLastRead *SCNTime `db:"timestamp_lastread" json:"timestamp_lastread"`
|
||||||
TimestampLastSent *SCNTime `db:"timestamp_lastsent" json:"timestamp_lastsent"`
|
TimestampLastSent *SCNTime `db:"timestamp_lastsent" json:"timestamp_lastsent"`
|
||||||
MessagesSent int `db:"messages_sent" json:"messages_sent"`
|
MessagesSent int `db:"messages_sent" json:"messages_sent"`
|
||||||
QuotaUsed int `db:"quota_used" json:"quota_used"`
|
QuotaUsed int `db:"quota_used" json:"-"`
|
||||||
QuotaUsedDay *string `db:"quota_used_day" json:"-"`
|
QuotaUsedDay *string `db:"quota_used_day" json:"-"`
|
||||||
IsPro bool `db:"is_pro" json:"is_pro"`
|
IsPro bool `db:"is_pro" json:"is_pro"`
|
||||||
ProToken *string `db:"pro_token" json:"-"`
|
ProToken *string `db:"pro_token" json:"-"`
|
||||||
@@ -22,6 +22,7 @@ type User struct {
|
|||||||
type UserExtra struct {
|
type UserExtra struct {
|
||||||
QuotaRemaining int `json:"quota_remaining"`
|
QuotaRemaining int `json:"quota_remaining"`
|
||||||
QuotaPerDay int `json:"quota_max"`
|
QuotaPerDay int `json:"quota_max"`
|
||||||
|
QuotaUsed int `json:"quota_used"`
|
||||||
DefaultChannel string `json:"default_channel"`
|
DefaultChannel string `json:"default_channel"`
|
||||||
MaxBodySize int `json:"max_body_size"`
|
MaxBodySize int `json:"max_body_size"`
|
||||||
MaxTitleLength int `json:"max_title_length"`
|
MaxTitleLength int `json:"max_title_length"`
|
||||||
@@ -58,6 +59,7 @@ func (u User) WithClients(clients []Client, ak string, sk string, rk string) Use
|
|||||||
func (u *User) PreMarshal() User {
|
func (u *User) PreMarshal() User {
|
||||||
u.UserExtra = UserExtra{
|
u.UserExtra = UserExtra{
|
||||||
QuotaPerDay: u.QuotaPerDay(),
|
QuotaPerDay: u.QuotaPerDay(),
|
||||||
|
QuotaUsed: u.QuotaUsedToday(),
|
||||||
QuotaRemaining: u.QuotaRemainingToday(),
|
QuotaRemaining: u.QuotaRemainingToday(),
|
||||||
DefaultChannel: u.DefaultChannel(),
|
DefaultChannel: u.DefaultChannel(),
|
||||||
MaxBodySize: u.MaxContentLength(),
|
MaxBodySize: u.MaxContentLength(),
|
||||||
|
Reference in New Issue
Block a user