Compare commits
79 Commits
Author | SHA1 | Date |
---|---|---|
Dan Ballard | 899da5fea1 | |
Sarah Jamie Lewis | 7741b255da | |
Sarah Jamie Lewis | 3aa0042b71 | |
Sarah Jamie Lewis | 4cb59d6cbc | |
Dan Ballard | f8ec6099bc | |
Sarah Jamie Lewis | 6e010b27b7 | |
Dan Ballard | 9f982ae167 | |
Dan Ballard | db1f0ed41e | |
Dan Ballard | fab824edce | |
Dan Ballard | 48152acca1 | |
Dan Ballard | 644245d9ce | |
Dan Ballard | b4b27da3e8 | |
Dan Ballard | 8f2b0b8563 | |
Sarah Jamie Lewis | ff297ff9e9 | |
Dan Ballard | 4dbfc83f16 | |
Dan Ballard | ddc23e35ca | |
Sarah Jamie Lewis | 50c9f66aca | |
Sarah Jamie Lewis | a4421f831a | |
Sarah Jamie Lewis | 33bc7b6db8 | |
Sarah Jamie Lewis | b23f8efaa1 | |
Sarah Jamie Lewis | e4c7729456 | |
Sarah Jamie Lewis | b64b99b510 | |
Sarah Jamie Lewis | 058fba7e69 | |
Sarah Jamie Lewis | da0d63b0dc | |
Sarah Jamie Lewis | 7cea83d141 | |
Sarah Jamie Lewis | 3b818e1181 | |
Sarah Jamie Lewis | 37ce0bd1d2 | |
Sarah Jamie Lewis | 26a3270585 | |
Sarah Jamie Lewis | 3463894dfd | |
Sarah Jamie Lewis | a479c2aeba | |
Sarah Jamie Lewis | fcd16b19c8 | |
Sarah Jamie Lewis | a866d9ff8a | |
Sarah Jamie Lewis | ff0bb0b548 | |
Sarah Jamie Lewis | 5ff87eb68a | |
Sarah Jamie Lewis | d22fccdd51 | |
Sarah Jamie Lewis | 2f1e939fdd | |
Sarah Jamie Lewis | 213ed00373 | |
Sarah Jamie Lewis | ff7d1cbd05 | |
Sarah Jamie Lewis | 3014a85803 | |
Sarah Jamie Lewis | a2f0fbdb38 | |
Sarah Jamie Lewis | 1dbd4b7ffc | |
Sarah Jamie Lewis | 03ffed9b25 | |
Sarah Jamie Lewis | dc45506f69 | |
Sarah Jamie Lewis | 8a0d52ab16 | |
Sarah Jamie Lewis | 7773efb8ee | |
Sarah Jamie Lewis | 8cc8af6a91 | |
Sarah Jamie Lewis | 9f03b48757 | |
Sarah Jamie Lewis | 098adc46e6 | |
Sarah Jamie Lewis | f235e56fbb | |
Sarah Jamie Lewis | 11e7e58109 | |
Sarah Jamie Lewis | 5627f6a438 | |
Sarah Jamie Lewis | caf85f337b | |
Sarah Jamie Lewis | eaae82ef55 | |
Sarah Jamie Lewis | 0ea595692f | |
Sarah Jamie Lewis | 5626e6ed90 | |
Dan Ballard | 273613a8b8 | |
Sarah Jamie Lewis | ff55f70bd4 | |
Dan Ballard | 7febeeadb6 | |
Dan Ballard | a6c0e8105d | |
Sarah Jamie Lewis | 3d2b960a20 | |
Sarah Jamie Lewis | f046dd923e | |
Sarah Jamie Lewis | 015b6ad10c | |
Dan Ballard | ea213080b1 | |
Sarah Jamie Lewis | fecf29176b | |
Sarah Jamie Lewis | 4bad19926b | |
Sarah Jamie Lewis | 75958faa38 | |
Sarah Jamie Lewis | 8300acb6f9 | |
Sarah Jamie Lewis | 33f99a3b18 | |
Sarah Jamie Lewis | b291188550 | |
Sarah Jamie Lewis | 0342eae5ce | |
Sarah Jamie Lewis | fe085e4802 | |
Sarah Jamie Lewis | 38d84e0f62 | |
Sarah Jamie Lewis | 3be7066e5d | |
Sarah Jamie Lewis | b492be0200 | |
Sarah Jamie Lewis | 6ba6f76ee1 | |
Sarah Jamie Lewis | 4ea0d4261c | |
Sarah Jamie Lewis | 88a8ac8cca | |
Sarah Jamie Lewis | 0eb1b95811 | |
Dan Ballard | e0546eb502 |
57
.drone.yml
57
.drone.yml
|
@ -8,7 +8,7 @@ clone:
|
|||
|
||||
steps:
|
||||
- name: clone
|
||||
image: openpriv/flutter-desktop:linux-fstable-3.13.4
|
||||
image: openpriv/flutter-desktop:linux-fstable-3.19.3
|
||||
environment:
|
||||
buildbot_key_b64:
|
||||
from_secret: buildbot_key_b64
|
||||
|
@ -24,7 +24,7 @@ steps:
|
|||
- git checkout $DRONE_COMMIT
|
||||
|
||||
- name: fetch
|
||||
image: openpriv/flutter-desktop:linux-fstable-3.13.4
|
||||
image: openpriv/flutter-desktop:linux-fstable-3.19.3
|
||||
volumes:
|
||||
- name: deps
|
||||
path: /root/.pub-cache
|
||||
|
@ -47,7 +47,7 @@ steps:
|
|||
# #Todo: fix all the lint errors and add `-set_exit_status` above to enforce linting
|
||||
|
||||
- name: build-linux
|
||||
image: openpriv/flutter-desktop:linux-fstable-3.13.4
|
||||
image: openpriv/flutter-desktop:linux-fstable-3.19.3
|
||||
volumes:
|
||||
- name: deps
|
||||
path: /root/.pub-cache
|
||||
|
@ -55,14 +55,29 @@ steps:
|
|||
- flutter build linux --dart-define BUILD_VER=`cat VERSION` --dart-define BUILD_DATE=`cat COMMIT_DATE`
|
||||
- linux/package-release.sh
|
||||
- mkdir -p deploy/cwtch
|
||||
- mkdir -p deploy/deb/cwtch/usr
|
||||
- mkdir -p deploy/deb/cwtch/DEBIAN
|
||||
- export VERSION=`cat VERSION | tr -d 'v'`
|
||||
- sed "s|VERSION|$VERSION|g" linux/deb/control > deploy/deb/cwtch/DEBIAN/control
|
||||
- cp -r build/linux/x64/release/bundle/* deploy/cwtch
|
||||
- cd deploy
|
||||
- cd cwtch
|
||||
- INSTALL_PREFIX=./../deb/cwtch/usr DESKTOP_PREFIX=/usr/ ./install.sh
|
||||
- cd ..
|
||||
# we depend on tor, get it from the tor project apt repo
|
||||
- rm -r deb/cwtch/usr/lib/cwtch/Tor
|
||||
# Tar archives need a few tricks to make this deterministic, see https://reproducible-builds.org/docs/archives/
|
||||
- tar --sort=name --mtime=`cat COMMIT_DATE` --owner=0 --group=0 --numeric-owner --pax-option=exthdr.name=%d/PaxHeaders/%f,delete=atime,delete=ctime -czf cwtch-`cat ../VERSION`.tar.gz cwtch
|
||||
- rm -r cwtch
|
||||
- cd deb
|
||||
- dpkg-deb --build cwtch
|
||||
- cd ..
|
||||
- mv deb/cwtch.deb cwtch-$VERSION.deb
|
||||
- rm -r deb
|
||||
|
||||
|
||||
- name: linux-ui-tests
|
||||
image: openpriv/flutter-desktop:linux-fstable-3.13.4
|
||||
image: openpriv/flutter-desktop:linux-fstable-3.19.3
|
||||
volumes:
|
||||
- name: deps
|
||||
path: /root/.pub-cache
|
||||
|
@ -71,7 +86,7 @@ steps:
|
|||
- ./run-tests-headless.sh "01_general|01_tor|02_global_settings|04_profile_mgmt"
|
||||
|
||||
- name: test-build-android
|
||||
image: openpriv/flutter-desktop:linux-fstable-3.13.4
|
||||
image: openpriv/flutter-desktop:linux-fstable-3.19.3
|
||||
when:
|
||||
event: pull_request
|
||||
volumes:
|
||||
|
@ -81,7 +96,7 @@ steps:
|
|||
- flutter build apk --debug
|
||||
|
||||
- name: build-android
|
||||
image: openpriv/flutter-desktop:linux-fstable-3.13.4
|
||||
image: openpriv/flutter-desktop:linux-fstable-3.19.3
|
||||
when:
|
||||
event: push
|
||||
environment:
|
||||
|
@ -105,7 +120,7 @@ steps:
|
|||
#- cp build/app/outputs/flutter-apk/app-debug.apk deploy/android
|
||||
|
||||
- name: widget-tests
|
||||
image: openpriv/flutter-desktop:linux-fstable-3.13.4
|
||||
image: openpriv/flutter-desktop:linux-fstable-3.19.3
|
||||
volumes:
|
||||
- name: deps
|
||||
path: /root/.pub-cache
|
||||
|
@ -114,6 +129,21 @@ steps:
|
|||
- flutter test --coverage
|
||||
- genhtml coverage/lcov.info -o coverage/html
|
||||
|
||||
- name: upload-nightlies
|
||||
image: openpriv/flutter-desktop:linux-fstable-3.19.3
|
||||
environment:
|
||||
GOGS_ACCOUNT_TOKEN:
|
||||
from_secret: gogs_account_token
|
||||
secrets: [gogs_account_token]
|
||||
volumes:
|
||||
- name: deps
|
||||
path: /root/.pub-cache
|
||||
when:
|
||||
event: push
|
||||
status: [ success ]
|
||||
commands:
|
||||
- ./upload-releases.sh deploy/cwtch-`cat VERSION`.apk application/vnd.android.package-archive cwtch-`cat VERSION`.apk
|
||||
|
||||
- name: deploy-buildfiles
|
||||
image: kroniak/ssh-client
|
||||
pull: if-not-exists
|
||||
|
@ -178,7 +208,7 @@ clone:
|
|||
|
||||
steps:
|
||||
- name: clone
|
||||
image: openpriv/flutter-desktop:windows-sdk30-fstable-3.13.4
|
||||
image: openpriv/flutter-desktop:windows-sdk30-fstable-3.19.3
|
||||
environment:
|
||||
buildbot_key_b64:
|
||||
from_secret: buildbot_key_b64
|
||||
|
@ -196,7 +226,7 @@ steps:
|
|||
- git checkout $Env:DRONE_COMMIT
|
||||
|
||||
- name: fetch
|
||||
image: openpriv/flutter-desktop:windows-sdk30-fstable-3.10.2
|
||||
image: openpriv/flutter-desktop:windows-sdk30-fstable-3.19.3
|
||||
commands:
|
||||
- git describe --tags --abbrev=1 > VERSION
|
||||
- git log -1 --format=%cd --date=format:'%Y-%m-%d-%H-%M' > COMMIT_DATE
|
||||
|
@ -204,12 +234,12 @@ steps:
|
|||
- .\fetch-libcwtch-go.ps1
|
||||
|
||||
- name: build-windows
|
||||
image: openpriv/flutter-desktop:windows-sdk30-fstable-3.13.4
|
||||
image: openpriv/flutter-desktop:windows-sdk30-fstable-3.19.3
|
||||
commands:
|
||||
- flutter pub get
|
||||
- $Env:version += type .\VERSION
|
||||
- $Env:commitdate += type .\COMMIT_DATE
|
||||
- $Env:releasedir = "build\\windows\\runner\\Release\\"
|
||||
- $Env:releasedir = "build\\windows\\x64\\runner\\Release\\"
|
||||
- flutter build windows --dart-define BUILD_VER=$Env:version --dart-define BUILD_DATE=$Env:commitdate
|
||||
- copy windows\libCwtch.dll $Env:releasedir
|
||||
# flutter hasn't worked out it's packaging of required dll's so we have to resort to this manual nonsense
|
||||
|
@ -236,7 +266,7 @@ steps:
|
|||
commands:
|
||||
- $Env:version += type .\VERSION
|
||||
- $Env:commitdate += type .\COMMIT_DATE
|
||||
- $Env:releasedir = "build\\windows\\runner\\Release\\"
|
||||
- $Env:releasedir = "build\\windows\\x64\\runner\\Release\\"
|
||||
- $Env:zip = 'cwtch-' + $Env:version + '.zip'
|
||||
- $Env:zipsha = $Env:zip + '.sha512.txt'
|
||||
- $Env:buildname = 'flwtch-' + $Env:commitdate + '-' + $Env:version
|
||||
|
@ -261,7 +291,7 @@ steps:
|
|||
- move *.sha512.txt deploy\$Env:builddir
|
||||
|
||||
- name: deploy-windows
|
||||
image: openpriv/flutter-desktop:windows-sdk30-fstable-3.13.4
|
||||
image: openpriv/flutter-desktop:windows-sdk30-fstable-3.19.3
|
||||
when:
|
||||
event: push
|
||||
status: [ success ]
|
||||
|
@ -333,6 +363,7 @@ steps:
|
|||
commands:
|
||||
- export PATH=$PATH:/Users/drone/bin/flutter/bin
|
||||
- export PATH=$GEM_HOME/ruby/2.6.0/bin:$PATH
|
||||
- flutter doctor
|
||||
- flutter build macos --dart-define BUILD_VER=`cat VERSION` --dart-define BUILD_DATE=`cat COMMIT_DATE`
|
||||
- export PATH=$PATH:/opt/homebrew/bin/ #create-dmg
|
||||
- macos/package-release.sh
|
||||
|
|
|
@ -35,6 +35,7 @@ test_home
|
|||
.pub-cache/
|
||||
.pub/
|
||||
/build/
|
||||
./lib/gen/
|
||||
|
||||
# Web related
|
||||
lib/generated_plugin_registrant.dart
|
||||
|
@ -58,7 +59,7 @@ package.
|
|||
# Compiled Libs
|
||||
linux/tor
|
||||
linux/libCwtch.so
|
||||
android/cwtch/cwtch.aar
|
||||
android/app/cwtch/cwtch.aar
|
||||
android/app/src/main/jniLibs/*/libtor.so
|
||||
*.dylib
|
||||
integration_test/gherkin_suite_test.g.dart
|
||||
|
|
|
@ -1 +1 @@
|
|||
2024-02-09-13-23-v0.0.11
|
||||
2024-02-26-18-01-v0.0.14
|
2
LICENSE
2
LICENSE
|
@ -1,5 +1,5 @@
|
|||
MIT License
|
||||
Copyright (c) 2021 Open Privacy Research Society
|
||||
Copyright (c) 2021-2024 Open Privacy Research Society
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
# NSIS Notes
|
||||
|
||||
## Images
|
||||
|
||||
Requires Windows 3 Compatible Bitmaps.
|
||||
|
||||
Can convert to the correct format with e.g. `mogrify -compress none -format bmp3 windows/nsis/cwtch_title.bmp
|
||||
`
|
|
@ -1,3 +1,9 @@
|
|||
plugins {
|
||||
id "com.android.application"
|
||||
id "kotlin-android"
|
||||
id "dev.flutter.flutter-gradle-plugin"
|
||||
}
|
||||
|
||||
def localProperties = new Properties()
|
||||
def localPropertiesFile = rootProject.file('local.properties')
|
||||
if (localPropertiesFile.exists()) {
|
||||
|
@ -6,11 +12,6 @@ if (localPropertiesFile.exists()) {
|
|||
}
|
||||
}
|
||||
|
||||
def flutterRoot = localProperties.getProperty('flutter.sdk')
|
||||
if (flutterRoot == null) {
|
||||
throw new FileNotFoundException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
|
||||
}
|
||||
|
||||
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
|
||||
if (flutterVersionCode == null) {
|
||||
flutterVersionCode = '1'
|
||||
|
@ -21,10 +22,6 @@ if (flutterVersionName == null) {
|
|||
flutterVersionName = '1.0'
|
||||
}
|
||||
|
||||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
|
||||
|
||||
// key.properties MUST have password placeholders filled in (via drone with secrets) and cwtch-upload.jks file must be added (from drone secret)
|
||||
def keystoreProperties = new Properties()
|
||||
def keystorePropertiesFile = rootProject.file('key.properties')
|
||||
|
@ -33,7 +30,7 @@ if (keystorePropertiesFile.exists()) {
|
|||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion 33
|
||||
compileSdkVersion 34
|
||||
|
||||
sourceSets {
|
||||
main.java.srcDirs += 'src/main/kotlin'
|
||||
|
@ -54,7 +51,7 @@ android {
|
|||
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
||||
applicationId "im.cwtch.flwtch"
|
||||
minSdkVersion 19
|
||||
targetSdkVersion 33
|
||||
targetSdkVersion 34
|
||||
versionCode flutterVersionCode.toInteger()
|
||||
versionName flutterVersionName
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
|
@ -93,11 +90,11 @@ flutter {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||
implementation project(':cwtch')
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.21" // same as kotlin version in settings.gradle
|
||||
implementation fileTree( dir: 'cwtch')
|
||||
implementation files ('cwtch/cwtch.aar')
|
||||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.2"
|
||||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.2"
|
||||
implementation "com.airbnb.android:lottie:5.2.0"
|
||||
implementation "androidx.localbroadcastmanager:localbroadcastmanager:1.0.0"
|
||||
implementation "com.android.support.constraint:constraint-layout:2.0.4"
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<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"
|
||||
package="im.cwtch.flwtch">
|
||||
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
|
||||
calls FlutterMain.startInitialization(this); in its onCreate method.
|
||||
|
@ -13,7 +13,7 @@
|
|||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:launchMode="singleTop"
|
||||
android:theme="@style/NormalTheme"
|
||||
android:theme="@style/LaunchTheme"
|
||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
|
||||
android:hardwareAccelerated="true"
|
||||
android:windowSoftInputMode="adjustResize"
|
||||
|
@ -38,22 +38,30 @@
|
|||
android:name="flutterEmbedding"
|
||||
android:value="2" />
|
||||
|
||||
<!--Needed to run in background (lol)-->
|
||||
<service
|
||||
android:name="androidx.work.impl.foreground.SystemForegroundService"
|
||||
android:foregroundServiceType="dataSync"
|
||||
tools:node="merge" />
|
||||
|
||||
</application>
|
||||
|
||||
<!--Needed to access Tor socket-->
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
|
||||
<!--Needed to run in background (lol)-->
|
||||
<!-- Needed for running in the background -->
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
<!-- As of Android 13 this permission is required -->
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
|
||||
|
||||
<!-- Ability to ask user to exempt app from power management (which can kill it more frequently especially on some devices.
|
||||
Allows app to use ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS -->
|
||||
<uses-permission-sdk-23 android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
|
||||
|
||||
<!-- TODO when we support sdk 31
|
||||
|
||||
<uses-permission-sdk-23 android:name="android.permission.HIDE_OVERLAY_WINDOWS" />
|
||||
-->
|
||||
|
||||
|
||||
<!--Needed to check if activity is foregrounded or if messages from the service should be queued-->
|
||||
<uses-permission android:name="android.permission.GET_TASKS" />
|
||||
|
|
|
@ -11,6 +11,7 @@ import android.graphics.Color
|
|||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.util.Log
|
||||
import android.content.pm.ServiceInfo
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager
|
||||
|
@ -22,6 +23,13 @@ import io.flutter.FlutterInjector
|
|||
import org.json.JSONObject
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Paths
|
||||
import java.io.FileInputStream
|
||||
|
||||
|
||||
import java.io.File
|
||||
|
||||
|
||||
|
||||
|
||||
class FlwtchWorker(context: Context, parameters: WorkerParameters) :
|
||||
CoroutineWorker(context, parameters) {
|
||||
|
@ -137,7 +145,19 @@ class FlwtchWorker(context: Context, parameters: WorkerParameters) :
|
|||
Log.i(TAG, "notification for " + evt.EventType + " " + handle + " " + conversationId + " " + channelId)
|
||||
Log.i(TAG, data.toString());
|
||||
val key = loader.getLookupKeyForAsset(data.getString("picture"))//"assets/profiles/001-centaur.png")
|
||||
val fh = applicationContext.assets.open(key)
|
||||
var fh : java.io.InputStream? = null;
|
||||
try {
|
||||
fh = applicationContext.assets.open(key)
|
||||
} catch (e: Exception) {
|
||||
Log.d("FlwtchWorker->ContactInfo", e.toString() + " :: " + e.getStackTrace());
|
||||
}
|
||||
|
||||
try {
|
||||
val file = File(data.getString("picture"))
|
||||
fh = FileInputStream(file)
|
||||
} catch (e: Exception) {
|
||||
Log.d("FlwtchWorker->ContactInfo", e.toString() + " :: " + e.getStackTrace());
|
||||
}
|
||||
|
||||
val clickIntent = Intent(applicationContext, MainActivity::class.java).also { intent ->
|
||||
intent.action = Intent.ACTION_RUN
|
||||
|
@ -145,18 +165,21 @@ class FlwtchWorker(context: Context, parameters: WorkerParameters) :
|
|||
intent.putExtra("ProfileOnion", data.getString("ProfileOnion"))
|
||||
intent.putExtra("Handle", handle)
|
||||
}
|
||||
|
||||
val image : android.graphics.Bitmap? = if (fh != null) BitmapFactory.decodeStream(fh ) else null;
|
||||
val newNotification = NotificationCompat.Builder(applicationContext, channelId)
|
||||
.setContentTitle(data.getString("Nick"))
|
||||
.setContentText((notificationConversationInfo
|
||||
?: "New Message From %1").replace("%1", data.getString("Nick")))
|
||||
.setLargeIcon(BitmapFactory.decodeStream(fh))
|
||||
.setLargeIcon(image)
|
||||
.setSmallIcon(R.mipmap.knott_transparent)
|
||||
.setContentIntent(PendingIntent.getActivity(applicationContext, 1, clickIntent, flags))
|
||||
.setAutoCancel(true)
|
||||
.build()
|
||||
|
||||
notificationManager.notify(getNotificationID(data.getString("ProfileOnion"), channelId), newNotification)
|
||||
if (fh != null) {
|
||||
fh.close()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -292,7 +315,7 @@ class FlwtchWorker(context: Context, parameters: WorkerParameters) :
|
|||
.addAction(android.R.drawable.ic_delete, cancel, PendingIntent.getActivity(applicationContext, 2, cancelIntent, flags))
|
||||
.build()
|
||||
|
||||
return ForegroundInfo(101, notification)
|
||||
return ForegroundInfo(101, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC)
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.O)
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package im.cwtch.flwtch
|
||||
|
||||
import SplashView
|
||||
import android.annotation.TargetApi
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
|
@ -19,7 +18,6 @@ import androidx.localbroadcastmanager.content.LocalBroadcastManager
|
|||
import androidx.work.*
|
||||
import cwtch.Cwtch
|
||||
import io.flutter.embedding.android.FlutterActivity
|
||||
import io.flutter.embedding.android.SplashScreen
|
||||
import io.flutter.embedding.engine.FlutterEngine
|
||||
import io.flutter.plugin.common.ErrorLogResult
|
||||
import io.flutter.plugin.common.MethodCall
|
||||
|
@ -32,8 +30,6 @@ import java.util.concurrent.TimeUnit
|
|||
import kotlinx.coroutines.*
|
||||
|
||||
class MainActivity: FlutterActivity() {
|
||||
override fun provideSplashScreen(): SplashScreen? = SplashView()
|
||||
|
||||
|
||||
// Channel to get app info
|
||||
private val CHANNEL_APP_INFO = "test.flutter.dev/applicationInfo"
|
||||
|
@ -577,9 +573,6 @@ class MainActivity: FlutterActivity() {
|
|||
result.success(Cwtch.searchConversations(profile, pattern))
|
||||
return
|
||||
}
|
||||
"ReconnectCwtchForeground" -> {
|
||||
Cwtch.reconnectCwtchForeground()
|
||||
}
|
||||
"Shutdown" -> {
|
||||
Cwtch.shutdownCwtch();
|
||||
}
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import im.cwtch.flwtch.R
|
||||
import io.flutter.embedding.android.SplashScreen
|
||||
|
||||
class SplashView : SplashScreen {
|
||||
override fun createSplashView(context: Context, savedInstanceState: Bundle?): View? =
|
||||
LayoutInflater.from(context).inflate(R.layout.splash_view, null, false)
|
||||
|
||||
override fun transitionToFlutter(onTransitionComplete: Runnable) {
|
||||
onTransitionComplete.run()
|
||||
}
|
||||
}
|
|
@ -1,12 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Modify this file to customize your launch splash screen -->
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="?android:colorBackground" />
|
||||
<item android:drawable="@color/darkGreyPurple" />
|
||||
|
||||
<!-- You can insert your own image assets here -->
|
||||
<!-- <item>
|
||||
<item>
|
||||
<bitmap
|
||||
android:gravity="center"
|
||||
android:src="@mipmap/launch_image" />
|
||||
</item> -->
|
||||
android:src="@mipmap/knott" />
|
||||
</item>
|
||||
</layer-list>
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="500dp"
|
||||
android:height="500dp"
|
||||
android:viewportWidth="500"
|
||||
android:viewportHeight="500">
|
||||
<path
|
||||
android:pathData="M436.2,215c-0.6,3 -2,6.4 -4.3,10.4l18.2,18.2c2.4,-4.8 6.2,-13.1 8.2,-22.9c4.1,-20.2 -0.5,-37.1 -13.7,-50.3c-24.2,-24.2 -49.4,-26.4 -81.8,-7.3c-7.8,4.6 -16.1,10.6 -24.6,17.7c-19.5,16.3 -41.3,39.5 -64.9,69.2c15.4,19.4 30.2,36.2 43.8,49.8c6.3,6.3 12.4,12 18.3,17.1l16.2,-16.2c-5.9,-5 -12.1,-10.7 -18.4,-17c-9,-9 -18.5,-19.5 -28.4,-31.2l-2.1,-2.5l2.1,-2.5c18.1,-21.5 35,-38.6 50.1,-50.9c9.6,-7.8 18.6,-13.8 26.7,-17.7c7,-3.4 13.4,-5.3 19,-5.6c2.7,-0.2 6.9,-0.1 12.1,2c5,2.1 10.2,5.8 15.7,11.3c2.1,2.1 5,5.4 6.8,10.4C437.1,202.1 437.5,208 436.2,215L436.2,215z"
|
||||
android:fillColor="#242425"/>
|
||||
<path
|
||||
android:pathData="M340.9,354.7l81.5,-81.5c-4.8,-7.1 -11.1,-14 -14.6,-17.7L327.3,336C332.5,342.4 337.1,348.6 340.9,354.7z"
|
||||
android:fillColor="#242425"/>
|
||||
<path
|
||||
android:pathData="M444.6,329.6c13.2,-13.2 17.8,-30.1 13.7,-50.3c-2.8,-14 -9.1,-24.9 -10.3,-26.9L382.6,187c-6,3.1 -12.5,7.4 -19.4,12.8l50.1,50.1l0,0c4.1,4.3 12.1,13 17.4,21.6c3.2,5.2 5.1,9.7 5.6,13.5c1.2,6.9 0.9,12.7 -0.9,17.9c-1.8,5 -4.8,8.3 -6.8,10.4c-5.9,5.9 -11.3,9.7 -16.7,11.7c-5.5,2 -10,1.8 -13.3,1.4c-4.4,-0.5 -9.2,-2 -14.3,-4.2l-17,17C397.5,355.7 421.5,352.7 444.6,329.6z"
|
||||
android:fillColor="#242425"/>
|
||||
<path
|
||||
android:pathData="M303.1,64.7c5,1.8 8.3,4.8 10.4,6.8c5.9,5.9 9.7,11.3 11.7,16.7c2,5.5 1.8,10 1.4,13.3c-0.5,4.4 -2,9.2 -4.2,14.3l17,17c16.4,-30.3 13.3,-54.4 -9.7,-77.4c-13.2,-13.2 -30.1,-17.8 -50.3,-13.7c-14,2.8 -24.9,9.1 -26.9,10.3L187,117.4c3.1,6 7.4,12.5 12.8,19.4L250,86.7l0,0c4.3,-4.1 13,-12.1 21.6,-17.4c5.2,-3.2 9.7,-5.1 13.5,-5.6C292,62.6 297.9,62.9 303.1,64.7z"
|
||||
android:fillColor="#242425"/>
|
||||
<path
|
||||
android:pathData="M170.4,55.4c-24.2,24.2 -26.4,49.4 -7.3,81.8c4.6,7.8 10.6,16.1 17.7,24.6c16.3,19.5 39.5,41.3 69.2,64.9c19.4,-15.4 36.2,-30.2 49.8,-43.8c6.3,-6.3 12,-12.4 17.1,-18.3l-16.2,-16.2c-5,5.9 -10.7,12.1 -17,18.4c-9,9 -19.5,18.5 -31.2,28.4l-2.5,2.1l-2.5,-2.1c-21.5,-18.1 -38.6,-35 -50.9,-50.1c-7.8,-9.6 -13.8,-18.6 -17.7,-26.7c-3.4,-7 -5.3,-13.4 -5.6,-19c-0.2,-2.7 -0.1,-6.9 2,-12.1c2.1,-5 5.8,-10.2 11.3,-15.7c2.1,-2.1 5.4,-5 10.4,-6.8c5.2,-1.9 11.1,-2.2 18,-0.9l0.1,0c3,0.6 6.4,2 10.4,4.3l18.2,-18.2c-4.8,-2.4 -13.1,-6.2 -23,-8.2C200.5,37.6 183.6,42.2 170.4,55.4z"
|
||||
android:fillColor="#242425"/>
|
||||
<path
|
||||
android:pathData="M273.2,77.6c-7.1,4.8 -14,11.1 -17.7,14.6l80.5,80.5c6.4,-5.2 12.7,-9.7 18.7,-13.6L273.2,77.6z"
|
||||
android:fillColor="#242425"/>
|
||||
<path
|
||||
android:pathData="M55.4,329.6c24.2,24.2 49.4,26.4 81.8,7.3c7.8,-4.6 16.1,-10.6 24.6,-17.7c19.5,-16.3 41.3,-39.5 64.9,-69.2c-15.4,-19.4 -30.2,-36.2 -43.8,-49.8c-6.3,-6.3 -12.4,-12 -18.3,-17.1l-16.2,16.2c5.9,5 12.1,10.7 18.4,17c9,9 18.5,19.5 28.4,31.2l2.1,2.5l-2.1,2.5c-18.1,21.5 -35,38.6 -50.1,50.9c-9.6,7.8 -18.6,13.8 -26.7,17.7c-7,3.4 -13.4,5.3 -19,5.6c-2.7,0.2 -6.9,0.1 -12.1,-2c-5,-2.1 -10.2,-5.8 -15.7,-11.3c-2.1,-2.1 -5,-5.4 -6.8,-10.4c-1.9,-5.2 -2.2,-11.1 -0.9,-18l0,-0.1c0.6,-3 2,-6.4 4.3,-10.4l-18.2,-18.2c-2.4,4.8 -6.2,13.1 -8.2,23C37.6,299.5 42.2,316.4 55.4,329.6z"
|
||||
android:fillColor="#242425"/>
|
||||
<path
|
||||
android:pathData="M86.7,250L86.7,250c-4.1,-4.4 -12,-13.1 -17.3,-21.6c-3.2,-5.2 -5.1,-9.7 -5.6,-13.5c-1.2,-6.9 -0.9,-12.7 0.9,-17.9c1.8,-5 4.8,-8.3 6.8,-10.4c5.9,-5.9 11.3,-9.7 16.7,-11.7c5.5,-2 10,-1.8 13.3,-1.4c4.4,0.5 9.2,2 14.3,4.2l17,-17c-30.3,-16.4 -54.4,-13.3 -77.4,9.7c-13.2,13.2 -17.8,30.1 -13.7,50.3c2.8,14 9.1,24.9 10.3,26.9l65.4,65.4c6,-3.1 12.5,-7.4 19.4,-12.8L86.7,250z"
|
||||
android:fillColor="#242425"/>
|
||||
<path
|
||||
android:pathData="M92.2,244.5l80.5,-80.5c-5.2,-6.4 -9.7,-12.7 -13.6,-18.7l-81.5,81.5C82.4,233.9 88.6,240.8 92.2,244.5z"
|
||||
android:fillColor="#242425"/>
|
||||
<path
|
||||
android:pathData="M329.6,444.6c24.2,-24.2 26.4,-49.4 7.3,-81.8c-4.6,-7.8 -10.6,-16.1 -17.7,-24.6c-16.3,-19.5 -39.5,-41.3 -69.2,-64.9c-19.4,15.4 -36.2,30.2 -49.8,43.8c-6.3,6.3 -12,12.4 -17.1,18.3l16.2,16.2c5,-5.9 10.7,-12.1 17,-18.4c9,-9 19.5,-18.5 31.2,-28.4l2.5,-2.1l2.5,2.1c21.5,18.1 38.6,35 50.9,50.1c7.8,9.6 13.8,18.6 17.7,26.7c3.4,7 5.3,13.4 5.6,19c0.2,2.7 0.1,6.9 -2,12.1c-2.1,5 -5.8,10.2 -11.3,15.7c-2.1,2.1 -5.4,5 -10.4,6.8c-5.2,1.9 -11.1,2.2 -18,0.9l-0.1,0c-3,-0.6 -6.4,-2 -10.4,-4.3l-18.2,18.2c4.7,2.4 13.1,6.1 22.9,8.2C299.4,462.4 316.4,457.8 329.6,444.6z"
|
||||
android:fillColor="#242425"/>
|
||||
<path
|
||||
android:pathData="M244.5,407.8L164,327.3c-6.4,5.2 -12.7,9.7 -18.7,13.6l81.5,81.5C233.9,417.6 240.8,411.4 244.5,407.8z"
|
||||
android:fillColor="#242425"/>
|
||||
<path
|
||||
android:pathData="M483.4,250c2.6,-6.3 5.3,-14 7.1,-22.7c6.3,-30.8 -1.8,-59.2 -22.7,-80.1c-19.7,-19.7 -41.7,-29.7 -65.5,-29.7c-7.5,0 -15.1,1 -22.8,3c2.9,-11.3 3.7,-22.3 2.3,-33.2c-2.5,-19.8 -12.3,-38.3 -29,-55.1C336.6,15.9 315.9,7.4 293,7.4c-6.6,0 -13.4,0.7 -20.2,2.1c-8.7,1.8 -16.5,4.5 -22.7,7.1c-6.3,-2.6 -14.1,-5.3 -22.8,-7.1c-6.9,-1.4 -13.7,-2.1 -20.2,-2.1c-22.9,0 -43.6,8.6 -59.9,24.8c-17.6,17.6 -27.5,37.2 -29.4,58.1c-0.9,9.9 0,19.9 2.7,30.2c-7.7,-2 -15.3,-3 -22.8,-3c-23.8,0 -45.8,10 -65.5,29.7c-20.9,20.9 -28.9,49.3 -22.7,80.1c1.8,8.7 4.5,16.5 7.1,22.7c-2.6,6.3 -5.3,14.1 -7.1,22.8c-6.2,30.8 1.8,59.2 22.7,80.1c19.7,19.7 41.7,29.7 65.5,29.7c0,0 0,0 0,0c7.5,0 15.1,-1 22.8,-3c-2.9,11.3 -3.7,22.3 -2.3,33.2c2.5,19.8 12.3,38.3 29,55.1c16.2,16.2 36.9,24.8 59.8,24.8c0,0 0,0 0,0c6.6,0 13.4,-0.7 20.2,-2.1c8.7,-1.8 16.5,-4.4 22.7,-7.1c6.3,2.6 14,5.3 22.7,7.1c6.9,1.4 13.7,2.1 20.3,2.1c0,0 0,0 0,0c22.9,0 43.6,-8.6 59.9,-24.8c17.6,-17.6 27.5,-37.2 29.4,-58.1c0.9,-9.9 0,-19.9 -2.7,-30.2c7.7,2 15.3,3 22.8,3c0,0 0,0 0,0c23.8,0 45.8,-10 65.5,-29.7c20.9,-20.9 29,-49.3 22.7,-80.1C488.8,264 486.1,256.3 483.4,250z"
|
||||
android:fillColor="#242425"/>
|
||||
<path
|
||||
android:pathData="M170.4,444.6c13.2,13.2 30.1,17.8 50.3,13.7c14,-2.8 24.9,-9.1 26.9,-10.3l65.4,-65.4c-3.1,-6 -7.4,-12.5 -12.8,-19.4L250,413.3l0,0c-4.3,4.1 -13,12.1 -21.6,17.4c-5.2,3.2 -9.7,5.1 -13.5,5.6c-6.9,1.2 -12.7,0.9 -17.9,-0.9c-5,-1.8 -8.3,-4.8 -10.4,-6.8c-5.9,-5.9 -9.7,-11.3 -11.7,-16.7c-2,-5.5 -1.8,-10 -1.4,-13.3c0.5,-4.4 2,-9.2 4.2,-14.3l-17,-17C144.3,397.5 147.3,421.5 170.4,444.6z"
|
||||
android:fillColor="#242425"/>
|
||||
<path
|
||||
android:pathData="M436.2,215c-0.6,3 -2,6.4 -4.3,10.4l18.2,18.2c2.4,-4.8 6.2,-13.1 8.2,-22.9c4.1,-20.2 -0.5,-37.1 -13.7,-50.3c-24.2,-24.2 -49.4,-26.4 -81.8,-7.3c-7.8,4.6 -16.1,10.6 -24.6,17.7c-19.5,16.3 -41.3,39.5 -64.9,69.2c15.4,19.4 30.2,36.2 43.8,49.8c6.3,6.3 12.4,12 18.3,17.1l16.2,-16.2c-5.9,-5 -12.1,-10.7 -18.4,-17c-9,-9 -18.5,-19.5 -28.4,-31.2l-2.1,-2.5l2.1,-2.5c18.1,-21.5 35,-38.6 50.1,-50.9c9.6,-7.8 18.6,-13.8 26.7,-17.7c7,-3.4 13.4,-5.3 19,-5.6c2.7,-0.2 6.9,-0.1 12.1,2c5,2.1 10.2,5.8 15.7,11.3c2.1,2.1 5,5.4 6.8,10.4C437.1,202.1 437.5,208 436.2,215L436.2,215z"
|
||||
android:fillColor="#FFFFFF"/>
|
||||
<path
|
||||
android:pathData="M340.9,354.7l81.5,-81.5c-4.8,-7.1 -11.1,-14 -14.6,-17.7L327.3,336C332.5,342.4 337.1,348.6 340.9,354.7z"
|
||||
android:fillColor="#FFFFFF"/>
|
||||
<path
|
||||
android:pathData="M444.6,329.6c13.2,-13.2 17.8,-30.1 13.7,-50.3c-2.8,-14 -9.1,-24.9 -10.3,-26.9L382.6,187c-6,3.1 -12.5,7.4 -19.4,12.8l50.1,50.1l0,0c4.1,4.3 12.1,13 17.4,21.6c3.2,5.2 5.1,9.7 5.6,13.5c1.2,6.9 0.9,12.7 -0.9,17.9c-1.8,5 -4.8,8.3 -6.8,10.4c-5.9,5.9 -11.3,9.7 -16.7,11.7c-5.5,2 -10,1.8 -13.3,1.4c-4.4,-0.5 -9.2,-2 -14.3,-4.2l-17,17C397.5,355.7 421.5,352.7 444.6,329.6z"
|
||||
android:fillColor="#FFFFFF"/>
|
||||
<path
|
||||
android:pathData="M303.1,64.7c5,1.8 8.3,4.8 10.4,6.8c5.9,5.9 9.7,11.3 11.7,16.7c2,5.5 1.8,10 1.4,13.3c-0.5,4.4 -2,9.2 -4.2,14.3l17,17c16.4,-30.3 13.3,-54.4 -9.7,-77.4c-13.2,-13.2 -30.1,-17.8 -50.3,-13.7c-14,2.8 -24.9,9.1 -26.9,10.3L187,117.4c3.1,6 7.4,12.5 12.8,19.4L250,86.7l0,0c4.3,-4.1 13,-12.1 21.6,-17.4c5.2,-3.2 9.7,-5.1 13.5,-5.6C292,62.6 297.9,62.9 303.1,64.7z"
|
||||
android:fillColor="#FFFFFF"/>
|
||||
<path
|
||||
android:pathData="M170.4,55.4c-24.2,24.2 -26.4,49.4 -7.3,81.8c4.6,7.8 10.6,16.1 17.7,24.6c16.3,19.5 39.5,41.3 69.2,64.9c19.4,-15.4 36.2,-30.2 49.8,-43.8c6.3,-6.3 12,-12.4 17.1,-18.3l-16.2,-16.2c-5,5.9 -10.7,12.1 -17,18.4c-9,9 -19.5,18.5 -31.2,28.4l-2.5,2.1l-2.5,-2.1c-21.5,-18.1 -38.6,-35 -50.9,-50.1c-7.8,-9.6 -13.8,-18.6 -17.7,-26.7c-3.4,-7 -5.3,-13.4 -5.6,-19c-0.2,-2.7 -0.1,-6.9 2,-12.1c2.1,-5 5.8,-10.2 11.3,-15.7c2.1,-2.1 5.4,-5 10.4,-6.8c5.2,-1.9 11.1,-2.2 18,-0.9l0.1,0c3,0.6 6.4,2 10.4,4.3l18.2,-18.2c-4.8,-2.4 -13.1,-6.2 -23,-8.2C200.5,37.6 183.6,42.2 170.4,55.4z"
|
||||
android:fillColor="#FFFFFF"/>
|
||||
<path
|
||||
android:pathData="M273.2,77.6c-7.1,4.8 -14,11.1 -17.7,14.6l80.5,80.5c6.4,-5.2 12.7,-9.7 18.7,-13.6L273.2,77.6z"
|
||||
android:fillColor="#FFFFFF"/>
|
||||
<path
|
||||
android:pathData="M55.4,329.6c24.2,24.2 49.4,26.4 81.8,7.3c7.8,-4.6 16.1,-10.6 24.6,-17.7c19.5,-16.3 41.3,-39.5 64.9,-69.2c-15.4,-19.4 -30.2,-36.2 -43.8,-49.8c-6.3,-6.3 -12.4,-12 -18.3,-17.1l-16.2,16.2c5.9,5 12.1,10.7 18.4,17c9,9 18.5,19.5 28.4,31.2l2.1,2.5l-2.1,2.5c-18.1,21.5 -35,38.6 -50.1,50.9c-9.6,7.8 -18.6,13.8 -26.7,17.7c-7,3.4 -13.4,5.3 -19,5.6c-2.7,0.2 -6.9,0.1 -12.1,-2c-5,-2.1 -10.2,-5.8 -15.7,-11.3c-2.1,-2.1 -5,-5.4 -6.8,-10.4c-1.9,-5.2 -2.2,-11.1 -0.9,-18l0,-0.1c0.6,-3 2,-6.4 4.3,-10.4l-18.2,-18.2c-2.4,4.8 -6.2,13.1 -8.2,23C37.6,299.5 42.2,316.4 55.4,329.6z"
|
||||
android:fillColor="#FFFFFF"/>
|
||||
<path
|
||||
android:pathData="M86.7,250L86.7,250c-4.1,-4.4 -12,-13.1 -17.3,-21.6c-3.2,-5.2 -5.1,-9.7 -5.6,-13.5c-1.2,-6.9 -0.9,-12.7 0.9,-17.9c1.8,-5 4.8,-8.3 6.8,-10.4c5.9,-5.9 11.3,-9.7 16.7,-11.7c5.5,-2 10,-1.8 13.3,-1.4c4.4,0.5 9.2,2 14.3,4.2l17,-17c-30.3,-16.4 -54.4,-13.3 -77.4,9.7c-13.2,13.2 -17.8,30.1 -13.7,50.3c2.8,14 9.1,24.9 10.3,26.9l65.4,65.4c6,-3.1 12.5,-7.4 19.4,-12.8L86.7,250z"
|
||||
android:fillColor="#FFFFFF"/>
|
||||
<path
|
||||
android:pathData="M92.2,244.5l80.5,-80.5c-5.2,-6.4 -9.7,-12.7 -13.6,-18.7l-81.5,81.5C82.4,233.9 88.6,240.8 92.2,244.5z"
|
||||
android:fillColor="#FFFFFF"/>
|
||||
<path
|
||||
android:pathData="M329.6,444.6c24.2,-24.2 26.4,-49.4 7.3,-81.8c-4.6,-7.8 -10.6,-16.1 -17.7,-24.6c-16.3,-19.5 -39.5,-41.3 -69.2,-64.9c-19.4,15.4 -36.2,30.2 -49.8,43.8c-6.3,6.3 -12,12.4 -17.1,18.3l16.2,16.2c5,-5.9 10.7,-12.1 17,-18.4c9,-9 19.5,-18.5 31.2,-28.4l2.5,-2.1l2.5,2.1c21.5,18.1 38.6,35 50.9,50.1c7.8,9.6 13.8,18.6 17.7,26.7c3.4,7 5.3,13.4 5.6,19c0.2,2.7 0.1,6.9 -2,12.1c-2.1,5 -5.8,10.2 -11.3,15.7c-2.1,2.1 -5.4,5 -10.4,6.8c-5.2,1.9 -11.1,2.2 -18,0.9l-0.1,0c-3,-0.6 -6.4,-2 -10.4,-4.3l-18.2,18.2c4.7,2.4 13.1,6.1 22.9,8.2C299.4,462.4 316.4,457.8 329.6,444.6z"
|
||||
android:fillColor="#FFFFFF"/>
|
||||
<path
|
||||
android:pathData="M244.5,407.8L164,327.3c-6.4,5.2 -12.7,9.7 -18.7,13.6l81.5,81.5C233.9,417.6 240.8,411.4 244.5,407.8z"
|
||||
android:fillColor="#FFFFFF"/>
|
||||
<path
|
||||
android:pathData="M170.4,444.6c13.2,13.2 30.1,17.8 50.3,13.7c14,-2.8 24.9,-9.1 26.9,-10.3l65.4,-65.4c-3.1,-6 -7.4,-12.5 -12.8,-19.4L250,413.3l0,0c-4.3,4.1 -13,12.1 -21.6,17.4c-5.2,3.2 -9.7,5.1 -13.5,5.6c-6.9,1.2 -12.7,0.9 -17.9,-0.9c-5,-1.8 -8.3,-4.8 -10.4,-6.8c-5.9,-5.9 -9.7,-11.3 -11.7,-16.7c-2,-5.5 -1.8,-10 -1.4,-13.3c0.5,-4.4 2,-9.2 4.2,-14.3l-17,-17C144.3,397.5 147.3,421.5 170.4,444.6z"
|
||||
android:fillColor="#FFFFFF"/>
|
||||
</vector>
|
|
@ -1,12 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Modify this file to customize your launch splash screen -->
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@android:color/white" />
|
||||
<item android:drawable="@color/darkGreyPurple" />
|
||||
|
||||
<!-- You can insert your own image assets here -->
|
||||
<!-- <item>
|
||||
<bitmap
|
||||
android:gravity="center"
|
||||
android:src="@mipmap/launch_image" />
|
||||
</item> -->
|
||||
<item android:drawable="@drawable/knott"
|
||||
android:gravity="center"
|
||||
/>
|
||||
</layer-list>
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<com.airbnb.lottie.LottieAnimationView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:lottie_autoPlay="true"
|
||||
app:lottie_rawRes="@raw/cwtch_animated_logo_op"
|
||||
app:lottie_loop="true"
|
||||
app:lottie_speed="1.00"
|
||||
app:lottie_enableMergePathsForKitKatAndAbove="true" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@color/ic_launcher_background"/>
|
||||
<foreground android:drawable="@drawable/knott"/>
|
||||
</adaptive-icon>
|
Binary file not shown.
Before Width: | Height: | Size: 544 B |
Binary file not shown.
Before Width: | Height: | Size: 442 B |
Binary file not shown.
Before Width: | Height: | Size: 721 B |
Binary file not shown.
Before Width: | Height: | Size: 1.0 KiB |
Binary file not shown.
Before Width: | Height: | Size: 1.4 KiB |
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
|
||||
<item name="android:windowSplashScreenBackground">@color/darkGreyPurple</item>
|
||||
<item name="android:windowSplashScreenAnimatedIcon">@drawable/knott</item>
|
||||
<item name="android:windowSplashScreenIconBackgroundColor">@color/darkGreyPurple</item>
|
||||
</style>
|
||||
|
||||
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
|
||||
<item name="android:windowBackground">?android:colorBackground</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
|
@ -0,0 +1,5 @@
|
|||
<resources>
|
||||
<color name="darkGreyPurple">#281831</color>
|
||||
<color name="testGreen">#00ff00</color>
|
||||
<color name="ic_launcher_background">@color/darkGreyPurple</color>
|
||||
</resources>
|
|
@ -1,18 +1,23 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on -->
|
||||
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
|
||||
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
|
||||
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
|
||||
<!-- Show a splash screen on the activity. Automatically removed when
|
||||
Flutter draws its first frame -->
|
||||
the Flutter engine draws its first frame -->
|
||||
<item name="android:windowBackground">@drawable/launch_background</item>
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- Theme applied to the Android Window as soon as the process has started.
|
||||
This theme determines the color of the Android Window while your
|
||||
Flutter UI initializes, as well as behind your Flutter UI while its
|
||||
running.
|
||||
|
||||
|
||||
This Theme is only used starting with V2 of Flutter's Android embedding. -->
|
||||
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
|
||||
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
|
||||
<item name="android:windowBackground">?android:colorBackground</item>
|
||||
</style>
|
||||
</resources>
|
||||
</resources>
|
|
@ -1,18 +1,3 @@
|
|||
buildscript {
|
||||
ext.kotlin_version = '1.8.21'
|
||||
repositories {
|
||||
google()
|
||||
// jCenter() no longer exists... https://blog.gradle.org/jcenter-shutdown
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:7.0.0'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
google()
|
||||
|
@ -28,7 +13,6 @@ subprojects {
|
|||
project.evaluationDependsOn(':app')
|
||||
}
|
||||
|
||||
//removed due to gradle namespace conflicts that are beyond erinn's mere mortal understanding
|
||||
//task clean(type: Delete) {
|
||||
// delete rootProject.buildDir
|
||||
//}
|
||||
tasks.register("clean", Delete) {
|
||||
delete rootProject.buildDir
|
||||
}
|
||||
|
|
|
@ -1,11 +1,25 @@
|
|||
include ':app', ':cwtch'
|
||||
pluginManagement {
|
||||
def flutterSdkPath = {
|
||||
def properties = new Properties()
|
||||
file("local.properties").withInputStream { properties.load(it) }
|
||||
def flutterSdkPath = properties.getProperty("flutter.sdk")
|
||||
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
|
||||
return flutterSdkPath
|
||||
}()
|
||||
|
||||
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
|
||||
def properties = new Properties()
|
||||
includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
|
||||
|
||||
assert localPropertiesFile.exists()
|
||||
localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
gradlePluginPortal()
|
||||
}
|
||||
}
|
||||
|
||||
def flutterSdkPath = properties.getProperty("flutter.sdk")
|
||||
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
|
||||
apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
|
||||
plugins {
|
||||
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
|
||||
id "com.android.application" version "7.4.2" apply false
|
||||
id "org.jetbrains.kotlin.android" version "1.8.21" apply false
|
||||
}
|
||||
|
||||
include ":app"
|
||||
|
|
|
@ -3,6 +3,6 @@
|
|||
VERSION=`cat LIBCWTCH-GO.version`
|
||||
echo $VERSION
|
||||
|
||||
curl --fail https://build.openprivacy.ca/files/libCwtch-autobindings-$VERSION/android/cwtch.aar --output android/cwtch/cwtch.aar
|
||||
curl --fail https://build.openprivacy.ca/files/libCwtch-autobindings-$VERSION/android/cwtch.aar --output android/app/cwtch/cwtch.aar
|
||||
# FIXME...at some point we need to support different linux architectures...for now rely on existing expectations and rename x64 lib
|
||||
curl --fail https://build.openprivacy.ca/files/libCwtch-autobindings-$VERSION/linux/libCwtch.x64.so --output linux/libCwtch.so
|
||||
curl --fail https://build.openprivacy.ca/files/libCwtch-autobindings-$VERSION/linux/libCwtch.x64.so --output linux/libCwtch.so
|
||||
|
|
|
@ -1,17 +1,8 @@
|
|||
import 'package:cwtch/main.dart';
|
||||
import 'package:cwtch/widgets/messagebubble.dart';
|
||||
import 'package:cwtch/widgets/profilerow.dart';
|
||||
import 'package:cwtch/widgets/quotedmessage.dart';
|
||||
import 'package:cwtch/widgets/tor_icon.dart';
|
||||
import 'package:cwtch/views/profilemgrview.dart';
|
||||
import 'package:flutter_gherkin/flutter_gherkin.dart';
|
||||
import 'package:flutter_gherkin/src/flutter/parameters/existence_parameter.dart';
|
||||
import 'package:flutter_gherkin/src/flutter/parameters/swipe_direction_parameter.dart';
|
||||
import 'package:gherkin/gherkin.dart';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'overrides.dart';
|
||||
|
||||
StepDefinitionGeneric ExpectReply() {
|
||||
return given3<String, String, int, FlutterWorld>(
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_driver/flutter_driver.dart';
|
||||
import 'package:flutter_gherkin/flutter_gherkin.dart';
|
||||
import 'package:gherkin/gherkin.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
|
||||
enum SwitchState { checked, unchecked }
|
||||
|
||||
|
@ -17,6 +14,7 @@ class SwitchStateParameter extends CustomParameter<SwitchState> {
|
|||
case "unchecked":
|
||||
return SwitchState.unchecked;
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import 'package:cwtch/themes/opaque.dart';
|
||||
import 'package:cwtch/third_party/linkify/linkify.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
|
@ -38,7 +37,7 @@ void modalOpenLink(BuildContext ctx, LinkableElement link) {
|
|||
final snackBar = SnackBar(
|
||||
content: Text(
|
||||
AppLocalizations.of(bcontext)!.copiedToClipboardNotification,
|
||||
style: Provider.of<Settings>(bcontext).scaleFonts(defaultTextButtonStyle),
|
||||
style: Provider.of<Settings>(bcontext, listen: false).scaleFonts(defaultTextButtonStyle),
|
||||
),
|
||||
);
|
||||
|
||||
|
|
|
@ -11,8 +11,6 @@ abstract class Cwtch {
|
|||
|
||||
// ignore: non_constant_identifier_names
|
||||
Future<void> Start();
|
||||
// ignore: non_constant_identifier_names
|
||||
Future<void> ReconnectCwtchForeground();
|
||||
|
||||
Future<String> getCwtchDir();
|
||||
|
||||
|
|
|
@ -3,15 +3,10 @@ import 'package:cwtch/cwtch/cwtch.dart';
|
|||
import 'package:cwtch/main.dart';
|
||||
import 'package:cwtch/models/appstate.dart';
|
||||
import 'package:cwtch/models/contact.dart';
|
||||
import 'package:cwtch/models/message.dart';
|
||||
import 'package:cwtch/models/profilelist.dart';
|
||||
import 'package:cwtch/models/profileservers.dart';
|
||||
import 'package:cwtch/models/remoteserver.dart';
|
||||
import 'package:cwtch/models/servers.dart';
|
||||
import 'package:cwtch/notification_manager.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import 'package:cwtch/torstatus.dart';
|
||||
|
||||
|
@ -63,7 +58,14 @@ class CwtchNotifier {
|
|||
// EnvironmentConfig.debugLog("NewEvent $type $data");
|
||||
switch (type) {
|
||||
case "CwtchStarted":
|
||||
flwtchState.cwtch.LoadProfiles(DefaultPassword);
|
||||
if (data["Reload"] == "true" && profileCN.num > 0) {
|
||||
// don't reload...
|
||||
// unless we have loaded no profiles...then there isnt a risk and this
|
||||
// might be a first time (e.g. new apk, existing service)
|
||||
} else {
|
||||
flwtchState.cwtch.LoadProfiles(DefaultPassword);
|
||||
}
|
||||
|
||||
appState.SetCwtchInit();
|
||||
break;
|
||||
case "CwtchStartError":
|
||||
|
@ -193,21 +195,9 @@ class CwtchNotifier {
|
|||
var senderImage = data['picture'];
|
||||
var isAuto = data['Auto'] == "true";
|
||||
String contenthash = data['ContentHash'];
|
||||
|
||||
var selectedProfile = appState.selectedProfile == data["ProfileOnion"];
|
||||
var selectedConversation = selectedProfile && appState.selectedConversation == identifier;
|
||||
var notification = data["notification"];
|
||||
|
||||
if (selectedConversation && seenMessageCallback != null) {
|
||||
seenMessageCallback!(data["ProfileOnion"]!, identifier, DateTime.now().toUtc());
|
||||
}
|
||||
|
||||
if (notification == "SimpleEvent") {
|
||||
notificationManager.notify(notificationSimple ?? "New Message", "", 0);
|
||||
} else if (notification == "ContactInfo") {
|
||||
var contact = profileCN.getProfile(data["ProfileOnion"])?.contactList.getContact(identifier);
|
||||
notificationManager.notify((notificationConversationInfo ?? "New Message from %1").replaceFirst("%1", (contact?.nickname ?? senderHandle.toString())), data["ProfileOnion"], identifier);
|
||||
}
|
||||
|
||||
profileCN.getProfile(data["ProfileOnion"])?.newMessage(
|
||||
identifier,
|
||||
messageID,
|
||||
|
@ -220,6 +210,19 @@ class CwtchNotifier {
|
|||
selectedProfile,
|
||||
selectedConversation,
|
||||
);
|
||||
|
||||
// Now perform the notification logic...
|
||||
var notification = data["notification"];
|
||||
if (selectedConversation && seenMessageCallback != null) {
|
||||
seenMessageCallback!(data["ProfileOnion"]!, identifier, DateTime.now().toUtc());
|
||||
}
|
||||
|
||||
if (notification == "SimpleEvent") {
|
||||
notificationManager.notify(notificationSimple ?? "New Message", "", 0);
|
||||
} else if (notification == "ContactInfo") {
|
||||
var contact = profileCN.getProfile(data["ProfileOnion"])?.contactList.getContact(identifier);
|
||||
notificationManager.notify((notificationConversationInfo ?? "New Message from %1").replaceFirst("%1", (contact?.nickname ?? senderHandle.toString())), data["ProfileOnion"], identifier);
|
||||
}
|
||||
appState.notifyProfileUnread();
|
||||
break;
|
||||
case "PeerAcknowledgement":
|
||||
|
@ -254,7 +257,7 @@ class CwtchNotifier {
|
|||
var notification = data["notification"];
|
||||
|
||||
// Only bother to do anything if we know about the group and the provided index is greater than our current total...
|
||||
if (currentTotal != null && idx >= currentTotal) {
|
||||
if (idx >= currentTotal) {
|
||||
// TODO: There are 2 timestamps associated with a new group message - time sent and time received.
|
||||
// Sent refers to the time a profile alleges they sent a message
|
||||
// Received refers to the time we actually saw the message from the server
|
||||
|
@ -302,6 +305,7 @@ class CwtchNotifier {
|
|||
break;
|
||||
case "UpdateGlobalSettings":
|
||||
settings.handleUpdate(jsonDecode(data["Data"]));
|
||||
appState.settingsLoaded = true;
|
||||
break;
|
||||
case "UpdatedProfileAttribute":
|
||||
if (data["Key"] == "public.profile.name") {
|
||||
|
@ -346,7 +350,7 @@ class CwtchNotifier {
|
|||
associatedGroups.forEach((identifier) {
|
||||
profileCN.getProfile(data["ProfileOnion"])?.contactList.getContact(int.parse(identifier.toString()))!.antispamTickets = count;
|
||||
});
|
||||
EnvironmentConfig.debugLog("update server token count for ${associatedGroups}, $count");
|
||||
EnvironmentConfig.debugLog("update server token count for $associatedGroups, $count");
|
||||
} catch (e) {
|
||||
// No tokens in data...
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@ import 'dart:convert';
|
|||
import 'dart:ffi';
|
||||
import 'dart:io';
|
||||
import 'dart:isolate';
|
||||
import 'dart:io' show Platform;
|
||||
import 'package:cwtch/cwtch/cwtchNotifier.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
|
||||
|
@ -13,7 +12,6 @@ import 'package:cwtch/cwtch/cwtch.dart';
|
|||
import '../config.dart';
|
||||
|
||||
import "package:path/path.dart" show dirname, join;
|
||||
import 'dart:io' show Platform;
|
||||
|
||||
/////////////////////
|
||||
/// Cwtch API ///
|
||||
|
@ -272,14 +270,6 @@ class CwtchFfi implements Cwtch {
|
|||
return _cwtchDir;
|
||||
}
|
||||
|
||||
// ignore: non_constant_identifier_names
|
||||
Future<void> ReconnectCwtchForeground() async {
|
||||
var reconnectCwtch = library.lookup<NativeFunction<Void Function()>>("c_ReconnectCwtchForeground");
|
||||
// ignore: non_constant_identifier_names
|
||||
final ReconnectCwtchForeground = reconnectCwtch.asFunction<void Function()>();
|
||||
ReconnectCwtchForeground();
|
||||
}
|
||||
|
||||
// Called on object being disposed to (presumably on app close) to close the isolate that's listening to libcwtch-go events
|
||||
@override
|
||||
void dispose() {
|
||||
|
|
|
@ -77,7 +77,7 @@ class CwtchGomobile implements Cwtch {
|
|||
Future<void> Start() async {
|
||||
print("gomobile.dart: Start()...");
|
||||
androidHomeDirectoryStr = (await androidHomeDirectory).path;
|
||||
_cwtchDir = path.join(await androidHomeDirectoryStr, ".cwtch");
|
||||
_cwtchDir = path.join(androidHomeDirectoryStr, ".cwtch");
|
||||
if (EnvironmentConfig.BUILD_VER == dev_version) {
|
||||
_cwtchDir = path.join(_cwtchDir, "dev");
|
||||
}
|
||||
|
@ -86,12 +86,6 @@ class CwtchGomobile implements Cwtch {
|
|||
cwtchPlatform.invokeMethod("Start", {"appDir": _cwtchDir, "torPath": torPath});
|
||||
}
|
||||
|
||||
@override
|
||||
// ignore: non_constant_identifier_names
|
||||
Future<void> ReconnectCwtchForeground() async {
|
||||
cwtchPlatform.invokeMethod("ReconnectCwtchForeground", {});
|
||||
}
|
||||
|
||||
// Handle libcwtch-go events (received via kotlin) and dispatch to the cwtchNotifier
|
||||
Future<void> _handleAppbusEvent(MethodCall call) async {
|
||||
final String json = call.arguments;
|
||||
|
|
|
@ -648,4 +648,20 @@ class MaterialLocalizationLu extends MaterialLocalizations {
|
|||
@override
|
||||
// TODO: implement scanTextButtonLabel
|
||||
String get scanTextButtonLabel => throw UnimplementedError();
|
||||
|
||||
@override
|
||||
// TODO: implement lookUpButtonLabel
|
||||
String get lookUpButtonLabel => throw UnimplementedError();
|
||||
|
||||
@override
|
||||
// TODO: implement menuDismissLabel
|
||||
String get menuDismissLabel => throw UnimplementedError();
|
||||
|
||||
@override
|
||||
// TODO: implement searchWebButtonLabel
|
||||
String get searchWebButtonLabel => throw UnimplementedError();
|
||||
|
||||
@override
|
||||
// TODO: implement shareButtonLabel
|
||||
String get shareButtonLabel => throw UnimplementedError();
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
{
|
||||
"@@locale": "cy",
|
||||
"@@last_modified": "2024-02-08T10:33:11+01:00",
|
||||
"@@last_modified": "2024-02-12T08:05:24+01:00",
|
||||
"settingsExperimentsShowPerformanceDescription": "Display an overlay graph of render time.",
|
||||
"settingsExperimentsShowPerformanceTitle": "Show Performance Overlay",
|
||||
"settingsImportThemeButton": "Import Theme",
|
||||
"settingsImportThemeDescription": "Select theme directory to import for use in Cwtch",
|
||||
"settingsImportThemeTitle": "Import Theme",
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
{
|
||||
"@@locale": "da",
|
||||
"@@last_modified": "2024-02-08T10:33:11+01:00",
|
||||
"@@last_modified": "2024-02-12T08:05:24+01:00",
|
||||
"settingsExperimentsShowPerformanceDescription": "Display an overlay graph of render time.",
|
||||
"settingsExperimentsShowPerformanceTitle": "Show Performance Overlay",
|
||||
"settingsImportThemeButton": "Import Theme",
|
||||
"settingsImportThemeDescription": "Select theme directory to import for use in Cwtch",
|
||||
"settingsImportThemeTitle": "Import Theme",
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
{
|
||||
"@@locale": "de",
|
||||
"@@last_modified": "2024-02-08T10:33:11+01:00",
|
||||
"@@last_modified": "2024-02-12T08:05:24+01:00",
|
||||
"settingsExperimentsShowPerformanceTitle": "Leistungs-Overlay anzeigen",
|
||||
"settingsExperimentsShowPerformanceDescription": "Zeigt ein Overlay-Diagramm der Renderzeit an.",
|
||||
"defaultScalingText": "Text in Standardgröße (Skalierungsfaktor:",
|
||||
"deleteServerConfirmBtn": "Server wirklich löschen",
|
||||
"groupsOnThisServerLabel": "Gruppen, in denen ich bin, werden auf diesem Server gehostet",
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
{
|
||||
"@@locale": "el",
|
||||
"@@last_modified": "2024-02-08T10:33:11+01:00",
|
||||
"@@last_modified": "2024-02-12T08:05:24+01:00",
|
||||
"settingsExperimentsShowPerformanceDescription": "Display an overlay graph of render time.",
|
||||
"settingsExperimentsShowPerformanceTitle": "Show Performance Overlay",
|
||||
"settingsImportThemeButton": "Import Theme",
|
||||
"settingsImportThemeDescription": "Select theme directory to import for use in Cwtch",
|
||||
"settingsImportThemeTitle": "Import Theme",
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
{
|
||||
"@@locale": "en",
|
||||
"@@last_modified": "2024-02-08T10:33:11+01:00",
|
||||
"@@last_modified": "2024-02-12T08:05:24+01:00",
|
||||
"settingsExperimentsShowPerformanceDescription": "Display an overlay graph of render time.",
|
||||
"settingsExperimentsShowPerformanceTitle": "Show Performance Overlay",
|
||||
"settingThemeOverwriteConfirm": "Confirm",
|
||||
"settingThemeOverwriteQuestion": "Theme $themeName already exists, confirm overwrite?",
|
||||
"settingsThemeErrorInvalid": "Error: Could not import $themeName, theme.yml missing, not a theme directory",
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
{
|
||||
"@@locale": "es",
|
||||
"@@last_modified": "2024-02-08T10:33:11+01:00",
|
||||
"@@last_modified": "2024-02-12T08:05:24+01:00",
|
||||
"settingsExperimentsShowPerformanceDescription": "Display an overlay graph of render time.",
|
||||
"settingsExperimentsShowPerformanceTitle": "Show Performance Overlay",
|
||||
"settingsImportThemeButton": "Import Theme",
|
||||
"settingsImportThemeDescription": "Select theme directory to import for use in Cwtch",
|
||||
"settingsImportThemeTitle": "Import Theme",
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
{
|
||||
"@@locale": "fr",
|
||||
"@@last_modified": "2024-02-08T10:33:11+01:00",
|
||||
"@@last_modified": "2024-02-12T08:05:24+01:00",
|
||||
"settingsExperimentsShowPerformanceDescription": "Display an overlay graph of render time.",
|
||||
"settingsExperimentsShowPerformanceTitle": "Show Performance Overlay",
|
||||
"settingsImportThemeButton": "Import Theme",
|
||||
"settingsImportThemeDescription": "Select theme directory to import for use in Cwtch",
|
||||
"settingsImportThemeTitle": "Import Theme",
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
{
|
||||
"@@locale": "it",
|
||||
"@@last_modified": "2024-02-08T10:33:11+01:00",
|
||||
"@@last_modified": "2024-02-12T08:05:24+01:00",
|
||||
"settingsExperimentsShowPerformanceDescription": "Display an overlay graph of render time.",
|
||||
"settingsExperimentsShowPerformanceTitle": "Show Performance Overlay",
|
||||
"settingsImportThemeButton": "Import Theme",
|
||||
"settingsImportThemeDescription": "Select theme directory to import for use in Cwtch",
|
||||
"settingsImportThemeTitle": "Import Theme",
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
{
|
||||
"@@locale": "ja",
|
||||
"@@last_modified": "2024-02-08T10:33:11+01:00",
|
||||
"@@last_modified": "2024-02-12T08:05:24+01:00",
|
||||
"settingsExperimentsShowPerformanceDescription": "Display an overlay graph of render time.",
|
||||
"settingsExperimentsShowPerformanceTitle": "Show Performance Overlay",
|
||||
"settingsImportThemeButton": "Import Theme",
|
||||
"settingsImportThemeDescription": "Select theme directory to import for use in Cwtch",
|
||||
"settingsImportThemeTitle": "Import Theme",
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
{
|
||||
"@@locale": "ko",
|
||||
"@@last_modified": "2024-02-08T10:33:11+01:00",
|
||||
"@@last_modified": "2024-02-12T08:05:24+01:00",
|
||||
"settingsExperimentsShowPerformanceDescription": "Display an overlay graph of render time.",
|
||||
"settingsExperimentsShowPerformanceTitle": "Show Performance Overlay",
|
||||
"sendAnInvitation": "초대를 보냈습니다: ",
|
||||
"sendInvite": "연락처 또는 그룹 초대 보내기",
|
||||
"pasteAddressToAddContact": "Paste a cwtch address, invitation or key bundle here to add a new conversation",
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
{
|
||||
"@@locale": "lb",
|
||||
"@@last_modified": "2024-02-08T10:33:11+01:00",
|
||||
"@@last_modified": "2024-02-12T08:05:24+01:00",
|
||||
"settingsExperimentsShowPerformanceDescription": "Display an overlay graph of render time.",
|
||||
"settingsExperimentsShowPerformanceTitle": "Show Performance Overlay",
|
||||
"settingsImportThemeButton": "Import Theme",
|
||||
"settingsImportThemeDescription": "Select theme directory to import for use in Cwtch",
|
||||
"settingsImportThemeTitle": "Import Theme",
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
{
|
||||
"@@locale": "nl",
|
||||
"@@last_modified": "2024-02-08T10:33:11+01:00",
|
||||
"@@last_modified": "2024-02-12T08:05:24+01:00",
|
||||
"settingsExperimentsShowPerformanceDescription": "Display an overlay graph of render time.",
|
||||
"settingsExperimentsShowPerformanceTitle": "Show Performance Overlay",
|
||||
"settingsImportThemeButton": "Import Theme",
|
||||
"settingsImportThemeDescription": "Select theme directory to import for use in Cwtch",
|
||||
"settingsImportThemeTitle": "Import Theme",
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
{
|
||||
"@@locale": "no",
|
||||
"@@last_modified": "2024-02-08T10:33:11+01:00",
|
||||
"@@last_modified": "2024-02-12T08:05:24+01:00",
|
||||
"settingsExperimentsShowPerformanceDescription": "Display an overlay graph of render time.",
|
||||
"settingsExperimentsShowPerformanceTitle": "Show Performance Overlay",
|
||||
"settingsImportThemeButton": "Import Theme",
|
||||
"settingsImportThemeDescription": "Select theme directory to import for use in Cwtch",
|
||||
"settingsImportThemeTitle": "Import Theme",
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
{
|
||||
"@@locale": "pl",
|
||||
"@@last_modified": "2024-02-08T10:33:11+01:00",
|
||||
"@@last_modified": "2024-02-12T08:05:24+01:00",
|
||||
"settingsExperimentsShowPerformanceDescription": "Display an overlay graph of render time.",
|
||||
"settingsExperimentsShowPerformanceTitle": "Show Performance Overlay",
|
||||
"settingsImportThemeButton": "Import Theme",
|
||||
"settingsImportThemeDescription": "Select theme directory to import for use in Cwtch",
|
||||
"settingsImportThemeTitle": "Import Theme",
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
{
|
||||
"@@locale": "pt",
|
||||
"@@last_modified": "2024-02-08T10:33:11+01:00",
|
||||
"@@last_modified": "2024-02-12T08:05:24+01:00",
|
||||
"settingsExperimentsShowPerformanceDescription": "Display an overlay graph of render time.",
|
||||
"settingsExperimentsShowPerformanceTitle": "Show Performance Overlay",
|
||||
"settingsImportThemeButton": "Import Theme",
|
||||
"settingsImportThemeDescription": "Select theme directory to import for use in Cwtch",
|
||||
"settingsImportThemeTitle": "Import Theme",
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
{
|
||||
"@@locale": "pt_BR",
|
||||
"@@last_modified": "2024-02-08T10:33:11+01:00",
|
||||
"@@last_modified": "2024-02-12T08:05:24+01:00",
|
||||
"settingsExperimentsShowPerformanceDescription": "Display an overlay graph of render time.",
|
||||
"settingsExperimentsShowPerformanceTitle": "Show Performance Overlay",
|
||||
"settingsImportThemeButton": "Import Theme",
|
||||
"settingsImportThemeDescription": "Select theme directory to import for use in Cwtch",
|
||||
"settingsImportThemeTitle": "Import Theme",
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
{
|
||||
"@@locale": "ro",
|
||||
"@@last_modified": "2024-02-08T10:33:11+01:00",
|
||||
"@@last_modified": "2024-02-12T08:05:24+01:00",
|
||||
"settingsExperimentsShowPerformanceDescription": "Display an overlay graph of render time.",
|
||||
"settingsExperimentsShowPerformanceTitle": "Show Performance Overlay",
|
||||
"settingsImportThemeButton": "Import Theme",
|
||||
"settingsImportThemeDescription": "Select theme directory to import for use in Cwtch",
|
||||
"settingsImportThemeTitle": "Import Theme",
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
{
|
||||
"@@locale": "ru",
|
||||
"@@last_modified": "2024-02-08T10:33:11+01:00",
|
||||
"@@last_modified": "2024-02-12T08:05:24+01:00",
|
||||
"settingsExperimentsShowPerformanceDescription": "Display an overlay graph of render time.",
|
||||
"settingsExperimentsShowPerformanceTitle": "Show Performance Overlay",
|
||||
"settingsImportThemeButton": "Import Theme",
|
||||
"settingsImportThemeDescription": "Select theme directory to import for use in Cwtch",
|
||||
"settingsImportThemeTitle": "Import Theme",
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
{
|
||||
"@@locale": "sk",
|
||||
"@@last_modified": "2024-02-08T10:33:11+01:00",
|
||||
"@@last_modified": "2024-02-12T08:05:24+01:00",
|
||||
"settingsExperimentsShowPerformanceDescription": "Display an overlay graph of render time.",
|
||||
"settingsExperimentsShowPerformanceTitle": "Show Performance Overlay",
|
||||
"settingsImportThemeButton": "Import Theme",
|
||||
"settingsImportThemeDescription": "Select theme directory to import for use in Cwtch",
|
||||
"settingsImportThemeTitle": "Import Theme",
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
{
|
||||
"@@locale": "sv",
|
||||
"@@last_modified": "2024-02-08T10:33:11+01:00",
|
||||
"@@last_modified": "2024-02-12T08:05:24+01:00",
|
||||
"settingsExperimentsShowPerformanceDescription": "Display an overlay graph of render time.",
|
||||
"settingsExperimentsShowPerformanceTitle": "Show Performance Overlay",
|
||||
"settingsImportThemeButton": "Import Theme",
|
||||
"settingsImportThemeDescription": "Select theme directory to import for use in Cwtch",
|
||||
"settingsImportThemeTitle": "Import Theme",
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
{
|
||||
"@@locale": "sw",
|
||||
"@@last_modified": "2024-02-08T10:33:11+01:00",
|
||||
"@@last_modified": "2024-02-12T08:05:24+01:00",
|
||||
"settingsExperimentsShowPerformanceDescription": "Display an overlay graph of render time.",
|
||||
"settingsExperimentsShowPerformanceTitle": "Show Performance Overlay",
|
||||
"settingsImportThemeButton": "Import Theme",
|
||||
"settingsImportThemeDescription": "Select theme directory to import for use in Cwtch",
|
||||
"settingsImportThemeTitle": "Import Theme",
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
{
|
||||
"@@locale": "tr",
|
||||
"@@last_modified": "2024-02-08T10:33:11+01:00",
|
||||
"@@last_modified": "2024-02-12T08:05:24+01:00",
|
||||
"settingsExperimentsShowPerformanceDescription": "Display an overlay graph of render time.",
|
||||
"settingsExperimentsShowPerformanceTitle": "Show Performance Overlay",
|
||||
"settingsImportThemeButton": "Import Theme",
|
||||
"settingsImportThemeDescription": "Select theme directory to import for use in Cwtch",
|
||||
"settingsImportThemeTitle": "Import Theme",
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
{
|
||||
"@@locale": "uk",
|
||||
"@@last_modified": "2024-02-08T10:33:11+01:00",
|
||||
"@@last_modified": "2024-02-12T08:05:24+01:00",
|
||||
"settingsExperimentsShowPerformanceDescription": "Display an overlay graph of render time.",
|
||||
"settingsExperimentsShowPerformanceTitle": "Show Performance Overlay",
|
||||
"settingsImportThemeButton": "Import Theme",
|
||||
"settingsImportThemeDescription": "Select theme directory to import for use in Cwtch",
|
||||
"settingsImportThemeTitle": "Import Theme",
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
{
|
||||
"@@locale": "uz",
|
||||
"@@last_modified": "2024-02-08T10:33:11+01:00",
|
||||
"@@last_modified": "2024-02-12T08:05:24+01:00",
|
||||
"settingsExperimentsShowPerformanceDescription": "Display an overlay graph of render time.",
|
||||
"settingsExperimentsShowPerformanceTitle": "Show Performance Overlay",
|
||||
"settingsImportThemeButton": "Import Theme",
|
||||
"settingsImportThemeDescription": "Select theme directory to import for use in Cwtch",
|
||||
"settingsImportThemeTitle": "Import Theme",
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:isolate';
|
||||
import 'package:cwtch/config.dart';
|
||||
import 'package:cwtch/notification_manager.dart';
|
||||
import 'package:cwtch/themes/cwtch.dart';
|
||||
import 'package:cwtch/views/doublecolview.dart';
|
||||
import 'package:cwtch/views/messageview.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
@ -33,9 +31,7 @@ import 'themes/opaque.dart';
|
|||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
import 'package:connectivity_plus/connectivity_plus.dart';
|
||||
|
||||
import 'package:intl/intl.dart' as intl;
|
||||
|
||||
var globalSettings = Settings(Locale("en", ''), CwtchDark());
|
||||
var globalSettings = Settings(Locale("en", ''));
|
||||
var globalErrorHandler = ErrorHandler();
|
||||
var globalTorStatus = TorStatus();
|
||||
var globalAppState = AppState();
|
||||
|
@ -80,7 +76,7 @@ class FlwtchState extends State<Flwtch> with WindowListener {
|
|||
@override
|
||||
initState() {
|
||||
print("initState() started, setting up handlers");
|
||||
globalSettings = Settings(Locale("en", ''), CwtchDark());
|
||||
globalSettings = Settings(Locale("en", ''));
|
||||
globalErrorHandler = ErrorHandler();
|
||||
globalTorStatus = TorStatus();
|
||||
globalAppState = AppState();
|
||||
|
@ -107,11 +103,14 @@ class FlwtchState extends State<Flwtch> with WindowListener {
|
|||
new CwtchNotifier(profs, globalSettings, globalErrorHandler, globalTorStatus, newDesktopNotificationsManager(_notificationSelectConvo), globalAppState, globalServersList, this);
|
||||
cwtch = CwtchFfi(cwtchNotifier);
|
||||
}
|
||||
print("initState: invoking cwtch.Start()");
|
||||
// Cwtch.start can take time, we don't want it blocking first splash screen draw, so postpone a smidge to let splash render
|
||||
Future.delayed(const Duration(milliseconds: 50), () async {
|
||||
await cwtch.Start();
|
||||
LoadThemes(await cwtch.getCwtchDir());
|
||||
Future.delayed(const Duration(milliseconds: 100), () {
|
||||
print("initState delayed: invoking cwtch.Start()");
|
||||
cwtch.Start().then((v) {
|
||||
cwtch.getCwtchDir().then((dir) {
|
||||
globalSettings.themeloader.LoadThemes(dir);
|
||||
});
|
||||
});
|
||||
});
|
||||
print("initState: starting connectivityListener");
|
||||
if (EnvironmentConfig.TEST_MODE == false) {
|
||||
|
@ -128,7 +127,7 @@ class FlwtchState extends State<Flwtch> with WindowListener {
|
|||
// gracefully fails and NOPs, as it's not a required functionality
|
||||
startConnectivityListener() async {
|
||||
try {
|
||||
connectivityStream = await Connectivity().onConnectivityChanged.listen((ConnectivityResult result) {
|
||||
connectivityStream = Connectivity().onConnectivityChanged.listen((ConnectivityResult result) {
|
||||
// Got a new connectivity status!
|
||||
if (result == ConnectivityResult.none) {
|
||||
connectivityState = ConnectivityState.confirmed_offline;
|
||||
|
@ -161,6 +160,7 @@ class FlwtchState extends State<Flwtch> with WindowListener {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
globalSettings.initPackageInfo();
|
||||
|
||||
return MultiProvider(
|
||||
providers: [
|
||||
getFlwtchStateProvider(),
|
||||
|
@ -172,10 +172,6 @@ class FlwtchState extends State<Flwtch> with WindowListener {
|
|||
getServerListStateProvider(),
|
||||
],
|
||||
builder: (context, widget) {
|
||||
// in test mode...rebuild everything every second...if cwtch isn't loaded...
|
||||
if (EnvironmentConfig.TEST_MODE && cwtch.IsLoaded() == false) {
|
||||
Timer t = new Timer.periodic(Duration(seconds: 1), (Timer t) => setState(() {}));
|
||||
}
|
||||
return Consumer2<Settings, AppState>(
|
||||
builder: (context, settings, appState, child) => MaterialApp(
|
||||
key: Key('app'),
|
||||
|
@ -193,7 +189,7 @@ class FlwtchState extends State<Flwtch> with WindowListener {
|
|||
title: 'Cwtch',
|
||||
showSemanticsDebugger: settings.useSemanticDebugger,
|
||||
theme: mkThemeData(settings),
|
||||
home: (!appState.cwtchInit || appState.modalState != ModalState.none) || !cwtch.IsLoaded() ? SplashView() : ProfileMgrView(),
|
||||
home: (!appState.loaded) ? SplashView() : ProfileMgrView(),
|
||||
),
|
||||
);
|
||||
},
|
||||
|
@ -256,7 +252,6 @@ class FlwtchState extends State<Flwtch> with WindowListener {
|
|||
exit(0);
|
||||
}
|
||||
}
|
||||
;
|
||||
}
|
||||
|
||||
// Invoked via notificationClickChannel by MyBroadcastReceiver in MainActivity.kt
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import 'package:cwtch/themes/cwtch.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
@ -8,16 +7,14 @@ import 'package:glob/list_local_fs.dart';
|
|||
import 'config.dart';
|
||||
import 'licenses.dart';
|
||||
import 'main.dart';
|
||||
import 'themes/opaque.dart';
|
||||
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'dart:typed_data';
|
||||
import "package:flutter_driver/driver_extension.dart";
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:glob/glob.dart';
|
||||
|
||||
var globalSettings = Settings(Locale("en", ''), CwtchDark());
|
||||
var globalSettings = Settings(Locale("en", ''));
|
||||
var globalErrorHandler = ErrorHandler();
|
||||
|
||||
Future<void> main() async {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:cwtch/config.dart';
|
||||
import 'package:cwtch/main.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
enum ModalState { none, storageMigration, shutdown }
|
||||
|
@ -18,6 +18,8 @@ class AppState extends ChangeNotifier {
|
|||
bool _unreadMessagesBelow = false;
|
||||
bool _disableFilePicker = false;
|
||||
bool _focus = true;
|
||||
bool _settingsLoaded = false;
|
||||
bool _themesLoaded = false;
|
||||
|
||||
StreamController<bool> _profilesUnreadNotifyControler = StreamController<bool>();
|
||||
late Stream<bool> profilesUnreadNotify;
|
||||
|
@ -33,13 +35,13 @@ class AppState extends ChangeNotifier {
|
|||
|
||||
void SetAppError(String error) {
|
||||
appError = error;
|
||||
EnvironmentConfig.debugLog("App Error: ${appError}");
|
||||
EnvironmentConfig.debugLog("App Error: $appError");
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void SetModalState(ModalState newState) {
|
||||
modalState = newState;
|
||||
EnvironmentConfig.debugLog("Modal State: ${newState}");
|
||||
EnvironmentConfig.debugLog("Modal State: $newState");
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
|
@ -86,6 +88,18 @@ class AppState extends ChangeNotifier {
|
|||
notifyListeners();
|
||||
}
|
||||
|
||||
set settingsLoaded(bool newVal) {
|
||||
_settingsLoaded = newVal;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
set themesLoaded(bool newVal) {
|
||||
_themesLoaded = newVal;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
bool get loaded => cwtchInit && _settingsLoaded && globalSettings.themeloader.themes.length > 0 && modalState == ModalState.none;
|
||||
|
||||
bool isLandscape(BuildContext c) => MediaQuery.of(c).size.width > MediaQuery.of(c).size.height;
|
||||
|
||||
void notifyProfileUnread() {
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
import 'dart:ffi';
|
||||
|
||||
import 'package:cwtch/main.dart';
|
||||
import 'package:cwtch/models/message_draft.dart';
|
||||
import 'package:cwtch/models/profile.dart';
|
||||
|
@ -13,7 +11,6 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
|||
import 'package:provider/provider.dart';
|
||||
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
|
||||
|
||||
import 'message.dart';
|
||||
import 'messagecache.dart';
|
||||
|
||||
enum ConversationNotificationPolicy {
|
||||
|
|
|
@ -54,7 +54,7 @@ class ContactListState extends ChangeNotifier {
|
|||
if (otherGroups != null && otherGroups.isNotEmpty) {
|
||||
EnvironmentConfig.debugLog("sharing antispam tickets to new group. FIXME: in Cwtch 1.14");
|
||||
var antispamTickets = otherGroups[0].antispamTickets;
|
||||
_contacts.last!.antispamTickets = antispamTickets;
|
||||
_contacts.last.antispamTickets = antispamTickets;
|
||||
}
|
||||
servers?.addGroup(newContact);
|
||||
}
|
||||
|
|
|
@ -64,6 +64,7 @@ Message compileOverlay(MessageInfo messageInfo) {
|
|||
|
||||
abstract class CacheHandler {
|
||||
Future<MessageInfo?> get(Cwtch cwtch, String profileOnion, int conversationIdentifier, MessageCache cache);
|
||||
Future<MessageInfo?> sync(Cwtch cwtch, String profileOnion, int conversationIdentifier, MessageCache cache);
|
||||
}
|
||||
|
||||
class ByIndex implements CacheHandler {
|
||||
|
@ -128,7 +129,8 @@ class ByIndex implements CacheHandler {
|
|||
List<dynamic> messagesWrapper = jsonDecode(msgs);
|
||||
|
||||
for (; i < messagesWrapper.length; i++) {
|
||||
var messageInfo = messageWrapperToInfo(profileOnion, conversationIdentifier, messagesWrapper[i]);
|
||||
var messageInfo = MessageWrapperToInfo(profileOnion, conversationIdentifier, messagesWrapper[i]);
|
||||
messageInfo.metadata.lastChecked = DateTime.now();
|
||||
cache.addIndexed(messageInfo, start + i);
|
||||
}
|
||||
} catch (e, stacktrace) {
|
||||
|
@ -143,6 +145,13 @@ class ByIndex implements CacheHandler {
|
|||
void add(MessageCache cache, MessageInfo messageInfo) {
|
||||
cache.addIndexed(messageInfo, index);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<MessageInfo?> sync(Cwtch cwtch, String profileOnion, int conversationIdentifier, MessageCache cache) {
|
||||
EnvironmentConfig.debugLog("performing a resync on message ${index}");
|
||||
fetchAndProcess(index, 1, cwtch, profileOnion, conversationIdentifier, cache);
|
||||
return get(cwtch, profileOnion, conversationIdentifier, cache);
|
||||
}
|
||||
}
|
||||
|
||||
class ById implements CacheHandler {
|
||||
|
@ -172,6 +181,11 @@ class ById implements CacheHandler {
|
|||
}
|
||||
return fetch(cwtch, profileOnion, conversationIdentifier, cache);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<MessageInfo?> sync(Cwtch cwtch, String profileOnion, int conversationIdentifier, MessageCache cache) {
|
||||
return get(cwtch, profileOnion, conversationIdentifier, cache);
|
||||
}
|
||||
}
|
||||
|
||||
class ByContentHash implements CacheHandler {
|
||||
|
@ -200,6 +214,11 @@ class ByContentHash implements CacheHandler {
|
|||
}
|
||||
return fetch(cwtch, profileOnion, conversationIdentifier, cache);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<MessageInfo?> sync(Cwtch cwtch, String profileOnion, int conversationIdentifier, MessageCache cache) {
|
||||
return get(cwtch, profileOnion, conversationIdentifier, cache);
|
||||
}
|
||||
}
|
||||
|
||||
List<Message> getReplies(MessageCache cache, int messageIdentifier) {
|
||||
|
@ -257,6 +276,16 @@ Future<Message> messageHandler(BuildContext context, String profileOnion, int co
|
|||
|
||||
MessageInfo? messageInfo = await cacheHandler.get(cwtch, profileOnion, conversationIdentifier, cache);
|
||||
|
||||
if (messageInfo != null) {
|
||||
if (messageInfo.metadata.ackd == false) {
|
||||
if (messageInfo.metadata.lastChecked == null || messageInfo.metadata.lastChecked!.difference(DateTime.now()).abs().inSeconds > 30) {
|
||||
messageInfo.metadata.lastChecked = DateTime.now();
|
||||
// NOTE: Only ByIndex lookups will trigger
|
||||
messageInfo = await cacheHandler.sync(cwtch, profileOnion, conversationIdentifier, cache);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (messageInfo != null) {
|
||||
return compileOverlay(messageInfo);
|
||||
} else {
|
||||
|
@ -272,14 +301,14 @@ MessageInfo? messageJsonToInfo(String profileOnion, int conversationIdentifier,
|
|||
return null;
|
||||
}
|
||||
|
||||
return messageWrapperToInfo(profileOnion, conversationIdentifier, messageWrapper);
|
||||
return MessageWrapperToInfo(profileOnion, conversationIdentifier, messageWrapper);
|
||||
} catch (e, stacktrace) {
|
||||
EnvironmentConfig.debugLog("message handler exception on parse message and cache: " + e.toString() + " " + stacktrace.toString());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
MessageInfo messageWrapperToInfo(String profileOnion, int conversationIdentifier, dynamic messageWrapper) {
|
||||
MessageInfo MessageWrapperToInfo(String profileOnion, int conversationIdentifier, dynamic messageWrapper) {
|
||||
// Construct the initial metadata
|
||||
var messageID = messageWrapper['ID'];
|
||||
var timestamp = DateTime.tryParse(messageWrapper['Timestamp'])!;
|
||||
|
@ -312,6 +341,7 @@ class MessageMetadata extends ChangeNotifier {
|
|||
|
||||
final String? signature;
|
||||
final String contenthash;
|
||||
DateTime? lastChecked;
|
||||
|
||||
dynamic get attributes => this._attributes;
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
/// A "MessageDraft" structure that stores information about in-progress message drafts.
|
||||
/// MessageDraft stores text, quoted replies, and attached images.
|
||||
|
@ -50,6 +49,8 @@ class MessageDraft extends ChangeNotifier {
|
|||
void clearDraft() {
|
||||
this._quotedReference = null;
|
||||
this.ctrlCompose.clear();
|
||||
this.ctrlCompose.clearComposing();
|
||||
this.ctrlCompose.text = "";
|
||||
this._inviteHandle = null;
|
||||
notifyListeners();
|
||||
}
|
||||
|
|
|
@ -128,8 +128,9 @@ class MessageCache extends ChangeNotifier {
|
|||
|
||||
void addNew(String profileOnion, int conversation, int messageID, DateTime timestamp, String senderHandle, String senderImage, bool isAuto, String data, String contenthash) {
|
||||
this.cache[messageID] = MessageInfo(MessageMetadata(profileOnion, conversation, messageID, timestamp, senderHandle, senderImage, "", {}, false, false, isAuto, contenthash), data);
|
||||
this.cache[messageID]?.metadata.lastChecked = DateTime.now(); // Don't check straight away...
|
||||
this.cacheByIndex.insert(0, LocalIndexMessage(messageID));
|
||||
if (contenthash != null && contenthash != "") {
|
||||
if (contenthash != "") {
|
||||
this.cacheByHash[contenthash] = messageID;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:cwtch/config.dart';
|
||||
import 'package:cwtch/models/message.dart';
|
||||
import 'package:cwtch/models/messages/malformedmessage.dart';
|
||||
import 'package:cwtch/widgets/malformedbubble.dart';
|
||||
|
@ -11,7 +10,6 @@ import 'package:flutter/widgets.dart';
|
|||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../../settings.dart';
|
||||
import '../../third_party/linkify/flutter_linkify.dart';
|
||||
|
||||
class QuotedMessageStructure {
|
||||
final String quotedHash;
|
||||
|
|
|
@ -1,17 +1,11 @@
|
|||
import 'dart:math';
|
||||
|
||||
import 'package:cwtch/models/message.dart';
|
||||
import 'package:cwtch/models/messages/malformedmessage.dart';
|
||||
import 'package:cwtch/widgets/malformedbubble.dart';
|
||||
import 'package:cwtch/widgets/messagebubble.dart';
|
||||
import 'package:cwtch/widgets/messageloadingbubble.dart';
|
||||
import 'package:cwtch/widgets/messagerow.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../../settings.dart';
|
||||
import '../../third_party/linkify/flutter_linkify.dart';
|
||||
import '../../widgets/messageBubbleWidgetHelpers.dart';
|
||||
|
||||
class TextMessage extends Message {
|
||||
|
@ -27,7 +21,6 @@ class TextMessage extends Message {
|
|||
builder: (bcontext, child) {
|
||||
var formatMessages = Provider.of<Settings>(bcontext).isExperimentEnabled(FormattingExperiment);
|
||||
return compileMessageContentWidget(context, constraints ?? BoxConstraints.loose(MediaQuery.sizeOf(context)), false, content, FocusNode(), formatMessages, false);
|
||||
;
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -14,8 +14,6 @@ import '../views/contactsview.dart';
|
|||
import 'contact.dart';
|
||||
import 'contactlist.dart';
|
||||
import 'filedownloadprogress.dart';
|
||||
import 'message.dart';
|
||||
import 'messagecache.dart';
|
||||
import 'profileservers.dart';
|
||||
|
||||
class ProfileInfoState extends ChangeNotifier {
|
||||
|
@ -241,7 +239,7 @@ class ProfileInfoState extends ChangeNotifier {
|
|||
this._unreadMessages = 0;
|
||||
this.replaceServers(serverJson);
|
||||
|
||||
if (contactsJson != null && contactsJson != "" && contactsJson != "null") {
|
||||
if (contactsJson != "" && contactsJson != "null") {
|
||||
List<dynamic> contacts = jsonDecode(contactsJson);
|
||||
contacts.forEach((contact) {
|
||||
var profileContact = this._contacts.getContact(contact["identifier"]);
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
import 'dart:ui';
|
||||
|
||||
import 'package:cwtch/config.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import 'package:cwtch/config.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
|
||||
import 'contact.dart';
|
||||
|
|
|
@ -3,13 +3,8 @@ import 'dart:convert';
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:cwtch/main.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:win_toast/win_toast.dart';
|
||||
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
||||
import 'package:flutter_local_notifications_linux/flutter_local_notifications_linux.dart';
|
||||
import 'package:flutter_local_notifications_linux/src/model/hint.dart';
|
||||
import 'package:flutter_local_notifications_linux/src/model/icon.dart';
|
||||
|
||||
import 'package:path/path.dart' as path;
|
||||
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
import 'dart:collection';
|
||||
import 'dart:ui';
|
||||
import 'dart:core';
|
||||
|
||||
import 'package:cwtch/themes/cwtch.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:package_info_plus/package_info_plus.dart';
|
||||
|
||||
|
@ -42,7 +40,6 @@ enum NotificationContent {
|
|||
class Settings extends ChangeNotifier {
|
||||
Locale locale;
|
||||
late PackageInfo packageInfo;
|
||||
OpaqueThemeType theme;
|
||||
bool _themeImages = false;
|
||||
|
||||
// explicitly set experiments to false until told otherwise...
|
||||
|
@ -70,6 +67,8 @@ class Settings extends ChangeNotifier {
|
|||
bool _useSemanticDebugger = false;
|
||||
double _fontScaling = 1.0;
|
||||
|
||||
ThemeLoader themeloader = ThemeLoader();
|
||||
|
||||
String get torCacheDir => _torCacheDir;
|
||||
|
||||
// Whether to show the profiling interface, not saved
|
||||
|
@ -88,8 +87,13 @@ class Settings extends ChangeNotifier {
|
|||
|
||||
bool get useSemanticDebugger => _useSemanticDebugger;
|
||||
|
||||
String? _themeId;
|
||||
String? get themeId => _themeId;
|
||||
String? _mode;
|
||||
OpaqueThemeType get theme => themeloader.getTheme(_themeId, _mode);
|
||||
void setTheme(String themeId, String mode) {
|
||||
theme = getTheme(themeId, mode);
|
||||
_themeId = themeId;
|
||||
_mode = mode;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
|
@ -404,9 +408,12 @@ class Settings extends ChangeNotifier {
|
|||
// checks experiment settings and file extension for image previews
|
||||
// (ignores file size; if the user manually accepts the file, assume it's okay to preview)
|
||||
bool shouldPreview(String path) {
|
||||
return isExperimentEnabled(ImagePreviewsExperiment) && isImage(path);
|
||||
}
|
||||
|
||||
bool isImage(String path) {
|
||||
var lpath = path.toLowerCase();
|
||||
return isExperimentEnabled(ImagePreviewsExperiment) &&
|
||||
(lpath.endsWith(".jpg") || lpath.endsWith(".jpeg") || lpath.endsWith(".png") || lpath.endsWith(".gif") || lpath.endsWith(".webp") || lpath.endsWith(".bmp"));
|
||||
return (lpath.endsWith(".jpg") || lpath.endsWith(".jpeg") || lpath.endsWith(".png") || lpath.endsWith(".gif") || lpath.endsWith(".webp") || lpath.endsWith(".bmp"));
|
||||
}
|
||||
|
||||
String get downloadPath => _downloadPath;
|
||||
|
@ -461,7 +468,7 @@ class Settings extends ChangeNotifier {
|
|||
}
|
||||
|
||||
/// Construct a default settings object.
|
||||
Settings(this.locale, this.theme);
|
||||
Settings(this.locale);
|
||||
|
||||
String _blodeuweddPath = "";
|
||||
String get blodeuweddPath => _blodeuweddPath;
|
||||
|
@ -475,7 +482,7 @@ class Settings extends ChangeNotifier {
|
|||
dynamic asJson() {
|
||||
return {
|
||||
"Locale": this.locale.toString(),
|
||||
"Theme": theme.theme,
|
||||
"Theme": _themeId,
|
||||
"ThemeMode": theme.mode,
|
||||
"ThemeImages": _themeImages,
|
||||
"PreviousPid": -1,
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import 'dart:io';
|
||||
import 'dart:ui';
|
||||
import 'dart:core';
|
||||
|
||||
import 'package:cwtch/themes/cwtch.dart';
|
||||
|
@ -16,41 +15,50 @@ const mode_dark = "dark";
|
|||
|
||||
final TextStyle defaultSmallTextStyle = TextStyle(fontFamily: "Inter", fontWeight: FontWeight.normal, fontSize: 10);
|
||||
final TextStyle defaultMessageTextStyle = TextStyle(fontFamily: "Inter", fontWeight: FontWeight.w400, fontSize: 13, fontFamilyFallback: [Platform.isWindows ? 'Segoe UI Emoji' : "Noto Color Emoji"]);
|
||||
final TextStyle defaultFormLabelTextStyle = TextStyle(fontFamily: "Inter", fontWeight: FontWeight.bold, fontSize: 20);
|
||||
final TextStyle defaultFormLabelTextStyle = TextStyle(
|
||||
fontFamily: "Inter",
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 20,
|
||||
);
|
||||
final TextStyle defaultTextStyle = TextStyle(fontFamily: "Inter", fontWeight: FontWeight.w500, fontSize: 12);
|
||||
final TextStyle defaultTextButtonStyle = defaultTextStyle.copyWith(fontWeight: FontWeight.bold);
|
||||
final TextStyle defaultDropDownMenuItemTextStyle = TextStyle(fontFamily: "Inter", fontWeight: FontWeight.bold, fontSize: 16);
|
||||
|
||||
Map<String, Map<String, OpaqueThemeType>> themes = Map();
|
||||
class ThemeLoader extends ChangeNotifier {
|
||||
Map<String, Map<String, OpaqueThemeType>> themes = Map();
|
||||
|
||||
LoadThemes(String cwtchDir) async {
|
||||
themes = await loadBuiltinThemes();
|
||||
final customThemes = await loadCustomThemes(path.join(cwtchDir, custom_themes_subdir));
|
||||
themes.addAll(customThemes);
|
||||
}
|
||||
|
||||
OpaqueThemeType getTheme(String themeId, String mode) {
|
||||
if (themeId == "") {
|
||||
themeId = cwtch_theme;
|
||||
}
|
||||
if (themeId == mode_light) {
|
||||
themeId = cwtch_theme;
|
||||
mode = mode_light;
|
||||
}
|
||||
if (themeId == mode_dark) {
|
||||
themeId = cwtch_theme;
|
||||
mode = mode_dark;
|
||||
LoadThemes(String cwtchDir) async {
|
||||
themes.clear(); // clear themes...
|
||||
loadBuiltinThemes().then((builtinThemes) {
|
||||
themes.addAll(builtinThemes);
|
||||
notifyListeners();
|
||||
loadCustomThemes(path.join(cwtchDir, custom_themes_subdir)).then((customThemes) {
|
||||
themes.addAll(customThemes);
|
||||
notifyListeners();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
var theme = themes[themeId]?[mode] ?? themes[themeId]?[flipMode(mode)];
|
||||
return theme ?? CwtchDark();
|
||||
}
|
||||
|
||||
String flipMode(String mode) {
|
||||
if (mode == mode_dark) {
|
||||
return mode_light;
|
||||
OpaqueThemeType getTheme(String? themeId, String? mode) {
|
||||
if (themeId == null) {
|
||||
themeId = cwtch_theme;
|
||||
}
|
||||
if (themeId == mode_light) {
|
||||
mode = mode_light;
|
||||
}
|
||||
if (themeId == mode_dark) {
|
||||
mode = mode_dark;
|
||||
}
|
||||
var theme = themes[themeId]?[mode] ?? themes[themeId]?[flipMode(mode ?? mode_dark)];
|
||||
return theme ?? CwtchDark();
|
||||
}
|
||||
|
||||
String flipMode(String mode) {
|
||||
if (mode == mode_dark) {
|
||||
return mode_light;
|
||||
}
|
||||
return mode_dark;
|
||||
}
|
||||
return mode_dark;
|
||||
}
|
||||
|
||||
Color lighten(Color color, [double amount = 0.15]) {
|
||||
|
@ -172,18 +180,22 @@ ThemeData mkThemeData(Settings opaque) {
|
|||
return ThemeData(
|
||||
hoverColor: opaque.current().backgroundHilightElementColor.withOpacity(0.5),
|
||||
visualDensity: VisualDensity.adaptivePlatformDensity,
|
||||
primarySwatch: getMaterialColor(opaque.current().topbarColor),
|
||||
primaryIconTheme: IconThemeData(
|
||||
color: opaque.current().mainTextColor,
|
||||
),
|
||||
primaryColor: opaque.current().mainTextColor,
|
||||
canvasColor: opaque.current().backgroundMainColor,
|
||||
backgroundColor: opaque.current().backgroundMainColor,
|
||||
highlightColor: opaque.current().hilightElementColor,
|
||||
iconTheme: IconThemeData(
|
||||
color: opaque.current().toolbarIconColor,
|
||||
),
|
||||
cardColor: opaque.current().backgroundMainColor,
|
||||
bottomSheetTheme: BottomSheetThemeData(
|
||||
backgroundColor: opaque.current().backgroundPaneColor,
|
||||
constraints: const BoxConstraints(
|
||||
maxWidth: double.infinity,
|
||||
),
|
||||
),
|
||||
appBarTheme: AppBarTheme(
|
||||
systemOverlayStyle: SystemUiOverlayStyle(
|
||||
// Status bar color
|
||||
|
@ -200,7 +212,9 @@ ThemeData mkThemeData(Settings opaque) {
|
|||
actionsIconTheme: IconThemeData(
|
||||
color: opaque.current().mainTextColor,
|
||||
)),
|
||||
|
||||
listTileTheme: ListTileThemeData(
|
||||
titleTextStyle: defaultFormLabelTextStyle.copyWith(color: opaque.current().mainTextColor), subtitleTextStyle: defaultMessageTextStyle.copyWith(color: opaque.current().mainTextColor)),
|
||||
iconButtonTheme: IconButtonThemeData(style: ButtonStyle(textStyle: MaterialStateProperty.all(defaultFormLabelTextStyle))),
|
||||
//bottomNavigationBarTheme: BottomNavigationBarThemeData(type: BottomNavigationBarType.fixed, backgroundColor: opaque.current().backgroundHilightElementColor), // Can't determine current use
|
||||
textButtonTheme: TextButtonThemeData(
|
||||
style: ButtonStyle(
|
||||
|
@ -229,12 +243,12 @@ ThemeData mkThemeData(Settings opaque) {
|
|||
),
|
||||
scrollbarTheme: ScrollbarThemeData(thumbVisibility: MaterialStateProperty.all(false), thumbColor: MaterialStateProperty.all(opaque.current().scrollbarDefaultColor)),
|
||||
tabBarTheme: TabBarTheme(
|
||||
labelColor: opaque.current().mainTextColor,
|
||||
unselectedLabelColor: opaque.current().mainTextColor,
|
||||
indicator: UnderlineTabIndicator(borderSide: BorderSide(color: opaque.current().defaultButtonActiveColor)),
|
||||
labelStyle: opaque.scaleFonts(defaultTextButtonStyle),
|
||||
unselectedLabelStyle: opaque.scaleFonts(defaultTextStyle),
|
||||
),
|
||||
labelColor: opaque.current().mainTextColor,
|
||||
unselectedLabelColor: opaque.current().mainTextColor,
|
||||
indicator: UnderlineTabIndicator(borderSide: BorderSide(color: opaque.current().defaultButtonActiveColor)),
|
||||
labelStyle: opaque.scaleFonts(defaultTextButtonStyle).copyWith(color: opaque.current().mainTextColor),
|
||||
unselectedLabelStyle: opaque.scaleFonts(defaultTextStyle).copyWith(color: opaque.current().mainTextColor),
|
||||
tabAlignment: TabAlignment.center),
|
||||
dialogTheme: DialogTheme(
|
||||
backgroundColor: opaque.current().backgroundPaneColor,
|
||||
titleTextStyle: TextStyle(fontFamily: "Inter", fontWeight: FontWeight.bold, color: opaque.current().mainTextColor),
|
||||
|
|
|
@ -1,13 +1,10 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:cwtch/config.dart';
|
||||
import 'package:cwtch/themes/cwtch.dart';
|
||||
import 'package:cwtch/themes/opaque.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:glob/list_local_fs.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:yaml/yaml.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
|
@ -132,7 +129,7 @@ class YmlTheme extends OpaqueThemeType {
|
|||
val = yml["themes"][mode]["theme"][val] ?? val;
|
||||
}
|
||||
if (!(val is int)) {
|
||||
val = yml["themes"][mode]?["colors"][val] ?? val;
|
||||
val = yml["themes"][mode]?["colors"]?[val] ?? val;
|
||||
}
|
||||
if (!(val is int)) {
|
||||
val = yml["colors"]?[val];
|
||||
|
|
|
@ -0,0 +1,673 @@
|
|||
# Generated by pub
|
||||
# See https://dart.dev/tools/pub/glossary#lockfile
|
||||
packages:
|
||||
_fe_analyzer_shared:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: _fe_analyzer_shared
|
||||
sha256: "0b2f2bd91ba804e53a61d757b986f89f1f9eaed5b11e4b2f5a2468d86d6c9fc7"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "67.0.0"
|
||||
analyzer:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: analyzer
|
||||
sha256: "37577842a27e4338429a1cbc32679d508836510b056f1eedf0c8d20e39c1383d"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.4.1"
|
||||
args:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: args
|
||||
sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.2"
|
||||
async:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: async
|
||||
sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.11.0"
|
||||
boolean_selector:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: boolean_selector
|
||||
sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.1"
|
||||
build:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build
|
||||
sha256: "80184af8b6cb3e5c1c4ec6d8544d27711700bc3e6d2efad04238c7b5290889f0"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.1"
|
||||
build_config:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_config
|
||||
sha256: bf80fcfb46a29945b423bd9aad884590fb1dc69b330a4d4700cac476af1708d1
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
build_daemon:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_daemon
|
||||
sha256: "0343061a33da9c5810b2d6cee51945127d8f4c060b7fbdd9d54917f0a3feaaa1"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.0.1"
|
||||
build_resolvers:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_resolvers
|
||||
sha256: "339086358431fa15d7eca8b6a36e5d783728cf025e559b834f4609a1fcfb7b0a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.2"
|
||||
build_runner:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: build_runner
|
||||
sha256: "581bacf68f89ec8792f5e5a0b2c4decd1c948e97ce659dc783688c8a88fbec21"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.8"
|
||||
build_runner_core:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_runner_core
|
||||
sha256: "4ae8ffe5ac758da294ecf1802f2aff01558d8b1b00616aa7538ea9a8a5d50799"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.3.0"
|
||||
built_collection:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: built_collection
|
||||
sha256: "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.1.1"
|
||||
built_value:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: built_value
|
||||
sha256: fedde275e0a6b798c3296963c5cd224e3e1b55d0e478d5b7e65e6b540f363a0e
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "8.9.1"
|
||||
characters:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: characters
|
||||
sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.0"
|
||||
checked_yaml:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: checked_yaml
|
||||
sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.3"
|
||||
clock:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: clock
|
||||
sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
code_builder:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: code_builder
|
||||
sha256: f692079e25e7869c14132d39f223f8eec9830eb76131925143b2129c4bb01b37
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.10.0"
|
||||
collection:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: collection
|
||||
sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.18.0"
|
||||
connectivity_plus_platform_interface:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
path: "../connectivity_plus_platform_interface"
|
||||
relative: true
|
||||
source: path
|
||||
version: "1.2.4"
|
||||
convert:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: convert
|
||||
sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.1"
|
||||
coverage:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: coverage
|
||||
sha256: "8acabb8306b57a409bf4c83522065672ee13179297a6bb0cb9ead73948df7c76"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.7.2"
|
||||
crypto:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: crypto
|
||||
sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.3"
|
||||
dart_style:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: dart_style
|
||||
sha256: "99e066ce75c89d6b29903d788a7bb9369cf754f7b24bf70bf4b6d6d6b26853b9"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.6"
|
||||
dbus:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: dbus
|
||||
sha256: "365c771ac3b0e58845f39ec6deebc76e3276aa9922b0cc60840712094d9047ac"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.10"
|
||||
fake_async:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: fake_async
|
||||
sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.1"
|
||||
ffi:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: ffi
|
||||
sha256: "493f37e7df1804778ff3a53bd691d8692ddf69702cf4c1c1096a2e41b4779e21"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.2"
|
||||
file:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file
|
||||
sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.0.0"
|
||||
fixnum:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: fixnum
|
||||
sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
flutter:
|
||||
dependency: "direct main"
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
flutter_lints:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: flutter_lints
|
||||
sha256: a25a15ebbdfc33ab1cd26c63a6ee519df92338a9c10f122adda92938253bef04
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.3"
|
||||
flutter_test:
|
||||
dependency: "direct dev"
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
flutter_web_plugins:
|
||||
dependency: "direct main"
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
frontend_server_client:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: frontend_server_client
|
||||
sha256: "408e3ca148b31c20282ad6f37ebfa6f4bdc8fede5b74bc2f08d9d92b55db3612"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.2.0"
|
||||
glob:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: glob
|
||||
sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.2"
|
||||
graphs:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: graphs
|
||||
sha256: aedc5a15e78fc65a6e23bcd927f24c64dd995062bcd1ca6eda65a3cff92a4d19
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.1"
|
||||
http_multi_server:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http_multi_server
|
||||
sha256: "97486f20f9c2f7be8f514851703d0119c3596d14ea63227af6f7a481ef2b2f8b"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.2.1"
|
||||
http_parser:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http_parser
|
||||
sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.0.2"
|
||||
io:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: io
|
||||
sha256: "2ec25704aba361659e10e3e5f5d672068d332fc8ac516421d483a11e5cbd061e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.4"
|
||||
js:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: js
|
||||
sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.6.7"
|
||||
json_annotation:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: json_annotation
|
||||
sha256: b10a7b2ff83d83c777edba3c6a0f97045ddadd56c944e1a23a3fdf43a1bf4467
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.8.1"
|
||||
leak_tracker:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: leak_tracker
|
||||
sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "10.0.0"
|
||||
leak_tracker_flutter_testing:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: leak_tracker_flutter_testing
|
||||
sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.1"
|
||||
leak_tracker_testing:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: leak_tracker_testing
|
||||
sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.1"
|
||||
lints:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: lints
|
||||
sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.1"
|
||||
logging:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: logging
|
||||
sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
matcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: matcher
|
||||
sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.12.16+1"
|
||||
material_color_utilities:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: material_color_utilities
|
||||
sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.8.0"
|
||||
meta:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: meta
|
||||
sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.11.0"
|
||||
mime:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: mime
|
||||
sha256: "2e123074287cc9fd6c09de8336dae606d1ddb88d9ac47358826db698c176a1f2"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.5"
|
||||
mockito:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: mockito
|
||||
sha256: "6841eed20a7befac0ce07df8116c8b8233ed1f4486a7647c7fc5a02ae6163917"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.4.4"
|
||||
node_preamble:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: node_preamble
|
||||
sha256: "6e7eac89047ab8a8d26cf16127b5ed26de65209847630400f9aefd7cd5c730db"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.2"
|
||||
package_config:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: package_config
|
||||
sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
path:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path
|
||||
sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.9.0"
|
||||
petitparser:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: petitparser
|
||||
sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.0.2"
|
||||
plugin_platform_interface:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: plugin_platform_interface
|
||||
sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.8"
|
||||
pool:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pool
|
||||
sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.5.1"
|
||||
pub_semver:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pub_semver
|
||||
sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.4"
|
||||
pubspec_parse:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pubspec_parse
|
||||
sha256: c63b2876e58e194e4b0828fcb080ad0e06d051cb607a6be51a9e084f47cb9367
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.3"
|
||||
shelf:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf
|
||||
sha256: ad29c505aee705f41a4d8963641f91ac4cee3c8fad5947e033390a7bd8180fa4
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.1"
|
||||
shelf_packages_handler:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf_packages_handler
|
||||
sha256: "89f967eca29607c933ba9571d838be31d67f53f6e4ee15147d5dc2934fee1b1e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.2"
|
||||
shelf_static:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf_static
|
||||
sha256: a41d3f53c4adf0f57480578c1d61d90342cd617de7fc8077b1304643c2d85c1e
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.2"
|
||||
shelf_web_socket:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf_web_socket
|
||||
sha256: "9ca081be41c60190ebcb4766b2486a7d50261db7bd0f5d9615f2d653637a84c1"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.4"
|
||||
sky_engine:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.99"
|
||||
source_gen:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_gen
|
||||
sha256: "14658ba5f669685cd3d63701d01b31ea748310f7ab854e471962670abcf57832"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.5.0"
|
||||
source_map_stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_map_stack_trace
|
||||
sha256: "84cf769ad83aa6bb61e0aa5a18e53aea683395f196a6f39c4c881fb90ed4f7ae"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.1"
|
||||
source_maps:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_maps
|
||||
sha256: "708b3f6b97248e5781f493b765c3337db11c5d2c81c3094f10904bfa8004c703"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.10.12"
|
||||
source_span:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_span
|
||||
sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.10.0"
|
||||
stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stack_trace
|
||||
sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.11.1"
|
||||
stream_channel:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stream_channel
|
||||
sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.2"
|
||||
stream_transform:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stream_transform
|
||||
sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
string_scanner:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: string_scanner
|
||||
sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
term_glyph:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: term_glyph
|
||||
sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.1"
|
||||
test:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: test
|
||||
sha256: a1f7595805820fcc05e5c52e3a231aedd0b72972cb333e8c738a8b1239448b6f
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.24.9"
|
||||
test_api:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_api
|
||||
sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.6.1"
|
||||
test_core:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_core
|
||||
sha256: a757b14fc47507060a162cc2530d9a4a2f92f5100a952c7443b5cad5ef5b106a
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.5.9"
|
||||
timing:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: timing
|
||||
sha256: "70a3b636575d4163c477e6de42f247a23b315ae20e86442bebe32d3cabf61c32"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
typed_data:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: typed_data
|
||||
sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.2"
|
||||
vector_math:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vector_math
|
||||
sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.4"
|
||||
vm_service:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vm_service
|
||||
sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "13.0.0"
|
||||
watcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: watcher
|
||||
sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: web
|
||||
sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.5.1"
|
||||
web_socket_channel:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: web_socket_channel
|
||||
sha256: "1d8e795e2a8b3730c41b8a98a2dff2e0fb57ae6f0764a1c46ec5915387d257b2"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.4"
|
||||
webkit_inspection_protocol:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: webkit_inspection_protocol
|
||||
sha256: "87d3f2333bb240704cd3f1c6b5b7acd8a10e7f0bc28c28dcf14e782014f4a572"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.1"
|
||||
xml:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: xml
|
||||
sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.5.0"
|
||||
yaml:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: yaml
|
||||
sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.2"
|
||||
sdks:
|
||||
dart: ">=3.3.0 <4.0.0"
|
||||
flutter: ">=3.7.0"
|
|
@ -34,6 +34,7 @@ dependencies:
|
|||
js: ^0.6.3
|
||||
meta: ^1.8.0
|
||||
|
||||
cwtch: any
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
|
|
|
@ -24,11 +24,8 @@
|
|||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
|
||||
import 'linkify.dart';
|
||||
|
||||
|
@ -129,7 +126,7 @@ class SelectableLinkify extends StatelessWidget {
|
|||
/// Called when the user changes the selection of text (including the cursor location).
|
||||
final SelectionChangedCallback? onSelectionChanged;
|
||||
|
||||
final BoxConstraints constraints;
|
||||
final BoxConstraints? constraints;
|
||||
|
||||
const SelectableLinkify({
|
||||
Key? key,
|
||||
|
@ -164,7 +161,7 @@ class SelectableLinkify extends StatelessWidget {
|
|||
this.cursorHeight,
|
||||
this.selectionControls,
|
||||
this.onSelectionChanged,
|
||||
required this.constraints,
|
||||
this.constraints,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
|
@ -238,7 +235,7 @@ TextSpan buildTextSpan(
|
|||
LinkCallback? onOpen,
|
||||
required BuildContext context,
|
||||
bool useMouseRegion = false,
|
||||
required BoxConstraints constraints,
|
||||
BoxConstraints? constraints,
|
||||
}) {
|
||||
// Ok, so the problem here is that Flutter really wants to optimize this function
|
||||
// out of the rebuild process. This is fine when the screen gets smaller because
|
||||
|
@ -250,7 +247,7 @@ TextSpan buildTextSpan(
|
|||
// (I tried a few other things, including the docs-sanctioned MediaQuery.sizeOf(context) - which promises a rebuild
|
||||
// but Flutter is pretty good at optimizing "useless" checks out)
|
||||
String inlineText = "\u0020";
|
||||
if (constraints.maxWidth % 2 == 0) {
|
||||
if (constraints != null && constraints.maxWidth % 2 == 0) {
|
||||
inlineText = "\u00A0";
|
||||
}
|
||||
elements.add(TextElement(inlineText));
|
||||
|
|
|
@ -9,24 +9,24 @@ class TorStatus extends ChangeNotifier {
|
|||
TorStatus({this.connected = false, this.progress = 0, this.status = "", this.version = ""});
|
||||
|
||||
/// Called by the event bus.
|
||||
handleUpdate(int new_progress, String new_status) {
|
||||
handleUpdate(int newProgress, String newStatus) {
|
||||
if (progress == 100) {
|
||||
connected = true;
|
||||
} else {
|
||||
connected = false;
|
||||
}
|
||||
|
||||
progress = new_progress;
|
||||
status = new_status;
|
||||
if (new_progress != 100) {
|
||||
status = "$new_progress% - $new_status";
|
||||
progress = newProgress;
|
||||
status = newStatus;
|
||||
if (newProgress != 100) {
|
||||
status = "$newProgress% - $newStatus";
|
||||
}
|
||||
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
updateVersion(String new_version) {
|
||||
version = new_version;
|
||||
updateVersion(String newVersion) {
|
||||
version = newVersion;
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,9 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:cwtch/cwtch_icons_icons.dart';
|
||||
import 'package:cwtch/models/profile.dart';
|
||||
import 'package:cwtch/models/remoteserver.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:cwtch/errorHandler.dart';
|
||||
import 'package:cwtch/models/profileservers.dart';
|
||||
import 'package:cwtch/settings.dart';
|
||||
import 'package:cwtch/widgets/buttontextfield.dart';
|
||||
import 'package:cwtch/widgets/cwtchlabel.dart';
|
||||
|
@ -237,7 +234,9 @@ class _AddContactViewState extends State<AddContactView> {
|
|||
controller: ctrlrGroupName,
|
||||
hintText: AppLocalizations.of(bcontext)!.groupNameLabel,
|
||||
onChanged: (newValue) {},
|
||||
validator: (value) {},
|
||||
validator: (value) {
|
||||
return null;
|
||||
},
|
||||
),
|
||||
SizedBox(
|
||||
height: 20,
|
||||
|
|
|
@ -20,7 +20,6 @@ import '../constants.dart';
|
|||
import '../cwtch_icons_icons.dart';
|
||||
import '../errorHandler.dart';
|
||||
import '../main.dart';
|
||||
import '../themes/opaque.dart';
|
||||
import '../settings.dart';
|
||||
|
||||
class AddEditProfileView extends StatefulWidget {
|
||||
|
@ -93,8 +92,8 @@ class _AddEditProfileViewState extends State<AddEditProfileView> {
|
|||
child: Form(
|
||||
key: _formKey,
|
||||
child: Container(
|
||||
margin: EdgeInsets.all(30),
|
||||
padding: EdgeInsets.all(20),
|
||||
color: theme.theme.backgroundPaneColor,
|
||||
padding: EdgeInsets.all(50),
|
||||
child: Column(mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.center, children: [
|
||||
Visibility(
|
||||
visible: Provider.of<ProfileInfoState>(context).onion.isNotEmpty,
|
||||
|
@ -154,7 +153,7 @@ class _AddEditProfileViewState extends State<AddEditProfileView> {
|
|||
Provider.of<FlwtchState>(context, listen: false).cwtch.SetProfileAttribute(onion, "profile.profile-attribute-1", profileAttribute1);
|
||||
Provider.of<ProfileInfoState>(context, listen: false).attributes[0] = profileAttribute1;
|
||||
},
|
||||
hintText: Provider.of<ProfileInfoState>(context).attributes[0] ?? AppLocalizations.of(context)!.profileInfoHint!)),
|
||||
hintText: Provider.of<ProfileInfoState>(context).attributes[0] ?? AppLocalizations.of(context)!.profileInfoHint)),
|
||||
Padding(
|
||||
padding: EdgeInsets.all(5.0),
|
||||
child: CwtchTextField(
|
||||
|
@ -165,7 +164,7 @@ class _AddEditProfileViewState extends State<AddEditProfileView> {
|
|||
Provider.of<FlwtchState>(context, listen: false).cwtch.SetProfileAttribute(onion, "profile.profile-attribute-2", profileAttribute2);
|
||||
Provider.of<ProfileInfoState>(context, listen: false).attributes[1] = profileAttribute2;
|
||||
},
|
||||
hintText: Provider.of<ProfileInfoState>(context).attributes[1] ?? AppLocalizations.of(context)!.profileInfoHint2!)),
|
||||
hintText: Provider.of<ProfileInfoState>(context).attributes[1] ?? AppLocalizations.of(context)!.profileInfoHint2)),
|
||||
Padding(
|
||||
padding: EdgeInsets.all(5.0),
|
||||
child: CwtchTextField(
|
||||
|
@ -176,7 +175,7 @@ class _AddEditProfileViewState extends State<AddEditProfileView> {
|
|||
Provider.of<FlwtchState>(context, listen: false).cwtch.SetProfileAttribute(onion, "profile.profile-attribute-3", profileAttribute3);
|
||||
Provider.of<ProfileInfoState>(context, listen: false).attributes[2] = profileAttribute3;
|
||||
},
|
||||
hintText: Provider.of<ProfileInfoState>(context).attributes[2] ?? AppLocalizations.of(context)!.profileInfoHint3!)),
|
||||
hintText: Provider.of<ProfileInfoState>(context).attributes[2] ?? AppLocalizations.of(context)!.profileInfoHint3)),
|
||||
],
|
||||
))
|
||||
],
|
||||
|
@ -258,7 +257,7 @@ class _AddEditProfileViewState extends State<AddEditProfileView> {
|
|||
onChanged: (bool value) {
|
||||
Provider.of<ProfileInfoState>(context, listen: false).autostart = value;
|
||||
|
||||
if (!Provider.of<ProfileInfoState>(context, listen: false).onion.isEmpty) {
|
||||
if (Provider.of<ProfileInfoState>(context, listen: false).onion.isNotEmpty) {
|
||||
Provider.of<FlwtchState>(context, listen: false)
|
||||
.cwtch
|
||||
.SetProfileAttribute(Provider.of<ProfileInfoState>(context, listen: false).onion, "profile.autostart", value ? "true" : "false");
|
||||
|
@ -280,7 +279,7 @@ class _AddEditProfileViewState extends State<AddEditProfileView> {
|
|||
onChanged: (bool value) {
|
||||
Provider.of<ProfileInfoState>(context, listen: false).appearOfflineAtStartup = value;
|
||||
var onion = Provider.of<ProfileInfoState>(context, listen: false).onion;
|
||||
if (!onion.isEmpty) {
|
||||
if (onion.isNotEmpty) {
|
||||
Provider.of<FlwtchState>(context, listen: false).cwtch.SetProfileAttribute(onion, "profile.appear-offline", value ? "true" : "false");
|
||||
}
|
||||
},
|
||||
|
@ -449,11 +448,11 @@ class _AddEditProfileViewState extends State<AddEditProfileView> {
|
|||
child: ElevatedButton.icon(
|
||||
style: ElevatedButton.styleFrom(
|
||||
minimumSize: Size(400, 75),
|
||||
backgroundColor: Provider.of<Settings>(context).theme.backgroundMainColor,
|
||||
maximumSize: Size(800, 75),
|
||||
shape: RoundedRectangleBorder(
|
||||
side: BorderSide(color: Provider.of<Settings>(context).theme.defaultButtonActiveColor, width: 2.0),
|
||||
borderRadius: BorderRadius.horizontal(left: Radius.circular(180), right: Radius.circular(180))),
|
||||
primary: Provider.of<Settings>(context).theme.backgroundMainColor,
|
||||
),
|
||||
onPressed: () {
|
||||
showAlertDialog(context);
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
import 'dart:convert';
|
||||
import 'package:cwtch/cwtch/cwtch.dart';
|
||||
import 'package:cwtch/cwtch_icons_icons.dart';
|
||||
import 'package:cwtch/models/servers.dart';
|
||||
import 'package:cwtch/widgets/cwtchlabel.dart';
|
||||
import 'package:cwtch/widgets/passwordfield.dart';
|
||||
import 'package:cwtch/widgets/textfield.dart';
|
||||
import 'package:package_info_plus/package_info_plus.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:cwtch/settings.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
@ -13,7 +11,6 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
|||
|
||||
import '../errorHandler.dart';
|
||||
import '../main.dart';
|
||||
import '../config.dart';
|
||||
|
||||
/// Pane to add or edit a server
|
||||
class AddEditServerView extends StatefulWidget {
|
||||
|
@ -143,7 +140,7 @@ class _AddEditServerViewState extends State<AddEditServerView> {
|
|||
onChanged: (bool value) {
|
||||
serverInfoState.setAutostart(value);
|
||||
|
||||
if (!serverInfoState.onion.isEmpty) {
|
||||
if (serverInfoState.onion.isNotEmpty) {
|
||||
Provider.of<FlwtchState>(context, listen: false).cwtch.SetServerAttribute(serverInfoState.onion, "autostart", value ? "true" : "false");
|
||||
}
|
||||
},
|
||||
|
|
|
@ -19,7 +19,6 @@ import 'package:provider/provider.dart';
|
|||
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
|
||||
import '../config.dart';
|
||||
import '../main.dart';
|
||||
import '../models/message.dart';
|
||||
import '../models/redaction.dart';
|
||||
import '../settings.dart';
|
||||
import '../themes/opaque.dart';
|
||||
|
@ -43,12 +42,12 @@ class ContactsView extends StatefulWidget {
|
|||
|
||||
// selectConversation can be called from anywhere to set the active conversation
|
||||
void selectConversation(BuildContext context, int handle, int? messageIndex) {
|
||||
int? index = null;
|
||||
int? index;
|
||||
|
||||
if (messageIndex != null) {
|
||||
// this message is loaded
|
||||
Provider.of<AppState>(context, listen: false).selectedSearchMessage = messageIndex;
|
||||
Provider.of<AppState>(context, listen: false).initialScrollIndex = messageIndex!;
|
||||
Provider.of<AppState>(context, listen: false).initialScrollIndex = messageIndex;
|
||||
EnvironmentConfig.debugLog("Looked up index $messageIndex");
|
||||
}
|
||||
|
||||
|
@ -70,9 +69,6 @@ void selectConversation(BuildContext context, int handle, int? messageIndex) {
|
|||
// triggers update in Double/TripleColumnView
|
||||
Provider.of<ContactInfoState>(context, listen: false).hoveredIndex = -1;
|
||||
Provider.of<AppState>(context, listen: false).selectedConversation = handle;
|
||||
if (index != null) {
|
||||
Provider.of<AppState>(context, listen: false).initialScrollIndex = unread;
|
||||
}
|
||||
|
||||
// if in singlepane mode, push to the stack
|
||||
var isLandscape = Provider.of<AppState>(context, listen: false).isLandscape(context);
|
||||
|
@ -125,6 +121,7 @@ class _ContactsViewState extends State<ContactsView> {
|
|||
return ScaffoldMessenger(
|
||||
key: scaffoldKey,
|
||||
child: Scaffold(
|
||||
backgroundColor: Provider.of<Settings>(context).theme.backgroundMainColor,
|
||||
endDrawerEnableOpenDragGesture: false,
|
||||
drawerEnableOpenDragGesture: false,
|
||||
appBar: AppBar(
|
||||
|
@ -243,7 +240,7 @@ class _ContactsViewState extends State<ContactsView> {
|
|||
color: Colors.white,
|
||||
),
|
||||
Expanded(
|
||||
child: Text(AppLocalizations.of(context)!.availabilityStatusAvailable!,
|
||||
child: Text(AppLocalizations.of(context)!.availabilityStatusAvailable,
|
||||
textAlign: TextAlign.right, style: Provider.of<Settings>(context, listen: false).scaleFonts(defaultTextButtonStyle)))
|
||||
]),
|
||||
),
|
||||
|
@ -256,7 +253,7 @@ class _ContactsViewState extends State<ContactsView> {
|
|||
color: Colors.yellowAccent,
|
||||
),
|
||||
Expanded(
|
||||
child: Text(AppLocalizations.of(context)!.availabilityStatusAway!,
|
||||
child: Text(AppLocalizations.of(context)!.availabilityStatusAway,
|
||||
textAlign: TextAlign.right, style: Provider.of<Settings>(context, listen: false).scaleFonts(defaultTextButtonStyle)))
|
||||
]),
|
||||
),
|
||||
|
@ -269,7 +266,7 @@ class _ContactsViewState extends State<ContactsView> {
|
|||
color: Colors.redAccent,
|
||||
),
|
||||
Expanded(
|
||||
child: Text(AppLocalizations.of(context)!.availabilityStatusBusy!,
|
||||
child: Text(AppLocalizations.of(context)!.availabilityStatusBusy,
|
||||
textAlign: TextAlign.right, style: Provider.of<Settings>(context, listen: false).scaleFonts(defaultTextButtonStyle)))
|
||||
]),
|
||||
),
|
||||
|
@ -280,7 +277,7 @@ class _ContactsViewState extends State<ContactsView> {
|
|||
child: Row(children: [
|
||||
Icon(CwtchIcons.disconnect_from_contact),
|
||||
Expanded(
|
||||
child: Text(AppLocalizations.of(context)!.profileAppearOffline!,
|
||||
child: Text(AppLocalizations.of(context)!.profileAppearOffline,
|
||||
textAlign: TextAlign.right, style: Provider.of<Settings>(context, listen: false).scaleFonts(defaultTextButtonStyle)))
|
||||
]),
|
||||
),
|
||||
|
@ -290,7 +287,7 @@ class _ContactsViewState extends State<ContactsView> {
|
|||
child: Row(children: [
|
||||
Icon(CwtchIcons.disconnect_from_contact),
|
||||
Expanded(
|
||||
child: Text(AppLocalizations.of(context)!.profileAppearOnline!,
|
||||
child: Text(AppLocalizations.of(context)!.profileAppearOnline,
|
||||
textAlign: TextAlign.right, style: Provider.of<Settings>(context, listen: false).scaleFonts(defaultTextButtonStyle)))
|
||||
]),
|
||||
),
|
||||
|
@ -303,7 +300,7 @@ class _ContactsViewState extends State<ContactsView> {
|
|||
color: settings.theme.mainTextColor,
|
||||
),
|
||||
Expanded(
|
||||
child: Text((settings.blockUnknownConnections ? AppLocalizations.of(context)!.profileAllowUnknownContacts! : AppLocalizations.of(context)!.profileBlockUnknownContacts!),
|
||||
child: Text((settings.blockUnknownConnections ? AppLocalizations.of(context)!.profileAllowUnknownContacts : AppLocalizations.of(context)!.profileBlockUnknownContacts),
|
||||
textAlign: TextAlign.right, style: Provider.of<Settings>(context, listen: false).scaleFonts(defaultTextButtonStyle)))
|
||||
]),
|
||||
),
|
||||
|
@ -313,7 +310,7 @@ class _ContactsViewState extends State<ContactsView> {
|
|||
child: Row(children: [
|
||||
Icon(CwtchIcons.favorite_24dp, color: settings.theme.mainTextColor),
|
||||
Expanded(
|
||||
child: Text((enabled ? AppLocalizations.of(context)!.profileDisableProfile! : AppLocalizations.of(context)!.profileEnableProfile!),
|
||||
child: Text((enabled ? AppLocalizations.of(context)!.profileDisableProfile : AppLocalizations.of(context)!.profileEnableProfile),
|
||||
textAlign: TextAlign.right, style: Provider.of<Settings>(context, listen: false).scaleFonts(defaultTextButtonStyle)))
|
||||
]),
|
||||
),
|
||||
|
@ -326,8 +323,7 @@ class _ContactsViewState extends State<ContactsView> {
|
|||
color: settings.theme.mainTextColor,
|
||||
),
|
||||
Expanded(
|
||||
child:
|
||||
Text(AppLocalizations.of(context)!.editProfile!, textAlign: TextAlign.right, style: Provider.of<Settings>(context, listen: false).scaleFonts(defaultTextButtonStyle)))
|
||||
child: Text(AppLocalizations.of(context)!.editProfile, textAlign: TextAlign.right, style: Provider.of<Settings>(context, listen: false).scaleFonts(defaultTextButtonStyle)))
|
||||
]),
|
||||
),
|
||||
],
|
||||
|
@ -640,14 +636,14 @@ class _ContactsViewState extends State<ContactsView> {
|
|||
});
|
||||
}
|
||||
|
||||
void _showQRCode(String profile_code) {
|
||||
void _showQRCode(String profileCode) {
|
||||
showModalBottomSheet<dynamic>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return Wrap(children: <Widget>[
|
||||
Center(
|
||||
child: QrImageView(
|
||||
data: profile_code,
|
||||
data: profileCode,
|
||||
version: QrVersions.auto,
|
||||
size: 400.0,
|
||||
backgroundColor: Provider.of<Settings>(context).theme.backgroundPaneColor,
|
||||
|
|
|
@ -4,7 +4,6 @@ import 'package:cwtch/models/profile.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
import '../main.dart';
|
||||
import '../settings.dart';
|
||||
import 'contactsview.dart';
|
||||
import 'messageview.dart';
|
||||
|
@ -36,6 +35,7 @@ class _DoubleColumnViewState extends State<DoubleColumnView> {
|
|||
color: Provider.of<Settings>(context).theme.backgroundMainColor,
|
||||
child: Card(
|
||||
margin: EdgeInsets.all(0.0),
|
||||
color: Provider.of<Settings>(context).theme.backgroundMainColor,
|
||||
shape: new RoundedRectangleBorder(side: new BorderSide(color: Provider.of<Settings>(context).theme.defaultButtonColor, width: 4.0), borderRadius: BorderRadius.circular(4.0)),
|
||||
child: Center(child: Text(AppLocalizations.of(context)!.addContactFirst))))
|
||||
: //dev
|
||||
|
|
|
@ -10,7 +10,6 @@ import '../config.dart';
|
|||
import '../cwtch_icons_icons.dart';
|
||||
import '../main.dart';
|
||||
import '../settings.dart';
|
||||
import '../themes/opaque.dart';
|
||||
import 'globalsettingsview.dart';
|
||||
|
||||
class GlobalSettingsAboutView extends StatefulWidget {
|
||||
|
@ -32,90 +31,89 @@ class _GlobalSettingsAboutViewState extends State<GlobalSettingsAboutView> {
|
|||
child: SingleChildScrollView(
|
||||
clipBehavior: Clip.antiAlias,
|
||||
controller: settingsListScrollController,
|
||||
padding: EdgeInsets.symmetric(vertical: 0, horizontal: 20),
|
||||
child: ConstrainedBox(
|
||||
constraints: BoxConstraints(
|
||||
minHeight: viewportConstraints.maxHeight,
|
||||
),
|
||||
child: Column(children: [
|
||||
AboutListTile(
|
||||
icon: appIcon,
|
||||
applicationIcon: Padding(padding: EdgeInsets.all(5), child: Icon(CwtchIcons.cwtch_knott)),
|
||||
applicationName: "Cwtch UI",
|
||||
applicationLegalese: '\u{a9} 2021-2023 Open Privacy Research Society',
|
||||
aboutBoxChildren: <Widget>[
|
||||
Padding(
|
||||
padding: EdgeInsets.fromLTRB(24.0 + 10.0 + (appIcon.size ?? 24.0), 16.0, 0.0, 0.0),
|
||||
// About has 24 padding (ln 389) and there appears to be another 10 of padding in the widget
|
||||
child: SelectableText(AppLocalizations.of(context)!.versionBuilddate.replaceAll("%1", EnvironmentConfig.BUILD_VER).replaceAll("%2", EnvironmentConfig.BUILD_DATE)),
|
||||
)
|
||||
]),
|
||||
SwitchListTile(
|
||||
// TODO: Translate, Remove, OR Hide Prior to Release
|
||||
title: Text("Show Performance Overlay"),
|
||||
subtitle: Text("Display an overlay graph of render time."),
|
||||
value: settings.profileMode,
|
||||
onChanged: (bool value) {
|
||||
setState(() {
|
||||
if (value) {
|
||||
settings.profileMode = value;
|
||||
} else {
|
||||
settings.profileMode = value;
|
||||
}
|
||||
});
|
||||
},
|
||||
activeTrackColor: settings.theme.defaultButtonActiveColor,
|
||||
inactiveTrackColor: settings.theme.defaultButtonDisabledColor,
|
||||
secondary: Icon(Icons.bar_chart, color: settings.current().mainTextColor),
|
||||
),
|
||||
Visibility(
|
||||
visible: EnvironmentConfig.BUILD_VER == dev_version && !Platform.isAndroid,
|
||||
child: SwitchListTile(
|
||||
title: Text("Show Semantic Debugger"),
|
||||
subtitle: Text("Show Accessibility Debugging View"),
|
||||
value: settings.useSemanticDebugger,
|
||||
constraints: BoxConstraints(minHeight: viewportConstraints.maxHeight, maxWidth: viewportConstraints.maxWidth),
|
||||
child: Container(
|
||||
color: settings.theme.backgroundPaneColor,
|
||||
child: Column(children: [
|
||||
AboutListTile(
|
||||
icon: appIcon,
|
||||
applicationIcon: Padding(padding: EdgeInsets.all(5), child: Icon(CwtchIcons.cwtch_knott)),
|
||||
applicationName: "Cwtch UI",
|
||||
applicationLegalese: '\u{a9} 2021-2023 Open Privacy Research Society',
|
||||
aboutBoxChildren: <Widget>[
|
||||
Padding(
|
||||
padding: EdgeInsets.fromLTRB(24.0 + 10.0 + (appIcon.size ?? 24.0), 16.0, 0.0, 0.0),
|
||||
// About has 24 padding (ln 389) and there appears to be another 10 of padding in the widget
|
||||
child: SelectableText(AppLocalizations.of(context)!.versionBuilddate.replaceAll("%1", EnvironmentConfig.BUILD_VER).replaceAll("%2", EnvironmentConfig.BUILD_DATE)),
|
||||
)
|
||||
]),
|
||||
SwitchListTile(
|
||||
// TODO: Translate, Remove, OR Hide Prior to Release
|
||||
title: Text(AppLocalizations.of(context)!.settingsExperimentsShowPerformanceTitle),
|
||||
subtitle: Text(AppLocalizations.of(context)!.settingsExperimentsShowPerformanceDescription),
|
||||
value: settings.profileMode,
|
||||
onChanged: (bool value) {
|
||||
if (value) {
|
||||
settings.useSemanticDebugger = value;
|
||||
} else {
|
||||
settings.useSemanticDebugger = value;
|
||||
}
|
||||
saveSettings(context);
|
||||
setState(() {
|
||||
if (value) {
|
||||
settings.profileMode = value;
|
||||
} else {
|
||||
settings.profileMode = value;
|
||||
}
|
||||
});
|
||||
},
|
||||
activeTrackColor: settings.theme.defaultButtonActiveColor,
|
||||
inactiveTrackColor: settings.theme.defaultButtonDisabledColor,
|
||||
secondary: Icon(Icons.settings_accessibility, color: settings.current().mainTextColor),
|
||||
)),
|
||||
Visibility(
|
||||
visible: EnvironmentConfig.BUILD_VER == dev_version && !Platform.isAndroid,
|
||||
child: FutureBuilder(
|
||||
future: EnvironmentConfig.BUILD_VER != dev_version || Platform.isAndroid ? null : Provider.of<FlwtchState>(context).cwtch.GetDebugInfo(),
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.hasData) {
|
||||
return Column(
|
||||
children: [
|
||||
Text("libCwtch Debug Info: " + snapshot.data.toString()),
|
||||
Text("Message Cache Size (Mb): " + (Provider.of<FlwtchState>(context).profs.cacheMemUsage() / (1024 * 1024)).toString())
|
||||
],
|
||||
);
|
||||
} else {
|
||||
return Container();
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
Visibility(
|
||||
visible: EnvironmentConfig.BUILD_VER == dev_version,
|
||||
child: FutureBuilder(
|
||||
future: Provider.of<FlwtchState>(context).cwtch.PlatformChannelInfo(),
|
||||
secondary: Icon(Icons.bar_chart, color: settings.current().mainTextColor),
|
||||
),
|
||||
Visibility(
|
||||
visible: EnvironmentConfig.BUILD_VER == dev_version && !Platform.isAndroid,
|
||||
child: SwitchListTile(
|
||||
title: Text("Show Semantic Debugger"),
|
||||
subtitle: Text("Show Accessibility Debugging View"),
|
||||
value: settings.useSemanticDebugger,
|
||||
onChanged: (bool value) {
|
||||
if (value) {
|
||||
settings.useSemanticDebugger = value;
|
||||
} else {
|
||||
settings.useSemanticDebugger = value;
|
||||
}
|
||||
saveSettings(context);
|
||||
},
|
||||
activeTrackColor: settings.theme.defaultButtonActiveColor,
|
||||
inactiveTrackColor: settings.theme.defaultButtonDisabledColor,
|
||||
secondary: Icon(Icons.settings_accessibility, color: settings.current().mainTextColor),
|
||||
)),
|
||||
Visibility(
|
||||
visible: EnvironmentConfig.BUILD_VER == dev_version && !Platform.isAndroid,
|
||||
child: FutureBuilder(
|
||||
future: EnvironmentConfig.BUILD_VER != dev_version || Platform.isAndroid ? null : Provider.of<FlwtchState>(context).cwtch.GetDebugInfo(),
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.hasData) {
|
||||
HashMap<String, String> data = snapshot.data as HashMap<String, String>;
|
||||
return getPlatformInfo(settings, data);
|
||||
return Column(
|
||||
children: [
|
||||
Text("libCwtch Debug Info: " + snapshot.data.toString()),
|
||||
Text("Message Cache Size (Mb): " + (Provider.of<FlwtchState>(context).profs.cacheMemUsage() / (1024 * 1024)).toString())
|
||||
],
|
||||
);
|
||||
} else {
|
||||
return Container();
|
||||
}
|
||||
return Container();
|
||||
}))
|
||||
]))));
|
||||
},
|
||||
),
|
||||
),
|
||||
Visibility(
|
||||
visible: EnvironmentConfig.BUILD_VER == dev_version,
|
||||
child: FutureBuilder(
|
||||
future: Provider.of<FlwtchState>(context).cwtch.PlatformChannelInfo(),
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.hasData) {
|
||||
HashMap<String, String> data = snapshot.data as HashMap<String, String>;
|
||||
return getPlatformInfo(settings, data);
|
||||
}
|
||||
return Container();
|
||||
}))
|
||||
])))));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -139,9 +137,6 @@ class _GlobalSettingsAboutViewState extends State<GlobalSettingsAboutView> {
|
|||
// TODO: deprecated ?
|
||||
/// Construct a version string from Package Info
|
||||
String constructVersionString(PackageInfo pinfo) {
|
||||
if (pinfo == null) {
|
||||
return "";
|
||||
}
|
||||
return pinfo.version + "." + pinfo.buildNumber;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@ import '../settings.dart';
|
|||
import '../themes/cwtch.dart';
|
||||
import '../themes/opaque.dart';
|
||||
import '../themes/yamltheme.dart';
|
||||
import '../widgets/folderpicker.dart';
|
||||
import 'globalsettingsview.dart';
|
||||
|
||||
class GlobalSettingsAppearanceView extends StatefulWidget {
|
||||
|
@ -35,218 +34,218 @@ class _GlobalSettingsAppearanceViewState extends State<GlobalSettingsAppearanceV
|
|||
child: SingleChildScrollView(
|
||||
clipBehavior: Clip.antiAlias,
|
||||
controller: settingsListScrollController,
|
||||
padding: EdgeInsets.symmetric(vertical: 0, horizontal: 20),
|
||||
child: ConstrainedBox(
|
||||
constraints: BoxConstraints(
|
||||
minHeight: viewportConstraints.maxHeight,
|
||||
),
|
||||
child: Column(children: [
|
||||
ListTile(
|
||||
title: Text(AppLocalizations.of(context)!.settingLanguage),
|
||||
leading: Icon(CwtchIcons.change_language, color: settings.current().mainTextColor),
|
||||
trailing: Container(
|
||||
width: MediaQuery.of(context).size.width / 4,
|
||||
child: DropdownButton(
|
||||
key: Key("languagelist"),
|
||||
isExpanded: true,
|
||||
value: Provider.of<Settings>(context).locale.toString(),
|
||||
onChanged: (String? newValue) {
|
||||
setState(() {
|
||||
EnvironmentConfig.debugLog("setting language: $newValue");
|
||||
settings.switchLocaleByCode(newValue!);
|
||||
saveSettings(context);
|
||||
});
|
||||
},
|
||||
items: AppLocalizations.supportedLocales.map<DropdownMenuItem<String>>((Locale value) {
|
||||
return DropdownMenuItem<String>(
|
||||
value: value.toString(),
|
||||
child: Text(
|
||||
key: Key("dropdownLanguage" + value.languageCode),
|
||||
getLanguageFull(context, value.languageCode, value.countryCode),
|
||||
style: settings.scaleFonts(defaultDropDownMenuItemTextStyle),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
);
|
||||
}).toList()))),
|
||||
SwitchListTile(
|
||||
title: Text(AppLocalizations.of(context)!.settingTheme),
|
||||
value: settings.current().mode == mode_light,
|
||||
onChanged: (bool value) {
|
||||
if (value) {
|
||||
settings.setTheme(settings.theme.theme, mode_light);
|
||||
} else {
|
||||
settings.setTheme(settings.theme.theme, mode_dark);
|
||||
}
|
||||
|
||||
// Save Settings...
|
||||
saveSettings(context);
|
||||
},
|
||||
activeTrackColor: settings.theme.defaultButtonColor,
|
||||
inactiveTrackColor: settings.theme.defaultButtonDisabledColor,
|
||||
secondary: Icon(CwtchIcons.change_theme, color: settings.current().mainTextColor),
|
||||
),
|
||||
ListTile(
|
||||
title: Text(AppLocalizations.of(context)!.themeColorLabel),
|
||||
trailing: Container(
|
||||
width: MediaQuery.of(context).size.width / 4,
|
||||
child: DropdownButton<String>(
|
||||
key: Key("DropdownTheme"),
|
||||
isExpanded: true,
|
||||
value: Provider.of<Settings>(context).theme.theme,
|
||||
onChanged: (String? newValue) {
|
||||
setState(() {
|
||||
settings.setTheme(newValue!, settings.theme.mode);
|
||||
saveSettings(context);
|
||||
});
|
||||
},
|
||||
items: themes.keys.map<DropdownMenuItem<String>>((String themeId) {
|
||||
return DropdownMenuItem<String>(
|
||||
value: themeId,
|
||||
child: Text(getThemeName(context, themeId), style: settings.scaleFonts(defaultDropDownMenuItemTextStyle)), //"ddi_$themeId", key: Key("ddi_$themeId")),
|
||||
);
|
||||
}).toList())),
|
||||
leading: Icon(Icons.palette, color: settings.current().mainTextColor),
|
||||
),
|
||||
Visibility(
|
||||
// TODO: Android support needs gomobile support for reading / writing themes, and ideally importing from a .zip or .tar.gz
|
||||
visible: !Platform.isAndroid,
|
||||
child: ListTile(
|
||||
leading: Icon(Icons.palette, color: Provider.of<Settings>(context).theme.messageFromMeTextColor),
|
||||
title: Text(AppLocalizations.of(context)!.settingsImportThemeTitle),
|
||||
subtitle: Text(AppLocalizations.of(context)!.settingsImportThemeDescription),
|
||||
//AppLocalizations.of(
|
||||
//context)!
|
||||
//.fileSharingSettingsDownloadFolderDescription,
|
||||
constraints: BoxConstraints(minHeight: viewportConstraints.maxHeight, maxWidth: viewportConstraints.maxWidth),
|
||||
child: Container(
|
||||
color: settings.theme.backgroundPaneColor,
|
||||
child: Column(children: [
|
||||
ListTile(
|
||||
title: Text(AppLocalizations.of(context)!.settingLanguage),
|
||||
leading: Icon(CwtchIcons.change_language, color: settings.current().mainTextColor),
|
||||
trailing: Container(
|
||||
width: MediaQuery.of(context).size.width / 4,
|
||||
child: ElevatedButton.icon(
|
||||
label: Text(AppLocalizations.of(context)!.settingsImportThemeButton),
|
||||
onPressed: Provider.of<AppState>(context).disableFilePicker
|
||||
? null
|
||||
: () async {
|
||||
if (Platform.isAndroid) {
|
||||
return;
|
||||
}
|
||||
var selectedDirectory = await showSelectDirectoryPicker(context);
|
||||
if (selectedDirectory != null) {
|
||||
selectedDirectory += path.separator;
|
||||
final customThemeDir = path.join(await Provider.of<FlwtchState>(context, listen: false).cwtch.getCwtchDir(), custom_themes_subdir);
|
||||
importThemeCheck(context, settings, customThemeDir, selectedDirectory);
|
||||
} else {
|
||||
// User canceled the picker
|
||||
}
|
||||
},
|
||||
//onChanged: widget.onSave,
|
||||
icon: Icon(Icons.folder),
|
||||
//tooltip: widget.tooltip,
|
||||
)))),
|
||||
SwitchListTile(
|
||||
title: Text(AppLocalizations.of(context)!.settingsThemeImages),
|
||||
subtitle: Text(AppLocalizations.of(context)!.settingsThemeImagesDescription),
|
||||
value: settings.themeImages,
|
||||
onChanged: (bool value) {
|
||||
settings.themeImages = value; // Save Settings...
|
||||
saveSettings(context);
|
||||
},
|
||||
activeTrackColor: settings.theme.defaultButtonColor,
|
||||
inactiveTrackColor: settings.theme.defaultButtonDisabledColor,
|
||||
secondary: Icon(Icons.image, color: settings.current().mainTextColor),
|
||||
),
|
||||
ListTile(
|
||||
title: Text(AppLocalizations.of(context)!.settingUIColumnPortrait),
|
||||
leading: Icon(Icons.table_chart, color: settings.current().mainTextColor),
|
||||
trailing: Container(
|
||||
width: MediaQuery.of(context).size.width / 4,
|
||||
child: DropdownButton(
|
||||
isExpanded: true,
|
||||
value: settings.uiColumnModePortrait.toString(),
|
||||
onChanged: (String? newValue) {
|
||||
settings.uiColumnModePortrait = Settings.uiColumnModeFromString(newValue!);
|
||||
saveSettings(context);
|
||||
},
|
||||
items: Settings.uiColumnModeOptions(false).map<DropdownMenuItem<String>>((DualpaneMode value) {
|
||||
return DropdownMenuItem<String>(
|
||||
value: value.toString(),
|
||||
child: Text(Settings.uiColumnModeToString(value, context), style: settings.scaleFonts(defaultDropDownMenuItemTextStyle)),
|
||||
);
|
||||
}).toList()))),
|
||||
ListTile(
|
||||
title: Text(
|
||||
AppLocalizations.of(context)!.settingUIColumnLandscape,
|
||||
textWidthBasis: TextWidthBasis.longestLine,
|
||||
softWrap: true,
|
||||
child: DropdownButton(
|
||||
key: Key("languagelist"),
|
||||
isExpanded: true,
|
||||
value: Provider.of<Settings>(context).locale.toString(),
|
||||
onChanged: (String? newValue) {
|
||||
setState(() {
|
||||
EnvironmentConfig.debugLog("setting language: $newValue");
|
||||
settings.switchLocaleByCode(newValue!);
|
||||
saveSettings(context);
|
||||
});
|
||||
},
|
||||
items: AppLocalizations.supportedLocales.map<DropdownMenuItem<String>>((Locale value) {
|
||||
return DropdownMenuItem<String>(
|
||||
value: value.toString(),
|
||||
child: Text(
|
||||
key: Key("dropdownLanguage" + value.languageCode),
|
||||
getLanguageFull(context, value.languageCode, value.countryCode),
|
||||
style: settings.scaleFonts(defaultDropDownMenuItemTextStyle),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
);
|
||||
}).toList()))),
|
||||
SwitchListTile(
|
||||
title: Text(AppLocalizations.of(context)!.settingTheme),
|
||||
value: settings.current().mode == mode_light,
|
||||
onChanged: (bool value) {
|
||||
if (value) {
|
||||
settings.setTheme(settings.theme.theme, mode_light);
|
||||
} else {
|
||||
settings.setTheme(settings.theme.theme, mode_dark);
|
||||
}
|
||||
|
||||
// Save Settings...
|
||||
saveSettings(context);
|
||||
},
|
||||
activeTrackColor: settings.theme.defaultButtonColor,
|
||||
inactiveTrackColor: settings.theme.defaultButtonDisabledColor,
|
||||
secondary: Icon(CwtchIcons.change_theme, color: settings.current().mainTextColor),
|
||||
),
|
||||
leading: Icon(Icons.stay_primary_landscape, color: settings.current().mainTextColor),
|
||||
trailing: Container(
|
||||
width: MediaQuery.of(context).size.width / 4,
|
||||
child: Container(
|
||||
ListTile(
|
||||
title: Text(AppLocalizations.of(context)!.themeColorLabel),
|
||||
trailing: Container(
|
||||
width: MediaQuery.of(context).size.width / 4,
|
||||
child: DropdownButton<String>(
|
||||
key: Key("DropdownTheme"),
|
||||
isExpanded: true,
|
||||
value: Provider.of<Settings>(context).themeId,
|
||||
onChanged: (String? newValue) {
|
||||
setState(() {
|
||||
settings.setTheme(newValue!, settings.theme.mode);
|
||||
saveSettings(context);
|
||||
});
|
||||
},
|
||||
items: settings.themeloader.themes.keys.map<DropdownMenuItem<String>>((String themeId) {
|
||||
return DropdownMenuItem<String>(
|
||||
value: themeId,
|
||||
child:
|
||||
Text(getThemeName(context, settings, themeId), style: settings.scaleFonts(defaultDropDownMenuItemTextStyle)), //"ddi_$themeId", key: Key("ddi_$themeId")),
|
||||
);
|
||||
}).toList())),
|
||||
leading: Icon(Icons.palette, color: settings.current().mainTextColor),
|
||||
),
|
||||
Visibility(
|
||||
// TODO: Android support needs gomobile support for reading / writing themes, and ideally importing from a .zip or .tar.gz
|
||||
visible: !Platform.isAndroid,
|
||||
child: ListTile(
|
||||
leading: Icon(Icons.palette, color: Provider.of<Settings>(context).theme.messageFromMeTextColor),
|
||||
title: Text(AppLocalizations.of(context)!.settingsImportThemeTitle),
|
||||
subtitle: Text(AppLocalizations.of(context)!.settingsImportThemeDescription),
|
||||
//AppLocalizations.of(
|
||||
//context)!
|
||||
//.fileSharingSettingsDownloadFolderDescription,
|
||||
trailing: Container(
|
||||
width: MediaQuery.of(context).size.width / 4,
|
||||
child: ElevatedButton.icon(
|
||||
label: Text(AppLocalizations.of(context)!.settingsImportThemeButton),
|
||||
onPressed: Provider.of<AppState>(context).disableFilePicker
|
||||
? null
|
||||
: () async {
|
||||
if (Platform.isAndroid) {
|
||||
return;
|
||||
}
|
||||
var selectedDirectory = await showSelectDirectoryPicker(context);
|
||||
if (selectedDirectory != null) {
|
||||
selectedDirectory += path.separator;
|
||||
final customThemeDir = path.join(await Provider.of<FlwtchState>(context, listen: false).cwtch.getCwtchDir(), custom_themes_subdir);
|
||||
importThemeCheck(context, settings, customThemeDir, selectedDirectory);
|
||||
} else {
|
||||
// User canceled the picker
|
||||
}
|
||||
},
|
||||
//onChanged: widget.onSave,
|
||||
icon: Icon(Icons.folder),
|
||||
//tooltip: widget.tooltip,
|
||||
)))),
|
||||
SwitchListTile(
|
||||
title: Text(AppLocalizations.of(context)!.settingsThemeImages),
|
||||
subtitle: Text(AppLocalizations.of(context)!.settingsThemeImagesDescription),
|
||||
value: settings.themeImages,
|
||||
onChanged: (bool value) {
|
||||
settings.themeImages = value; // Save Settings...
|
||||
saveSettings(context);
|
||||
},
|
||||
activeTrackColor: settings.theme.defaultButtonColor,
|
||||
inactiveTrackColor: settings.theme.defaultButtonDisabledColor,
|
||||
secondary: Icon(Icons.image, color: settings.current().mainTextColor),
|
||||
),
|
||||
ListTile(
|
||||
title: Text(AppLocalizations.of(context)!.settingUIColumnPortrait),
|
||||
leading: Icon(Icons.table_chart, color: settings.current().mainTextColor),
|
||||
trailing: Container(
|
||||
width: MediaQuery.of(context).size.width / 4,
|
||||
child: DropdownButton(
|
||||
isExpanded: true,
|
||||
value: settings.uiColumnModeLandscape.toString(),
|
||||
value: settings.uiColumnModePortrait.toString(),
|
||||
onChanged: (String? newValue) {
|
||||
settings.uiColumnModeLandscape = Settings.uiColumnModeFromString(newValue!);
|
||||
settings.uiColumnModePortrait = Settings.uiColumnModeFromString(newValue!);
|
||||
saveSettings(context);
|
||||
},
|
||||
items: Settings.uiColumnModeOptions(true).map<DropdownMenuItem<String>>((DualpaneMode value) {
|
||||
items: Settings.uiColumnModeOptions(false).map<DropdownMenuItem<String>>((DualpaneMode value) {
|
||||
return DropdownMenuItem<String>(
|
||||
value: value.toString(),
|
||||
child: Text(Settings.uiColumnModeToString(value, context), overflow: TextOverflow.ellipsis, style: settings.scaleFonts(defaultDropDownMenuItemTextStyle)),
|
||||
child: Text(Settings.uiColumnModeToString(value, context), style: settings.scaleFonts(defaultDropDownMenuItemTextStyle)),
|
||||
);
|
||||
}).toList())))),
|
||||
ListTile(
|
||||
title: Text(AppLocalizations.of(context)!.defaultScalingText),
|
||||
subtitle: Text(AppLocalizations.of(context)!.fontScalingDescription),
|
||||
trailing: Container(
|
||||
width: MediaQuery.of(context).size.width / 4,
|
||||
child: Slider(
|
||||
onChanged: (double value) {
|
||||
settings.fontScaling = value;
|
||||
}).toList()))),
|
||||
ListTile(
|
||||
title: Text(
|
||||
AppLocalizations.of(context)!.settingUIColumnLandscape,
|
||||
textWidthBasis: TextWidthBasis.longestLine,
|
||||
softWrap: true,
|
||||
),
|
||||
leading: Icon(Icons.stay_primary_landscape, color: settings.current().mainTextColor),
|
||||
trailing: Container(
|
||||
width: MediaQuery.of(context).size.width / 4,
|
||||
child: Container(
|
||||
width: MediaQuery.of(context).size.width / 4,
|
||||
child: DropdownButton(
|
||||
isExpanded: true,
|
||||
value: settings.uiColumnModeLandscape.toString(),
|
||||
onChanged: (String? newValue) {
|
||||
settings.uiColumnModeLandscape = Settings.uiColumnModeFromString(newValue!);
|
||||
saveSettings(context);
|
||||
},
|
||||
items: Settings.uiColumnModeOptions(true).map<DropdownMenuItem<String>>((DualpaneMode value) {
|
||||
return DropdownMenuItem<String>(
|
||||
value: value.toString(),
|
||||
child: Text(Settings.uiColumnModeToString(value, context), overflow: TextOverflow.ellipsis, style: settings.scaleFonts(defaultDropDownMenuItemTextStyle)),
|
||||
);
|
||||
}).toList())))),
|
||||
ListTile(
|
||||
title: Text(AppLocalizations.of(context)!.defaultScalingText),
|
||||
subtitle: Text(AppLocalizations.of(context)!.fontScalingDescription),
|
||||
trailing: Container(
|
||||
width: MediaQuery.of(context).size.width / 4,
|
||||
child: Slider(
|
||||
onChanged: (double value) {
|
||||
settings.fontScaling = value;
|
||||
// Save Settings...
|
||||
saveSettings(context);
|
||||
EnvironmentConfig.debugLog("Font Scaling: $value");
|
||||
},
|
||||
min: 0.5,
|
||||
divisions: 12,
|
||||
max: 2.0,
|
||||
label: '${settings.fontScaling * 100}%',
|
||||
activeColor: settings.current().defaultButtonColor,
|
||||
thumbColor: settings.current().mainTextColor,
|
||||
overlayColor: MaterialStateProperty.all(settings.current().mainTextColor),
|
||||
inactiveColor: settings.theme.defaultButtonDisabledColor,
|
||||
value: settings.fontScaling)),
|
||||
leading: Icon(Icons.format_size, color: settings.current().mainTextColor),
|
||||
),
|
||||
SwitchListTile(
|
||||
title: Text(AppLocalizations.of(context)!.streamerModeLabel),
|
||||
subtitle: Text(AppLocalizations.of(context)!.descriptionStreamerMode),
|
||||
value: settings.streamerMode,
|
||||
onChanged: (bool value) {
|
||||
settings.setStreamerMode(value);
|
||||
saveSettings(context);
|
||||
EnvironmentConfig.debugLog("Font Scaling: $value");
|
||||
},
|
||||
min: 0.5,
|
||||
divisions: 12,
|
||||
max: 2.0,
|
||||
label: '${settings.fontScaling * 100}%',
|
||||
activeColor: settings.current().defaultButtonColor,
|
||||
thumbColor: settings.current().mainTextColor,
|
||||
overlayColor: MaterialStateProperty.all(settings.current().mainTextColor),
|
||||
inactiveColor: settings.theme.defaultButtonDisabledColor,
|
||||
value: settings.fontScaling)),
|
||||
leading: Icon(Icons.format_size, color: settings.current().mainTextColor),
|
||||
),
|
||||
SwitchListTile(
|
||||
title: Text(AppLocalizations.of(context)!.streamerModeLabel),
|
||||
subtitle: Text(AppLocalizations.of(context)!.descriptionStreamerMode),
|
||||
value: settings.streamerMode,
|
||||
onChanged: (bool value) {
|
||||
settings.setStreamerMode(value);
|
||||
// Save Settings...
|
||||
saveSettings(context);
|
||||
},
|
||||
activeTrackColor: settings.theme.defaultButtonColor,
|
||||
inactiveTrackColor: settings.theme.defaultButtonDisabledColor,
|
||||
secondary: Icon(CwtchIcons.streamer_bunnymask, color: settings.current().mainTextColor),
|
||||
),
|
||||
SwitchListTile(
|
||||
title: Text(AppLocalizations.of(context)!.formattingExperiment),
|
||||
subtitle: Text(AppLocalizations.of(context)!.messageFormattingDescription),
|
||||
value: settings.isExperimentEnabled(FormattingExperiment),
|
||||
onChanged: (bool value) {
|
||||
if (value) {
|
||||
settings.enableExperiment(FormattingExperiment);
|
||||
} else {
|
||||
settings.disableExperiment(FormattingExperiment);
|
||||
}
|
||||
saveSettings(context);
|
||||
},
|
||||
activeTrackColor: settings.theme.defaultButtonActiveColor,
|
||||
inactiveTrackColor: settings.theme.defaultButtonDisabledColor,
|
||||
secondary: Icon(Icons.text_fields, color: settings.current().mainTextColor),
|
||||
),
|
||||
]))));
|
||||
saveSettings(context);
|
||||
},
|
||||
activeTrackColor: settings.theme.defaultButtonColor,
|
||||
inactiveTrackColor: settings.theme.defaultButtonDisabledColor,
|
||||
secondary: Icon(CwtchIcons.streamer_bunnymask, color: settings.current().mainTextColor),
|
||||
),
|
||||
SwitchListTile(
|
||||
title: Text(AppLocalizations.of(context)!.formattingExperiment),
|
||||
subtitle: Text(AppLocalizations.of(context)!.messageFormattingDescription),
|
||||
value: settings.isExperimentEnabled(FormattingExperiment),
|
||||
onChanged: (bool value) {
|
||||
if (value) {
|
||||
settings.enableExperiment(FormattingExperiment);
|
||||
} else {
|
||||
settings.disableExperiment(FormattingExperiment);
|
||||
}
|
||||
saveSettings(context);
|
||||
},
|
||||
activeTrackColor: settings.theme.defaultButtonColor,
|
||||
inactiveTrackColor: settings.theme.defaultButtonDisabledColor,
|
||||
secondary: Icon(Icons.text_fields, color: settings.current().mainTextColor),
|
||||
),
|
||||
])))));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -330,7 +329,7 @@ class _GlobalSettingsAppearanceViewState extends State<GlobalSettingsAppearanceV
|
|||
}
|
||||
|
||||
/// Since we don't seem to able to dynamically pull translations, this function maps themes to their names
|
||||
String getThemeName(context, String theme) {
|
||||
String getThemeName(context, Settings settings, String theme) {
|
||||
switch (theme) {
|
||||
case cwtch_theme:
|
||||
return AppLocalizations.of(context)!.themeNameCwtch;
|
||||
|
@ -353,7 +352,7 @@ class _GlobalSettingsAppearanceViewState extends State<GlobalSettingsAppearanceV
|
|||
case "juniper":
|
||||
return "Juniper"; // Juniper is a noun, and doesn't get subject to translation...
|
||||
}
|
||||
return theme;
|
||||
return settings.themeloader.themes[theme]?[mode_light]?.theme ?? settings.themeloader.themes[theme]?[mode_dark]?.theme ?? theme;
|
||||
}
|
||||
|
||||
void importThemeCheck(BuildContext context, Settings settings, String themesDir, String newThemeDirectory) async {
|
||||
|
@ -372,7 +371,7 @@ class _GlobalSettingsAppearanceViewState extends State<GlobalSettingsAppearanceV
|
|||
|
||||
Directory targetDir = Directory(path.join(themesDir, themeName));
|
||||
// check if exists
|
||||
if (themes.containsKey(themeName) || targetDir.existsSync()) {
|
||||
if (settings.themeloader.themes.containsKey(themeName) || targetDir.existsSync()) {
|
||||
_modalConfirmOverwriteCustomTheme(srcDir, targetDir, themesDir, themeName, settings);
|
||||
} else {
|
||||
importTheme(srcDir, targetDir, themesDir, themeName, settings);
|
||||
|
@ -393,7 +392,7 @@ class _GlobalSettingsAppearanceViewState extends State<GlobalSettingsAppearanceV
|
|||
|
||||
var data = await loadFileYamlTheme(path.join(targetDir.path, "theme.yml"), targetDir.path);
|
||||
if (data != null) {
|
||||
themes[themeName] = data;
|
||||
settings.themeloader.themes[themeName] = data;
|
||||
}
|
||||
|
||||
if (settings.current().theme == themeName) {
|
||||
|
|
|
@ -5,7 +5,6 @@ import 'package:flutter/services.dart';
|
|||
import 'package:provider/provider.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
|
||||
import '../config.dart';
|
||||
import '../cwtch_icons_icons.dart';
|
||||
import '../settings.dart';
|
||||
import '../themes/opaque.dart';
|
||||
|
@ -70,108 +69,108 @@ class _GlobalSettingsBehaviourViewState extends State<GlobalSettingsBehaviourVie
|
|||
child: SingleChildScrollView(
|
||||
clipBehavior: Clip.antiAlias,
|
||||
controller: settingsListScrollController,
|
||||
padding: EdgeInsets.symmetric(vertical: 0, horizontal: 20),
|
||||
child: ConstrainedBox(
|
||||
constraints: BoxConstraints(
|
||||
minHeight: viewportConstraints.maxHeight,
|
||||
),
|
||||
child: Column(children: [
|
||||
Visibility(
|
||||
visible: Platform.isAndroid,
|
||||
child: SwitchListTile(
|
||||
title: Text(AppLocalizations.of(context)!.settingAndroidPowerExemption),
|
||||
subtitle: Text(AppLocalizations.of(context)!.settingAndroidPowerExemptionDescription),
|
||||
value: powerExempt,
|
||||
onChanged: (bool value) {
|
||||
if (value) {
|
||||
requestBatteryExemption();
|
||||
} else {
|
||||
// We can't ask for it to be turned off, show an informational popup
|
||||
showBatteryDialog(context);
|
||||
}
|
||||
},
|
||||
activeTrackColor: settings.theme.defaultButtonColor,
|
||||
inactiveTrackColor: settings.theme.defaultButtonDisabledColor,
|
||||
secondary: Icon(Icons.power, color: settings.current().mainTextColor),
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
title: Text(AppLocalizations.of(context)!.notificationPolicySettingLabel),
|
||||
subtitle: Text(AppLocalizations.of(context)!.notificationPolicySettingDescription),
|
||||
trailing: Container(
|
||||
width: MediaQuery.of(context).size.width / 4,
|
||||
child: DropdownButton(
|
||||
isExpanded: true,
|
||||
value: settings.notificationPolicy,
|
||||
onChanged: (NotificationPolicy? newValue) {
|
||||
settings.notificationPolicy = newValue!;
|
||||
saveSettings(context);
|
||||
},
|
||||
items: NotificationPolicy.values.map<DropdownMenuItem<NotificationPolicy>>((NotificationPolicy value) {
|
||||
return DropdownMenuItem<NotificationPolicy>(
|
||||
value: value,
|
||||
child: Text(Settings.notificationPolicyToString(value, context), overflow: TextOverflow.ellipsis, style: settings.scaleFonts(defaultDropDownMenuItemTextStyle)),
|
||||
);
|
||||
}).toList())),
|
||||
leading: Icon(CwtchIcons.chat_bubble_empty_24px, color: settings.current().mainTextColor),
|
||||
),
|
||||
ListTile(
|
||||
title: Text(AppLocalizations.of(context)!.notificationContentSettingLabel),
|
||||
subtitle: Text(AppLocalizations.of(context)!.notificationContentSettingDescription),
|
||||
trailing: Container(
|
||||
width: MediaQuery.of(context).size.width / 4,
|
||||
child: DropdownButton(
|
||||
isExpanded: true,
|
||||
value: settings.notificationContent,
|
||||
onChanged: (NotificationContent? newValue) {
|
||||
settings.notificationContent = newValue!;
|
||||
saveSettings(context);
|
||||
},
|
||||
items: NotificationContent.values.map<DropdownMenuItem<NotificationContent>>((NotificationContent value) {
|
||||
return DropdownMenuItem<NotificationContent>(
|
||||
value: value,
|
||||
child: Text(Settings.notificationContentToString(value, context), overflow: TextOverflow.ellipsis, style: settings.scaleFonts(defaultDropDownMenuItemTextStyle)),
|
||||
);
|
||||
}).toList())),
|
||||
leading: Icon(CwtchIcons.chat_bubble_empty_24px, color: settings.current().mainTextColor),
|
||||
),
|
||||
SwitchListTile(
|
||||
title: Text(AppLocalizations.of(context)!.blockUnknownLabel),
|
||||
subtitle: Text(AppLocalizations.of(context)!.descriptionBlockUnknownConnections),
|
||||
value: settings.blockUnknownConnections,
|
||||
onChanged: (bool value) {
|
||||
if (value) {
|
||||
settings.forbidUnknownConnections();
|
||||
} else {
|
||||
settings.allowUnknownConnections();
|
||||
}
|
||||
constraints: BoxConstraints(minHeight: viewportConstraints.maxHeight, maxWidth: viewportConstraints.maxWidth),
|
||||
child: Container(
|
||||
color: settings.theme.backgroundPaneColor,
|
||||
child: Column(children: [
|
||||
Visibility(
|
||||
visible: Platform.isAndroid,
|
||||
child: SwitchListTile(
|
||||
title: Text(AppLocalizations.of(context)!.settingAndroidPowerExemption),
|
||||
subtitle: Text(AppLocalizations.of(context)!.settingAndroidPowerExemptionDescription),
|
||||
value: powerExempt,
|
||||
onChanged: (bool value) {
|
||||
if (value) {
|
||||
requestBatteryExemption();
|
||||
} else {
|
||||
// We can't ask for it to be turned off, show an informational popup
|
||||
showBatteryDialog(context);
|
||||
}
|
||||
},
|
||||
activeTrackColor: settings.theme.defaultButtonColor,
|
||||
inactiveTrackColor: settings.theme.defaultButtonDisabledColor,
|
||||
secondary: Icon(Icons.power, color: settings.current().mainTextColor),
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
title: Text(AppLocalizations.of(context)!.notificationPolicySettingLabel),
|
||||
subtitle: Text(AppLocalizations.of(context)!.notificationPolicySettingDescription),
|
||||
trailing: Container(
|
||||
width: MediaQuery.of(context).size.width / 4,
|
||||
child: DropdownButton(
|
||||
isExpanded: true,
|
||||
value: settings.notificationPolicy,
|
||||
onChanged: (NotificationPolicy? newValue) {
|
||||
settings.notificationPolicy = newValue!;
|
||||
saveSettings(context);
|
||||
},
|
||||
items: NotificationPolicy.values.map<DropdownMenuItem<NotificationPolicy>>((NotificationPolicy value) {
|
||||
return DropdownMenuItem<NotificationPolicy>(
|
||||
value: value,
|
||||
child: Text(Settings.notificationPolicyToString(value, context), overflow: TextOverflow.ellipsis, style: settings.scaleFonts(defaultDropDownMenuItemTextStyle)),
|
||||
);
|
||||
}).toList())),
|
||||
leading: Icon(CwtchIcons.chat_bubble_empty_24px, color: settings.current().mainTextColor),
|
||||
),
|
||||
ListTile(
|
||||
title: Text(AppLocalizations.of(context)!.notificationContentSettingLabel),
|
||||
subtitle: Text(AppLocalizations.of(context)!.notificationContentSettingDescription),
|
||||
trailing: Container(
|
||||
width: MediaQuery.of(context).size.width / 4,
|
||||
child: DropdownButton(
|
||||
isExpanded: true,
|
||||
value: settings.notificationContent,
|
||||
onChanged: (NotificationContent? newValue) {
|
||||
settings.notificationContent = newValue!;
|
||||
saveSettings(context);
|
||||
},
|
||||
items: NotificationContent.values.map<DropdownMenuItem<NotificationContent>>((NotificationContent value) {
|
||||
return DropdownMenuItem<NotificationContent>(
|
||||
value: value,
|
||||
child:
|
||||
Text(Settings.notificationContentToString(value, context), overflow: TextOverflow.ellipsis, style: settings.scaleFonts(defaultDropDownMenuItemTextStyle)),
|
||||
);
|
||||
}).toList())),
|
||||
leading: Icon(CwtchIcons.chat_bubble_empty_24px, color: settings.current().mainTextColor),
|
||||
),
|
||||
SwitchListTile(
|
||||
title: Text(AppLocalizations.of(context)!.blockUnknownLabel),
|
||||
subtitle: Text(AppLocalizations.of(context)!.descriptionBlockUnknownConnections),
|
||||
value: settings.blockUnknownConnections,
|
||||
onChanged: (bool value) {
|
||||
if (value) {
|
||||
settings.forbidUnknownConnections();
|
||||
} else {
|
||||
settings.allowUnknownConnections();
|
||||
}
|
||||
|
||||
// Save Settings...
|
||||
saveSettings(context);
|
||||
},
|
||||
activeTrackColor: settings.theme.defaultButtonColor,
|
||||
inactiveTrackColor: settings.theme.defaultButtonDisabledColor,
|
||||
secondary: Icon(CwtchIcons.block_unknown, color: settings.current().mainTextColor),
|
||||
),
|
||||
SwitchListTile(
|
||||
title: Text(AppLocalizations.of(context)!.defaultPreserveHistorySetting),
|
||||
subtitle: Text(AppLocalizations.of(context)!.preserveHistorySettingDescription),
|
||||
value: settings.preserveHistoryByDefault,
|
||||
onChanged: (bool value) {
|
||||
if (value) {
|
||||
settings.setPreserveHistoryDefault();
|
||||
} else {
|
||||
settings.setDeleteHistoryDefault();
|
||||
}
|
||||
// Save Settings...
|
||||
saveSettings(context);
|
||||
},
|
||||
activeTrackColor: settings.theme.defaultButtonColor,
|
||||
inactiveTrackColor: settings.theme.defaultButtonDisabledColor,
|
||||
secondary: Icon(CwtchIcons.block_unknown, color: settings.current().mainTextColor),
|
||||
),
|
||||
SwitchListTile(
|
||||
title: Text(AppLocalizations.of(context)!.defaultPreserveHistorySetting),
|
||||
subtitle: Text(AppLocalizations.of(context)!.preserveHistorySettingDescription),
|
||||
value: settings.preserveHistoryByDefault,
|
||||
onChanged: (bool value) {
|
||||
if (value) {
|
||||
settings.setPreserveHistoryDefault();
|
||||
} else {
|
||||
settings.setDeleteHistoryDefault();
|
||||
}
|
||||
|
||||
// Save Settings...
|
||||
saveSettings(context);
|
||||
},
|
||||
activeTrackColor: settings.theme.defaultButtonColor,
|
||||
inactiveTrackColor: settings.theme.defaultButtonDisabledColor,
|
||||
secondary: Icon(CwtchIcons.peer_history, color: settings.current().mainTextColor),
|
||||
),
|
||||
]))));
|
||||
// Save Settings...
|
||||
saveSettings(context);
|
||||
},
|
||||
activeTrackColor: settings.theme.defaultButtonColor,
|
||||
inactiveTrackColor: settings.theme.defaultButtonDisabledColor,
|
||||
secondary: Icon(CwtchIcons.peer_history, color: settings.current().mainTextColor),
|
||||
),
|
||||
])))));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ import 'package:flutter/material.dart';
|
|||
import 'package:provider/provider.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
|
||||
import '../config.dart';
|
||||
import '../cwtch_icons_icons.dart';
|
||||
import '../main.dart';
|
||||
import '../models/servers.dart';
|
||||
|
@ -31,211 +30,210 @@ class _GlobalSettingsExperimentsViewState extends State<GlobalSettingsExperiment
|
|||
child: SingleChildScrollView(
|
||||
clipBehavior: Clip.antiAlias,
|
||||
controller: settingsListScrollController,
|
||||
padding: EdgeInsets.symmetric(vertical: 0, horizontal: 20),
|
||||
child: ConstrainedBox(
|
||||
constraints: BoxConstraints(
|
||||
minHeight: viewportConstraints.maxHeight,
|
||||
),
|
||||
child: Column(children: [
|
||||
SwitchListTile(
|
||||
title: Text(AppLocalizations.of(context)!.experimentsEnabled),
|
||||
subtitle: Text(AppLocalizations.of(context)!.descriptionExperiments),
|
||||
value: settings.experimentsEnabled,
|
||||
onChanged: (bool value) {
|
||||
if (value) {
|
||||
settings.enableExperiments();
|
||||
} else {
|
||||
settings.disableExperiments();
|
||||
}
|
||||
// Save Settings...
|
||||
saveSettings(context);
|
||||
},
|
||||
activeTrackColor: settings.theme.defaultButtonColor,
|
||||
inactiveTrackColor: settings.theme.defaultButtonDisabledColor,
|
||||
secondary: Icon(CwtchIcons.enable_experiments, color: settings.current().mainTextColor),
|
||||
),
|
||||
Visibility(
|
||||
visible: settings.experimentsEnabled,
|
||||
child: Column(
|
||||
children: [
|
||||
SwitchListTile(
|
||||
title: Text(AppLocalizations.of(context)!.enableGroups),
|
||||
subtitle: Text(AppLocalizations.of(context)!.descriptionExperimentsGroups),
|
||||
value: settings.isExperimentEnabled(TapirGroupsExperiment),
|
||||
onChanged: (bool value) {
|
||||
if (value) {
|
||||
settings.enableExperiment(TapirGroupsExperiment);
|
||||
} else {
|
||||
settings.disableExperiment(TapirGroupsExperiment);
|
||||
}
|
||||
// Save Settings...
|
||||
saveSettings(context);
|
||||
},
|
||||
activeTrackColor: settings.theme.defaultButtonColor,
|
||||
inactiveTrackColor: settings.theme.defaultButtonDisabledColor,
|
||||
secondary: Icon(CwtchIcons.enable_groups, color: settings.current().mainTextColor),
|
||||
),
|
||||
Visibility(
|
||||
visible: !Platform.isAndroid && !Platform.isIOS,
|
||||
child: SwitchListTile(
|
||||
title: Text(AppLocalizations.of(context)!.settingServers),
|
||||
subtitle: Provider.of<FlwtchState>(context, listen: false).cwtch.IsServersCompiled()
|
||||
? Text(AppLocalizations.of(context)!.settingServersDescription)
|
||||
: Text("This version of Cwtch has been compiled without support for the server hosting experiment."),
|
||||
value: Provider.of<FlwtchState>(context, listen: false).cwtch.IsServersCompiled() && settings.isExperimentEnabled(ServerManagementExperiment),
|
||||
onChanged: Provider.of<FlwtchState>(context, listen: false).cwtch.IsServersCompiled()
|
||||
? (bool value) {
|
||||
Provider.of<ServerListState>(context, listen: false).clear();
|
||||
if (value) {
|
||||
settings.enableExperiment(ServerManagementExperiment);
|
||||
} else {
|
||||
settings.disableExperiment(ServerManagementExperiment);
|
||||
}
|
||||
// Save Settings...
|
||||
saveSettings(context);
|
||||
}
|
||||
: null,
|
||||
constraints: BoxConstraints(minHeight: viewportConstraints.maxHeight, maxWidth: viewportConstraints.maxWidth),
|
||||
child: Container(
|
||||
color: settings.theme.backgroundPaneColor,
|
||||
child: Column(children: [
|
||||
SwitchListTile(
|
||||
title: Text(AppLocalizations.of(context)!.experimentsEnabled),
|
||||
subtitle: Text(AppLocalizations.of(context)!.descriptionExperiments),
|
||||
value: settings.experimentsEnabled,
|
||||
onChanged: (bool value) {
|
||||
if (value) {
|
||||
settings.enableExperiments();
|
||||
} else {
|
||||
settings.disableExperiments();
|
||||
}
|
||||
// Save Settings...
|
||||
saveSettings(context);
|
||||
},
|
||||
activeTrackColor: settings.theme.defaultButtonColor,
|
||||
inactiveTrackColor: settings.theme.defaultButtonDisabledColor,
|
||||
secondary: Icon(CwtchIcons.enable_experiments, color: settings.current().mainTextColor),
|
||||
),
|
||||
Visibility(
|
||||
visible: settings.experimentsEnabled,
|
||||
child: Column(
|
||||
children: [
|
||||
SwitchListTile(
|
||||
title: Text(AppLocalizations.of(context)!.enableGroups),
|
||||
subtitle: Text(AppLocalizations.of(context)!.descriptionExperimentsGroups),
|
||||
value: settings.isExperimentEnabled(TapirGroupsExperiment),
|
||||
onChanged: (bool value) {
|
||||
if (value) {
|
||||
settings.enableExperiment(TapirGroupsExperiment);
|
||||
} else {
|
||||
settings.disableExperiment(TapirGroupsExperiment);
|
||||
}
|
||||
// Save Settings...
|
||||
saveSettings(context);
|
||||
},
|
||||
activeTrackColor: settings.theme.defaultButtonColor,
|
||||
inactiveTrackColor: settings.theme.defaultButtonDisabledColor,
|
||||
inactiveThumbColor: settings.theme.defaultButtonDisabledColor,
|
||||
secondary: Icon(CwtchIcons.dns_24px),
|
||||
)),
|
||||
SwitchListTile(
|
||||
title: Text(AppLocalizations.of(context)!.settingFileSharing),
|
||||
subtitle: Text(AppLocalizations.of(context)!.descriptionFileSharing),
|
||||
value: settings.isExperimentEnabled(FileSharingExperiment),
|
||||
onChanged: (bool value) {
|
||||
if (value) {
|
||||
if (checkDownloadDirectory(context, settings)) {
|
||||
settings.enableExperiment(FileSharingExperiment);
|
||||
} else {
|
||||
settings.enableExperiment(FileSharingExperiment);
|
||||
settings.disableExperiment(ImagePreviewsExperiment);
|
||||
}
|
||||
} else {
|
||||
settings.disableExperiment(FileSharingExperiment);
|
||||
settings.disableExperiment(ImagePreviewsExperiment);
|
||||
}
|
||||
saveSettings(context);
|
||||
},
|
||||
activeTrackColor: settings.theme.defaultButtonColor,
|
||||
inactiveTrackColor: settings.theme.defaultButtonDisabledColor,
|
||||
secondary: Icon(CwtchIcons.attached_file_3, color: settings.current().mainTextColor),
|
||||
),
|
||||
Visibility(
|
||||
visible: settings.isExperimentEnabled(FileSharingExperiment),
|
||||
child: Column(children: [
|
||||
secondary: Icon(CwtchIcons.enable_groups, color: settings.current().mainTextColor),
|
||||
),
|
||||
Visibility(
|
||||
visible: !Platform.isAndroid && !Platform.isIOS,
|
||||
child: SwitchListTile(
|
||||
title: Text(AppLocalizations.of(context)!.settingServers),
|
||||
subtitle: Provider.of<FlwtchState>(context, listen: false).cwtch.IsServersCompiled()
|
||||
? Text(AppLocalizations.of(context)!.settingServersDescription)
|
||||
: Text("This version of Cwtch has been compiled without support for the server hosting experiment."),
|
||||
value: Provider.of<FlwtchState>(context, listen: false).cwtch.IsServersCompiled() && settings.isExperimentEnabled(ServerManagementExperiment),
|
||||
onChanged: Provider.of<FlwtchState>(context, listen: false).cwtch.IsServersCompiled()
|
||||
? (bool value) {
|
||||
Provider.of<ServerListState>(context, listen: false).clear();
|
||||
if (value) {
|
||||
settings.enableExperiment(ServerManagementExperiment);
|
||||
} else {
|
||||
settings.disableExperiment(ServerManagementExperiment);
|
||||
}
|
||||
// Save Settings...
|
||||
saveSettings(context);
|
||||
}
|
||||
: null,
|
||||
activeTrackColor: settings.theme.defaultButtonColor,
|
||||
inactiveTrackColor: settings.theme.defaultButtonDisabledColor,
|
||||
secondary: Icon(CwtchIcons.dns_24px),
|
||||
)),
|
||||
SwitchListTile(
|
||||
title: Text(AppLocalizations.of(context)!.settingImagePreviews),
|
||||
subtitle: Text(AppLocalizations.of(context)!.settingImagePreviewsDescription),
|
||||
value: settings.isExperimentEnabled(ImagePreviewsExperiment),
|
||||
title: Text(AppLocalizations.of(context)!.settingFileSharing),
|
||||
subtitle: Text(AppLocalizations.of(context)!.descriptionFileSharing),
|
||||
value: settings.isExperimentEnabled(FileSharingExperiment),
|
||||
onChanged: (bool value) {
|
||||
if (value) {
|
||||
if (checkDownloadDirectory(context, settings)) {
|
||||
settings.enableExperiment(ImagePreviewsExperiment);
|
||||
settings.enableExperiment(FileSharingExperiment);
|
||||
} else {
|
||||
settings.enableExperiment(FileSharingExperiment);
|
||||
settings.disableExperiment(ImagePreviewsExperiment);
|
||||
}
|
||||
} else {
|
||||
settings.disableExperiment(FileSharingExperiment);
|
||||
settings.disableExperiment(ImagePreviewsExperiment);
|
||||
}
|
||||
saveSettings(context);
|
||||
},
|
||||
activeTrackColor: settings.theme.defaultButtonActiveColor,
|
||||
activeTrackColor: settings.theme.defaultButtonColor,
|
||||
inactiveTrackColor: settings.theme.defaultButtonDisabledColor,
|
||||
secondary: Icon(Icons.photo, color: settings.current().mainTextColor),
|
||||
secondary: Icon(CwtchIcons.attached_file_3, color: settings.current().mainTextColor),
|
||||
),
|
||||
Visibility(
|
||||
visible: settings.isExperimentEnabled(ImagePreviewsExperiment) && !Platform.isAndroid,
|
||||
visible: settings.isExperimentEnabled(FileSharingExperiment),
|
||||
child: Column(children: [
|
||||
SwitchListTile(
|
||||
title: Text(AppLocalizations.of(context)!.settingImagePreviews),
|
||||
subtitle: Text(AppLocalizations.of(context)!.settingImagePreviewsDescription),
|
||||
value: settings.isExperimentEnabled(ImagePreviewsExperiment),
|
||||
onChanged: (bool value) {
|
||||
if (value) {
|
||||
if (checkDownloadDirectory(context, settings)) {
|
||||
settings.enableExperiment(ImagePreviewsExperiment);
|
||||
} else {
|
||||
settings.disableExperiment(ImagePreviewsExperiment);
|
||||
}
|
||||
} else {
|
||||
settings.disableExperiment(ImagePreviewsExperiment);
|
||||
}
|
||||
saveSettings(context);
|
||||
},
|
||||
activeTrackColor: settings.theme.defaultButtonColor,
|
||||
inactiveTrackColor: settings.theme.defaultButtonDisabledColor,
|
||||
secondary: Icon(Icons.photo, color: settings.current().mainTextColor),
|
||||
),
|
||||
Visibility(
|
||||
visible: settings.isExperimentEnabled(ImagePreviewsExperiment) && !Platform.isAndroid,
|
||||
child: CwtchFolderPicker(
|
||||
testKey: Key("DownloadFolderPicker"),
|
||||
label: AppLocalizations.of(context)!.settingDownloadFolder,
|
||||
initialValue: settings.downloadPath,
|
||||
textStyle: settings.scaleFonts(defaultDropDownMenuItemTextStyle),
|
||||
description: AppLocalizations.of(context)!.fileSharingSettingsDownloadFolderDescription,
|
||||
tooltip: AppLocalizations.of(context)!.fileSharingSettingsDownloadFolderTooltip,
|
||||
onSave: (newVal) {
|
||||
settings.downloadPath = newVal;
|
||||
saveSettings(context);
|
||||
},
|
||||
),
|
||||
),
|
||||
]),
|
||||
),
|
||||
Visibility(
|
||||
visible: Provider.of<FlwtchState>(context, listen: false).cwtch.IsBlodeuweddSupported(),
|
||||
child: SwitchListTile(
|
||||
title: Text(AppLocalizations.of(context)!.blodeuweddExperimentEnable),
|
||||
subtitle: Provider.of<FlwtchState>(context, listen: false).cwtch.IsBlodeuweddSupported()
|
||||
? Text(AppLocalizations.of(context)!.blodeuweddDescription)
|
||||
: Text(AppLocalizations.of(context)!.blodeuweddNotSupported),
|
||||
value: Provider.of<FlwtchState>(context, listen: false).cwtch.IsBlodeuweddSupported() && settings.isExperimentEnabled(BlodeuweddExperiment),
|
||||
onChanged: Provider.of<FlwtchState>(context, listen: false).cwtch.IsBlodeuweddSupported()
|
||||
? (bool value) {
|
||||
if (value) {
|
||||
settings.enableExperiment(BlodeuweddExperiment);
|
||||
} else {
|
||||
settings.disableExperiment(BlodeuweddExperiment);
|
||||
}
|
||||
saveSettings(context);
|
||||
}
|
||||
: null,
|
||||
activeTrackColor: settings.theme.defaultButtonColor,
|
||||
inactiveTrackColor: settings.theme.defaultButtonDisabledColor,
|
||||
secondary: Icon(Icons.assistant, color: settings.current().mainTextColor),
|
||||
)),
|
||||
Visibility(
|
||||
visible: Provider.of<FlwtchState>(context, listen: false).cwtch.IsBlodeuweddSupported() && settings.isExperimentEnabled(BlodeuweddExperiment),
|
||||
child: CwtchFolderPicker(
|
||||
testKey: Key("DownloadFolderPicker"),
|
||||
label: AppLocalizations.of(context)!.settingDownloadFolder,
|
||||
initialValue: settings.downloadPath,
|
||||
textStyle: settings.scaleFonts(defaultDropDownMenuItemTextStyle),
|
||||
description: AppLocalizations.of(context)!.fileSharingSettingsDownloadFolderDescription,
|
||||
tooltip: AppLocalizations.of(context)!.fileSharingSettingsDownloadFolderTooltip,
|
||||
initialValue: settings.blodeuweddPath,
|
||||
description: AppLocalizations.of(context)!.blodeuweddPath,
|
||||
tooltip: AppLocalizations.of(context)!.blodeuweddPath,
|
||||
onSave: (newVal) {
|
||||
settings.downloadPath = newVal;
|
||||
settings.blodeuweddPath = newVal;
|
||||
saveSettings(context);
|
||||
},
|
||||
),
|
||||
),
|
||||
]),
|
||||
),
|
||||
SwitchListTile(
|
||||
title: Text(AppLocalizations.of(context)!.blodeuweddExperimentEnable),
|
||||
subtitle: Provider.of<FlwtchState>(context, listen: false).cwtch.IsBlodeuweddSupported()
|
||||
? Text(AppLocalizations.of(context)!.blodeuweddDescription)
|
||||
: Text(AppLocalizations.of(context)!.blodeuweddNotSupported),
|
||||
value: Provider.of<FlwtchState>(context, listen: false).cwtch.IsBlodeuweddSupported() && settings.isExperimentEnabled(BlodeuweddExperiment),
|
||||
onChanged: Provider.of<FlwtchState>(context, listen: false).cwtch.IsBlodeuweddSupported()
|
||||
? (bool value) {
|
||||
if (value) {
|
||||
settings.enableExperiment(BlodeuweddExperiment);
|
||||
} else {
|
||||
settings.disableExperiment(BlodeuweddExperiment);
|
||||
}
|
||||
saveSettings(context);
|
||||
}
|
||||
: null,
|
||||
],
|
||||
)),
|
||||
Visibility(
|
||||
visible: settings.experimentsEnabled,
|
||||
child: SwitchListTile(
|
||||
title: Text(AppLocalizations.of(context)!.enableExperimentClickableLinks),
|
||||
subtitle: Text(AppLocalizations.of(context)!.experimentClickableLinksDescription),
|
||||
value: settings.isExperimentEnabled(ClickableLinksExperiment),
|
||||
onChanged: (bool value) {
|
||||
if (value) {
|
||||
settings.enableExperiment(ClickableLinksExperiment);
|
||||
} else {
|
||||
settings.disableExperiment(ClickableLinksExperiment);
|
||||
}
|
||||
saveSettings(context);
|
||||
},
|
||||
activeTrackColor: settings.theme.defaultButtonColor,
|
||||
inactiveTrackColor: settings.theme.defaultButtonDisabledColor,
|
||||
inactiveThumbColor: settings.theme.defaultButtonDisabledColor,
|
||||
secondary: Icon(Icons.assistant, color: settings.current().mainTextColor),
|
||||
),
|
||||
Visibility(
|
||||
visible: Provider.of<FlwtchState>(context, listen: false).cwtch.IsBlodeuweddSupported() && settings.isExperimentEnabled(BlodeuweddExperiment),
|
||||
child: CwtchFolderPicker(
|
||||
testKey: Key("DownloadFolderPicker"),
|
||||
label: AppLocalizations.of(context)!.settingDownloadFolder,
|
||||
initialValue: settings.blodeuweddPath,
|
||||
description: AppLocalizations.of(context)!.blodeuweddPath,
|
||||
tooltip: AppLocalizations.of(context)!.blodeuweddPath,
|
||||
onSave: (newVal) {
|
||||
settings.blodeuweddPath = newVal;
|
||||
saveSettings(context);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
)),
|
||||
Visibility(
|
||||
visible: settings.experimentsEnabled,
|
||||
child: SwitchListTile(
|
||||
title: Text(AppLocalizations.of(context)!.enableExperimentClickableLinks),
|
||||
subtitle: Text(AppLocalizations.of(context)!.experimentClickableLinksDescription),
|
||||
value: settings.isExperimentEnabled(ClickableLinksExperiment),
|
||||
onChanged: (bool value) {
|
||||
if (value) {
|
||||
settings.enableExperiment(ClickableLinksExperiment);
|
||||
} else {
|
||||
settings.disableExperiment(ClickableLinksExperiment);
|
||||
}
|
||||
saveSettings(context);
|
||||
},
|
||||
activeTrackColor: settings.theme.defaultButtonActiveColor,
|
||||
inactiveTrackColor: settings.theme.defaultButtonDisabledColor,
|
||||
secondary: Icon(Icons.link, color: settings.current().mainTextColor),
|
||||
)),
|
||||
Visibility(
|
||||
visible: settings.experimentsEnabled,
|
||||
child: SwitchListTile(
|
||||
title: Text(AppLocalizations.of(context)!.enableExperimentQRCode),
|
||||
subtitle: Text(AppLocalizations.of(context)!.experimentQRCodeDescription),
|
||||
value: settings.isExperimentEnabled(QRCodeExperiment),
|
||||
onChanged: (bool value) {
|
||||
if (value) {
|
||||
settings.enableExperiment(QRCodeExperiment);
|
||||
} else {
|
||||
settings.disableExperiment(QRCodeExperiment);
|
||||
}
|
||||
saveSettings(context);
|
||||
},
|
||||
activeTrackColor: settings.theme.defaultButtonActiveColor,
|
||||
inactiveTrackColor: settings.theme.defaultButtonDisabledColor,
|
||||
secondary: Icon(Icons.qr_code, color: settings.current().mainTextColor),
|
||||
)),
|
||||
]))));
|
||||
secondary: Icon(Icons.link, color: settings.current().mainTextColor),
|
||||
)),
|
||||
Visibility(
|
||||
visible: settings.experimentsEnabled,
|
||||
child: SwitchListTile(
|
||||
title: Text(AppLocalizations.of(context)!.enableExperimentQRCode),
|
||||
subtitle: Text(AppLocalizations.of(context)!.experimentQRCodeDescription),
|
||||
value: settings.isExperimentEnabled(QRCodeExperiment),
|
||||
onChanged: (bool value) {
|
||||
if (value) {
|
||||
settings.enableExperiment(QRCodeExperiment);
|
||||
} else {
|
||||
settings.disableExperiment(QRCodeExperiment);
|
||||
}
|
||||
saveSettings(context);
|
||||
},
|
||||
activeTrackColor: settings.theme.defaultButtonColor,
|
||||
inactiveTrackColor: settings.theme.defaultButtonDisabledColor,
|
||||
secondary: Icon(Icons.qr_code, color: settings.current().mainTextColor),
|
||||
)),
|
||||
])))));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,24 +1,15 @@
|
|||
import 'dart:collection';
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'package:cwtch/cwtch_icons_icons.dart';
|
||||
import 'package:cwtch/models/servers.dart';
|
||||
import 'package:cwtch/views/globalsettingsaboutview.dart';
|
||||
import 'package:cwtch/views/globalsettingsappearanceview.dart';
|
||||
import 'package:cwtch/views/globalsettingsbehaviourview.dart';
|
||||
import 'package:cwtch/views/globalsettingsexperimentsview.dart';
|
||||
import 'package:cwtch/widgets/folderpicker.dart';
|
||||
import 'package:cwtch/themes/cwtch.dart';
|
||||
import 'package:cwtch/themes/opaque.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:package_info_plus/package_info_plus.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:cwtch/settings.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
|
||||
import '../main.dart';
|
||||
import '../config.dart';
|
||||
|
||||
/// Global Settings View provides access to modify all the Globally Relevant Settings including Locale, Theme and Experiments.
|
||||
class GlobalSettingsView extends StatefulWidget {
|
||||
|
|
|
@ -71,8 +71,8 @@ class _GroupSettingsViewState extends State<GroupSettingsView> {
|
|||
minHeight: viewportConstraints.maxHeight,
|
||||
),
|
||||
child: Container(
|
||||
margin: EdgeInsets.all(10),
|
||||
padding: EdgeInsets.all(2),
|
||||
color: settings.theme.backgroundPaneColor,
|
||||
padding: EdgeInsets.all(12),
|
||||
child: Column(mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.stretch, children: [
|
||||
// Nickname Save Button
|
||||
Column(mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [
|
||||
|
@ -109,7 +109,9 @@ class _GroupSettingsViewState extends State<GroupSettingsView> {
|
|||
),
|
||||
CwtchTextField(
|
||||
controller: TextEditingController(text: Provider.of<ContactInfoState>(context, listen: false).server),
|
||||
validator: (value) {},
|
||||
validator: (value) {
|
||||
return null;
|
||||
},
|
||||
hintText: '',
|
||||
)
|
||||
]),
|
||||
|
|
|
@ -2,7 +2,6 @@ import 'dart:async';
|
|||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'dart:math';
|
||||
import 'dart:ui';
|
||||
import 'package:crypto/crypto.dart';
|
||||
import 'package:cwtch/cwtch/cwtch.dart';
|
||||
import 'package:cwtch/cwtch_icons_icons.dart';
|
||||
|
@ -91,7 +90,7 @@ class _MessageViewState extends State<MessageView> {
|
|||
Widget build(BuildContext context) {
|
||||
// After leaving a conversation the selected conversation is set to null...
|
||||
if (Provider.of<ContactInfoState>(context, listen: false).profileOnion == "") {
|
||||
return Card(child: Center(child: Text(AppLocalizations.of(context)!.addContactFirst)));
|
||||
return Container(color: Provider.of<Settings>(context).theme.backgroundMainColor, child: Center(child: Text(AppLocalizations.of(context)!.addContactFirst)));
|
||||
}
|
||||
|
||||
var showMessageFormattingPreview = Provider.of<Settings>(context).isExperimentEnabled(FormattingExperiment);
|
||||
|
@ -178,8 +177,8 @@ class _MessageViewState extends State<MessageView> {
|
|||
onPressed: _pushContactSettings));
|
||||
|
||||
var appState = Provider.of<AppState>(context);
|
||||
return WillPopScope(
|
||||
onWillPop: _onWillPop,
|
||||
return PopScope(
|
||||
onPopInvoked: _onWillPop,
|
||||
child: Scaffold(
|
||||
backgroundColor: Provider.of<Settings>(context).theme.backgroundMainColor,
|
||||
floatingActionButton: showDown
|
||||
|
@ -259,7 +258,7 @@ class _MessageViewState extends State<MessageView> {
|
|||
actions: appBarButtons,
|
||||
),
|
||||
body: Padding(
|
||||
padding: EdgeInsets.fromLTRB(8.0, 8.0, 8.0, 182.0),
|
||||
padding: EdgeInsets.fromLTRB(8.0, 8.0, 8.0, 164.0),
|
||||
child: MessageList(
|
||||
scrollListener,
|
||||
)),
|
||||
|
@ -267,7 +266,7 @@ class _MessageViewState extends State<MessageView> {
|
|||
));
|
||||
}
|
||||
|
||||
Future<bool> _onWillPop() async {
|
||||
Future<bool> _onWillPop(popd) async {
|
||||
Provider.of<ContactInfoState>(context, listen: false).unreadMessages = 0;
|
||||
|
||||
var previouslySelected = Provider.of<AppState>(context, listen: false).selectedConversation;
|
||||
|
@ -435,6 +434,7 @@ class _MessageViewState extends State<MessageView> {
|
|||
|
||||
Provider.of<FlwtchState>(context, listen: false).cwtch.SetConversationAttribute(profileOnion, identifier, LastMessageSeenTimeKey, DateTime.now().toIso8601String());
|
||||
focusNode.requestFocus();
|
||||
Provider.of<ContactInfoState>(context, listen: false).messageDraft.clearDraft();
|
||||
}
|
||||
|
||||
Widget senderInviteChrome(String chrome, String targetName) {
|
||||
|
@ -488,7 +488,7 @@ class _MessageViewState extends State<MessageView> {
|
|||
backgroundColor: Provider.of<Settings>(context).theme.messageFromOtherBackgroundColor),
|
||||
textAlign: TextAlign.left,
|
||||
textWidthBasis: TextWidthBasis.longestLine,
|
||||
constraints: BoxConstraints.expand(),
|
||||
constraints: null,
|
||||
));
|
||||
|
||||
var showMessageFormattingPreview = Provider.of<Settings>(context).isExperimentEnabled(FormattingExperiment);
|
||||
|
@ -632,9 +632,9 @@ class _MessageViewState extends State<MessageView> {
|
|||
|
||||
var textField = Container(
|
||||
decoration: BoxDecoration(border: Border(top: BorderSide(color: Provider.of<Settings>(context).theme.defaultButtonActiveColor))),
|
||||
child: RawKeyboardListener(
|
||||
child: KeyboardListener(
|
||||
focusNode: FocusNode(),
|
||||
onKey: handleKeyPress,
|
||||
onKeyEvent: handleKeyPress,
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(8),
|
||||
child: TextFormField(
|
||||
|
@ -807,21 +807,21 @@ class _MessageViewState extends State<MessageView> {
|
|||
children = [invite, composeBox];
|
||||
}
|
||||
|
||||
return Container(color: Provider.of<Settings>(context).theme.backgroundMainColor, child: Column(mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: children));
|
||||
return Container(
|
||||
color: Provider.of<Settings>(context).theme.backgroundMainColor, child: Column(mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.stretch, children: children));
|
||||
}
|
||||
|
||||
// Send the message if enter is pressed without the shift key...
|
||||
void handleKeyPress(RawKeyEvent event) {
|
||||
var data = event.data;
|
||||
if (event is RawKeyUpEvent) {
|
||||
if ((data.logicalKey == LogicalKeyboardKey.enter && !event.isShiftPressed) || data.logicalKey == LogicalKeyboardKey.numpadEnter && !event.isShiftPressed) {
|
||||
// Don't send when inserting a new line that is not at the end of the message
|
||||
if (Provider.of<ContactInfoState>(context, listen: false).messageDraft.ctrlCompose.selection.baseOffset !=
|
||||
Provider.of<ContactInfoState>(context, listen: false).messageDraft.ctrlCompose.text.length) {
|
||||
return;
|
||||
}
|
||||
_sendMessage();
|
||||
void handleKeyPress(KeyEvent event) {
|
||||
var key = event.logicalKey;
|
||||
if ((event.logicalKey == LogicalKeyboardKey.enter && !HardwareKeyboard.instance.isShiftPressed) || event.logicalKey == LogicalKeyboardKey.numpadEnter && HardwareKeyboard.instance.isShiftPressed) {
|
||||
// Don't send when inserting a new line that is not at the end of the message
|
||||
if (Provider.of<ContactInfoState>(context, listen: false).messageDraft.ctrlCompose.selection.baseOffset !=
|
||||
Provider.of<ContactInfoState>(context, listen: false).messageDraft.ctrlCompose.text.length) {
|
||||
return;
|
||||
}
|
||||
_sendMessage();
|
||||
Provider.of<ContactInfoState>(context, listen: false).messageDraft.clearDraft();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:ui';
|
||||
import 'package:cwtch/config.dart';
|
||||
import 'package:cwtch/cwtch_icons_icons.dart';
|
||||
import 'package:cwtch/models/appstate.dart';
|
||||
|
@ -107,8 +105,8 @@ class _PeerSettingsViewState extends State<PeerSettingsView> {
|
|||
minHeight: viewportConstraints.maxHeight,
|
||||
),
|
||||
child: Container(
|
||||
margin: EdgeInsets.all(10),
|
||||
padding: EdgeInsets.all(2),
|
||||
color: settings.theme.backgroundPaneColor,
|
||||
padding: EdgeInsets.all(12),
|
||||
child: Column(mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.center, children: [
|
||||
Column(crossAxisAlignment: CrossAxisAlignment.center, children: [
|
||||
ProfileImage(
|
||||
|
|
|
@ -16,7 +16,6 @@ import 'package:flutter/services.dart';
|
|||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
import 'package:cwtch/widgets/profilerow.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import '../config.dart';
|
||||
import '../main.dart';
|
||||
import '../torstatus.dart';
|
||||
import 'addeditprofileview.dart';
|
||||
|
@ -178,7 +177,7 @@ class _ProfileMgrViewState extends State<ProfileMgrView> {
|
|||
);
|
||||
}
|
||||
|
||||
void _pushAddProfile(bcontext, {onion: ""}) {
|
||||
void _pushAddProfile(bcontext, {onion = ""}) {
|
||||
Navigator.popUntil(bcontext, (route) => route.isFirst);
|
||||
|
||||
Navigator.of(context).push(
|
||||
|
@ -246,11 +245,11 @@ class _ProfileMgrViewState extends State<ProfileMgrView> {
|
|||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
minimumSize: Size(399, 20),
|
||||
backgroundColor: Provider.of<Settings>(context).theme.backgroundMainColor,
|
||||
maximumSize: Size(400, 20),
|
||||
shape: RoundedRectangleBorder(
|
||||
side: BorderSide(color: Provider.of<Settings>(context).theme.defaultButtonActiveColor, width: 2.0),
|
||||
borderRadius: BorderRadius.horizontal(left: Radius.circular(180), right: Radius.circular(180))),
|
||||
primary: Provider.of<Settings>(context).theme.backgroundMainColor,
|
||||
),
|
||||
child: Text(AppLocalizations.of(context)!.importProfile,
|
||||
semanticsLabel: AppLocalizations.of(context)!.importProfile,
|
||||
|
@ -308,7 +307,9 @@ class _ProfileMgrViewState extends State<ProfileMgrView> {
|
|||
autofocus: true,
|
||||
controller: ctrlrPassword,
|
||||
action: unlock,
|
||||
validator: (value) {},
|
||||
validator: (value) {
|
||||
return null;
|
||||
},
|
||||
),
|
||||
SizedBox(
|
||||
height: 20,
|
||||
|
@ -379,6 +380,7 @@ class _ProfileMgrViewState extends State<ProfileMgrView> {
|
|||
|
||||
final divided = ListTile.divideTiles(
|
||||
context: context,
|
||||
color: Provider.of<Settings>(context).theme.backgroundPaneColor,
|
||||
tiles: widgetTiles,
|
||||
).toList();
|
||||
|
||||
|
|
|
@ -1,26 +1,15 @@
|
|||
import 'dart:convert';
|
||||
import 'package:cwtch/cwtch/cwtch.dart';
|
||||
import 'package:cwtch/cwtch_icons_icons.dart';
|
||||
import 'package:cwtch/models/contact.dart';
|
||||
import 'package:cwtch/models/profile.dart';
|
||||
import 'package:cwtch/models/profileservers.dart';
|
||||
import 'package:cwtch/models/remoteserver.dart';
|
||||
import 'package:cwtch/models/servers.dart';
|
||||
import 'package:cwtch/widgets/buttontextfield.dart';
|
||||
import 'package:cwtch/widgets/contactrow.dart';
|
||||
import 'package:cwtch/widgets/cwtchlabel.dart';
|
||||
import 'package:cwtch/widgets/passwordfield.dart';
|
||||
import 'package:cwtch/widgets/textfield.dart';
|
||||
import 'package:package_info_plus/package_info_plus.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:cwtch/settings.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
|
||||
import '../errorHandler.dart';
|
||||
import '../main.dart';
|
||||
import '../config.dart';
|
||||
import '../models/appstate.dart';
|
||||
import '../themes/opaque.dart';
|
||||
|
||||
/// Pane to add or edit a server
|
||||
|
|
|
@ -3,8 +3,6 @@ import 'package:cwtch/views/addeditservers.dart';
|
|||
import 'package:cwtch/widgets/passwordfield.dart';
|
||||
import 'package:cwtch/widgets/serverrow.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:cwtch/torstatus.dart';
|
||||
import 'package:cwtch/widgets/tor_icon.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
|
||||
|
@ -112,7 +110,9 @@ class _ServersView extends State<ServersView> {
|
|||
autofocus: true,
|
||||
controller: ctrlrPassword,
|
||||
action: unlock,
|
||||
validator: (value) {},
|
||||
validator: (value) {
|
||||
return null;
|
||||
},
|
||||
),
|
||||
SizedBox(
|
||||
height: 20,
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
import 'package:cwtch/config.dart';
|
||||
import 'package:cwtch/models/appstate.dart';
|
||||
import 'package:cwtch/themes/opaque.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
|
||||
import '../main.dart';
|
||||
import '../settings.dart';
|
||||
import '../themes/cwtch.dart';
|
||||
|
||||
class SplashView extends StatefulWidget {
|
||||
@override
|
||||
|
@ -16,6 +17,7 @@ class SplashView extends StatefulWidget {
|
|||
class _SplashViewState extends State<SplashView> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
EnvironmentConfig.debugLog("building splash screen...");
|
||||
var cwtch = Provider.of<FlwtchState>(context, listen: false).cwtch;
|
||||
if (!cwtch.isL10nInit()) {
|
||||
if (AppLocalizations.of(context) != null && AppLocalizations.of(context)!.newMessageNotificationSimple.isNotEmpty) {
|
||||
|
@ -25,6 +27,7 @@ class _SplashViewState extends State<SplashView> {
|
|||
|
||||
return Consumer<AppState>(
|
||||
builder: (context, appState, child) => Scaffold(
|
||||
backgroundColor: darkGreyPurple, // Cwtch Dark Background
|
||||
key: Key("SplashView"),
|
||||
body: Center(
|
||||
child: Column(mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [
|
||||
|
@ -53,8 +56,7 @@ class _SplashViewState extends State<SplashView> {
|
|||
: appState.modalState == ModalState.storageMigration
|
||||
? AppLocalizations.of(context)!.storageMigrationModalMessage
|
||||
: AppLocalizations.of(context)!.shuttingDownApp, // Todo l10n AppLocalizations.of(context)!.storageMigrationModalMessage
|
||||
style: defaultTextButtonStyle.copyWith(
|
||||
fontSize: 16.0, color: appState.appError == "" ? Provider.of<Settings>(context).theme.mainTextColor : Provider.of<Settings>(context).theme.textfieldErrorColor))),
|
||||
style: defaultTextButtonStyle.copyWith(fontSize: 16.0, fontFamily: "Inter", color: appState.appError == "" ? whiteishPurple : hotPink))),
|
||||
Visibility(
|
||||
visible: appState.modalState == ModalState.storageMigration || appState.modalState == ModalState.shutdown,
|
||||
child: LinearProgressIndicator(
|
||||
|
|
|
@ -31,6 +31,7 @@ class _TorStatusView extends State<TorStatusView> {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: Provider.of<Settings>(context).theme.backgroundMainColor,
|
||||
appBar: AppBar(
|
||||
title: Text(AppLocalizations.of(context)!.torNetworkStatus),
|
||||
),
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue