Compare commits
No commits in common. "trunk" and "stable-blockers" have entirely different histories.
trunk
...
stable-blo
75
.drone.yml
|
@ -8,7 +8,7 @@ clone:
|
|||
|
||||
steps:
|
||||
- name: clone
|
||||
image: openpriv/flutter-desktop:linux-fstable-3.19.3
|
||||
image: openpriv/flutter-desktop:linux-fstable-3.13.4
|
||||
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.19.3
|
||||
image: openpriv/flutter-desktop:linux-fstable-3.13.4
|
||||
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.19.3
|
||||
image: openpriv/flutter-desktop:linux-fstable-3.13.4
|
||||
volumes:
|
||||
- name: deps
|
||||
path: /root/.pub-cache
|
||||
|
@ -55,29 +55,14 @@ 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.19.3
|
||||
image: openpriv/flutter-desktop:linux-fstable-3.13.4
|
||||
volumes:
|
||||
- name: deps
|
||||
path: /root/.pub-cache
|
||||
|
@ -86,7 +71,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.19.3
|
||||
image: openpriv/flutter-desktop:linux-fstable-3.13.4
|
||||
when:
|
||||
event: pull_request
|
||||
volumes:
|
||||
|
@ -96,7 +81,7 @@ steps:
|
|||
- flutter build apk --debug
|
||||
|
||||
- name: build-android
|
||||
image: openpriv/flutter-desktop:linux-fstable-3.19.3
|
||||
image: openpriv/flutter-desktop:linux-fstable-3.13.4
|
||||
when:
|
||||
event: push
|
||||
environment:
|
||||
|
@ -120,7 +105,7 @@ steps:
|
|||
#- cp build/app/outputs/flutter-apk/app-debug.apk deploy/android
|
||||
|
||||
- name: widget-tests
|
||||
image: openpriv/flutter-desktop:linux-fstable-3.19.3
|
||||
image: openpriv/flutter-desktop:linux-fstable-3.13.4
|
||||
volumes:
|
||||
- name: deps
|
||||
path: /root/.pub-cache
|
||||
|
@ -129,21 +114,6 @@ 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
|
||||
|
@ -208,7 +178,7 @@ clone:
|
|||
|
||||
steps:
|
||||
- name: clone
|
||||
image: openpriv/flutter-desktop:windows-sdk30-fstable-3.19.3
|
||||
image: openpriv/flutter-desktop:windows-sdk30-fstable-3.13.4
|
||||
environment:
|
||||
buildbot_key_b64:
|
||||
from_secret: buildbot_key_b64
|
||||
|
@ -226,7 +196,7 @@ steps:
|
|||
- git checkout $Env:DRONE_COMMIT
|
||||
|
||||
- name: fetch
|
||||
image: openpriv/flutter-desktop:windows-sdk30-fstable-3.19.3
|
||||
image: openpriv/flutter-desktop:windows-sdk30-fstable-3.10.2
|
||||
commands:
|
||||
- git describe --tags --abbrev=1 > VERSION
|
||||
- git log -1 --format=%cd --date=format:'%Y-%m-%d-%H-%M' > COMMIT_DATE
|
||||
|
@ -234,12 +204,12 @@ steps:
|
|||
- .\fetch-libcwtch-go.ps1
|
||||
|
||||
- name: build-windows
|
||||
image: openpriv/flutter-desktop:windows-sdk30-fstable-3.19.3
|
||||
image: openpriv/flutter-desktop:windows-sdk30-fstable-3.13.4
|
||||
commands:
|
||||
- flutter pub get
|
||||
- $Env:version += type .\VERSION
|
||||
- $Env:commitdate += type .\COMMIT_DATE
|
||||
- $Env:releasedir = "build\\windows\\x64\\runner\\Release\\"
|
||||
- $Env:releasedir = "build\\windows\\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
|
||||
|
@ -266,7 +236,7 @@ steps:
|
|||
commands:
|
||||
- $Env:version += type .\VERSION
|
||||
- $Env:commitdate += type .\COMMIT_DATE
|
||||
- $Env:releasedir = "build\\windows\\x64\\runner\\Release\\"
|
||||
- $Env:releasedir = "build\\windows\\runner\\Release\\"
|
||||
- $Env:zip = 'cwtch-' + $Env:version + '.zip'
|
||||
- $Env:zipsha = $Env:zip + '.sha512.txt'
|
||||
- $Env:buildname = 'flwtch-' + $Env:commitdate + '-' + $Env:version
|
||||
|
@ -291,7 +261,7 @@ steps:
|
|||
- move *.sha512.txt deploy\$Env:builddir
|
||||
|
||||
- name: deploy-windows
|
||||
image: openpriv/flutter-desktop:windows-sdk30-fstable-3.19.3
|
||||
image: openpriv/flutter-desktop:windows-sdk30-fstable-3.13.4
|
||||
when:
|
||||
event: push
|
||||
status: [ success ]
|
||||
|
@ -330,8 +300,7 @@ steps:
|
|||
commands:
|
||||
- mkdir ~/.ssh
|
||||
- echo $buildbot_key_b64 > ~/.ssh/id_rsa.b64
|
||||
- ls -lh ~/.ssh/id_rsa.b64
|
||||
- base64 -d -i ~/.ssh/id_rsa.b64 -o ~/.ssh/id_rsa
|
||||
- base64 -d ~/.ssh/id_rsa.b64 > ~/.ssh/id_rsa
|
||||
- chmod 400 ~/.ssh/id_rsa
|
||||
# force by pass of ssh host key check, less secure
|
||||
- ssh-keyscan -H git.openprivacy.ca >> ~/.ssh/known_hosts
|
||||
|
@ -350,22 +319,20 @@ steps:
|
|||
- ./fetch-tor-macos.sh
|
||||
- echo `git describe --tags --abbrev=1` > VERSION
|
||||
- echo `git log -1 --format=%cd --date=format:%G-%m-%d-%H-%M` > COMMIT_DATE
|
||||
- export PATH=$PATH:/Users/drone/development/flutter/bin
|
||||
- export PATH=$PATH:/Users/Dan/development/flutter/bin
|
||||
- flutter pub get
|
||||
- mkdir deploy
|
||||
- ./fetch-libcwtch-go-macos.sh
|
||||
# Drone builds in container directories and gem seems to have some weird side effects so have to manually re install these locally
|
||||
- gem install --user-install ffi -v 1.15.5 -- --enable-libffi-alloc
|
||||
# currently unneeded to reinstall but was, and may be again? so saving
|
||||
#- gem install --user-install cocoapods -v 1.11.3
|
||||
- gem install --user-install cocoapods
|
||||
|
||||
- name: build-macos
|
||||
commands:
|
||||
- export PATH=$PATH:/Users/drone/bin/flutter/bin
|
||||
- export PATH=$PATH:/Users/Dan/development/flutter/bin
|
||||
- export GEM_HOME=$HOME/.gem
|
||||
- export PATH=$GEM_HOME/ruby/2.6.0/bin:$PATH
|
||||
- flutter doctor
|
||||
- flutter config --enable-macos-desktop
|
||||
- flutter build macos --dart-define BUILD_VER=`cat VERSION` --dart-define BUILD_DATE=`cat COMMIT_DATE`
|
||||
- export PATH=$PATH:/opt/homebrew/bin/ #create-dmg
|
||||
- export PATH=$PATH:/usr/local/bin #create-dmg
|
||||
- macos/package-release.sh
|
||||
- mkdir -p deploy
|
||||
- mv Cwtch.dmg deploy/Cwtch-`cat VERSION`.dmg
|
||||
|
@ -379,7 +346,7 @@ steps:
|
|||
status: [ success ]
|
||||
commands:
|
||||
- echo $BUILDFILES_KEY > ~/id_rsab64
|
||||
- base64 -d -i ~/id_rsab64 -o ~/id_rsa
|
||||
- base64 -d ~/id_rsab64 > ~/id_rsa
|
||||
- chmod 400 ~/id_rsa
|
||||
- export DIR=flwtch-`cat COMMIT_DATE`-`cat VERSION`
|
||||
- mv deploy $DIR
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
*.log
|
||||
*.pyc
|
||||
*.swp
|
||||
.DS_Store
|
||||
.atom/
|
||||
.buildlog/
|
||||
.history
|
||||
|
@ -35,7 +36,6 @@ test_home
|
|||
.pub-cache/
|
||||
.pub/
|
||||
/build/
|
||||
./lib/gen/
|
||||
|
||||
# Web related
|
||||
lib/generated_plugin_registrant.dart
|
||||
|
@ -59,7 +59,7 @@ package.
|
|||
# Compiled Libs
|
||||
linux/tor
|
||||
linux/libCwtch.so
|
||||
android/app/cwtch/cwtch.aar
|
||||
android/cwtch/cwtch.aar
|
||||
android/app/src/main/jniLibs/*/libtor.so
|
||||
*.dylib
|
||||
integration_test/gherkin_suite_test.g.dart
|
||||
|
|
|
@ -1 +1 @@
|
|||
2024-02-26-18-01-v0.0.14
|
||||
2023-09-26-13-15-v0.0.10
|
2
LICENSE
|
@ -1,5 +1,5 @@
|
|||
MIT License
|
||||
Copyright (c) 2021-2024 Open Privacy Research Society
|
||||
Copyright (c) 2021 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:
|
||||
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
# 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,9 +1,3 @@
|
|||
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()) {
|
||||
|
@ -12,6 +6,11 @@ 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'
|
||||
|
@ -22,6 +21,10 @@ 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')
|
||||
|
@ -30,7 +33,7 @@ if (keystorePropertiesFile.exists()) {
|
|||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion 34
|
||||
compileSdkVersion 33
|
||||
|
||||
sourceSets {
|
||||
main.java.srcDirs += 'src/main/kotlin'
|
||||
|
@ -51,7 +54,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 34
|
||||
targetSdkVersion 33
|
||||
versionCode flutterVersionCode.toInteger()
|
||||
versionName flutterVersionName
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
|
@ -90,11 +93,11 @@ flutter {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
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.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||
implementation project(':cwtch')
|
||||
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" xmlns:tools="http://schemas.android.com/tools"
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
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/LaunchTheme"
|
||||
android:theme="@style/NormalTheme"
|
||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
|
||||
android:hardwareAccelerated="true"
|
||||
android:windowSoftInputMode="adjustResize"
|
||||
|
@ -38,30 +38,22 @@
|
|||
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 for running in the background -->
|
||||
<!--Needed to run in background (lol)-->
|
||||
<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,7 +11,6 @@ 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
|
||||
|
@ -23,13 +22,6 @@ 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) {
|
||||
|
@ -145,19 +137,7 @@ 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")
|
||||
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 fh = applicationContext.assets.open(key)
|
||||
|
||||
val clickIntent = Intent(applicationContext, MainActivity::class.java).also { intent ->
|
||||
intent.action = Intent.ACTION_RUN
|
||||
|
@ -165,21 +145,18 @@ 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(image)
|
||||
.setLargeIcon(BitmapFactory.decodeStream(fh))
|
||||
.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()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -315,7 +292,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, ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC)
|
||||
return ForegroundInfo(101, notification)
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.O)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package im.cwtch.flwtch
|
||||
|
||||
import SplashView
|
||||
import android.annotation.TargetApi
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
|
@ -18,6 +19,7 @@ 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
|
||||
|
@ -30,6 +32,8 @@ 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"
|
||||
|
@ -327,9 +331,8 @@ class MainActivity: FlutterActivity() {
|
|||
val conversation: Int = call.argument("conversation") ?: 0
|
||||
val indexI: Int = call.argument("index") ?: 0
|
||||
val count: Int = call.argument("count") ?: 1
|
||||
val ucount : Int = maxOf(1, count) // don't allow negative counts
|
||||
|
||||
result.success(Cwtch.getMessages(profile, conversation.toLong(), indexI.toLong(), ucount.toLong()))
|
||||
result.success(Cwtch.getMessages(profile, conversation.toLong(), indexI.toLong(), count.toLong()))
|
||||
return
|
||||
}
|
||||
"SendMessage" -> {
|
||||
|
@ -573,6 +576,9 @@ class MainActivity: FlutterActivity() {
|
|||
result.success(Cwtch.searchConversations(profile, pattern))
|
||||
return
|
||||
}
|
||||
"ReconnectCwtchForeground" -> {
|
||||
Cwtch.reconnectCwtchForeground()
|
||||
}
|
||||
"Shutdown" -> {
|
||||
Cwtch.shutdownCwtch();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
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="@color/darkGreyPurple" />
|
||||
<item android:drawable="?android:colorBackground" />
|
||||
|
||||
<!-- You can insert your own image assets here -->
|
||||
<item>
|
||||
<!-- <item>
|
||||
<bitmap
|
||||
android:gravity="center"
|
||||
android:src="@mipmap/knott" />
|
||||
</item>
|
||||
android:src="@mipmap/launch_image" />
|
||||
</item> -->
|
||||
</layer-list>
|
||||
|
|
|
@ -1,81 +0,0 @@
|
|||
<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,10 +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="@color/darkGreyPurple" />
|
||||
<item android:drawable="@android:color/white" />
|
||||
|
||||
<!-- You can insert your own image assets here -->
|
||||
<item android:drawable="@drawable/knott"
|
||||
android:gravity="center"
|
||||
/>
|
||||
<!-- <item>
|
||||
<bitmap
|
||||
android:gravity="center"
|
||||
android:src="@mipmap/launch_image" />
|
||||
</item> -->
|
||||
</layer-list>
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
<?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>
|
|
@ -1,5 +0,0 @@
|
|||
<?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>
|
After Width: | Height: | Size: 544 B |
After Width: | Height: | Size: 442 B |
After Width: | Height: | Size: 721 B |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 1.4 KiB |
|
@ -1,23 +1,18 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
|
||||
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
|
||||
<!-- 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">
|
||||
<!-- Show a splash screen on the activity. Automatically removed when
|
||||
the Flutter engine draws its first frame -->
|
||||
Flutter 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.Light.NoTitleBar">
|
||||
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
|
||||
<item name="android:windowBackground">?android:colorBackground</item>
|
||||
</style>
|
||||
</resources>
|
||||
</resources>
|
|
@ -1,14 +0,0 @@
|
|||
<?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>
|
|
@ -1,5 +0,0 @@
|
|||
<resources>
|
||||
<color name="darkGreyPurple">#281831</color>
|
||||
<color name="testGreen">#00ff00</color>
|
||||
<color name="ic_launcher_background">@color/darkGreyPurple</color>
|
||||
</resources>
|
|
@ -1,3 +1,18 @@
|
|||
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()
|
||||
|
@ -13,6 +28,7 @@ subprojects {
|
|||
project.evaluationDependsOn(':app')
|
||||
}
|
||||
|
||||
tasks.register("clean", Delete) {
|
||||
delete rootProject.buildDir
|
||||
}
|
||||
//removed due to gradle namespace conflicts that are beyond erinn's mere mortal understanding
|
||||
//task clean(type: Delete) {
|
||||
// delete rootProject.buildDir
|
||||
//}
|
||||
|
|
|
@ -1,25 +1,11 @@
|
|||
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
|
||||
}()
|
||||
include ':app', ':cwtch'
|
||||
|
||||
includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
|
||||
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
|
||||
def properties = new Properties()
|
||||
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
gradlePluginPortal()
|
||||
}
|
||||
}
|
||||
assert localPropertiesFile.exists()
|
||||
localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
|
||||
|
||||
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"
|
||||
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"
|
||||
|
|
Before Width: | Height: | Size: 19 KiB |
|
@ -1,107 +0,0 @@
|
|||
---
|
||||
colors:
|
||||
darkGreyPurple: 0x281831
|
||||
deepPurple: 0x422850
|
||||
mauvePurple: 0x8E64A5
|
||||
whiteishPurple: 0xE3DFE4
|
||||
lightGrey: 0x9E9E9E
|
||||
softGreen: 0xA0FFB0
|
||||
softRed: 0xFFA0B0
|
||||
whitePurple: 0xFFFDFF
|
||||
softPurple: 0xFDF3FC
|
||||
purple: 0xDFB9DE
|
||||
brightPurple: 0xD1B0E0 # not in new: portrait badge color
|
||||
darkPurple: 0x350052
|
||||
greyPurple: 0x775F84 # not in new: portrait borders
|
||||
pink: 0xE85DA1 # not in new: active button color
|
||||
hotPink: 0xD20070 # #D01972)
|
||||
softGrey: 0xB3B6B3 # not in new theme: blocked
|
||||
themes:
|
||||
name: cwtch
|
||||
dark:
|
||||
colors:
|
||||
background: darkGreyPurple
|
||||
header: darkGreyPurple
|
||||
userBubble: mauvePurple
|
||||
peerBubble: deepPurple
|
||||
font: whiteishPurple
|
||||
settings: whiteishPurple
|
||||
accent: hotPink
|
||||
theme:
|
||||
backgroundHilightElementColor: deepPurple
|
||||
backgroundMainColor: background # darkGreyPurple
|
||||
backgroundPaneColor: header # darkGreyPurple
|
||||
defaultButtonColor: accent # hotPink
|
||||
defaultButtonDisabledColor: lightGrey
|
||||
defaultButtonDisabledTextColor: darkGreyPurple
|
||||
defaultButtonTextColor: whiteishPurple
|
||||
dropShadowColor: mauvePurple
|
||||
hilightElementColor: purple
|
||||
mainTextColor: font # whiteishPurple
|
||||
messageFromMeBackgroundColor: userBubble # mauvePurple
|
||||
messageFromMeTextColor: font # whiteishPurple
|
||||
messageFromOtherBackgroundColor: peerBubble # deepPurple
|
||||
messageFromOtherTextColor: font # whiteishPurple
|
||||
portraitBackgroundColor: deepPurple
|
||||
portraitBlockedBorderColor: lightGrey
|
||||
portraitBlockedTextColor: lightGrey
|
||||
portraitContactBadgeColor: hotPink
|
||||
portraitContactBadgeTextColor: whiteishPurple
|
||||
portraitOfflineBorderColor: purple
|
||||
portraitOnlineBorderColor: whiteishPurple
|
||||
portraitProfileBadgeColor: hotPink
|
||||
portraitProfileBadgeTextColor: whiteishPurple
|
||||
scrollbarDefaultColor: purple
|
||||
sendHintTextColor: mauvePurple
|
||||
chatReactionIconColor: mauvePurple
|
||||
textfieldBackgroundColor: deepPurple
|
||||
textfieldBorderColor: deepPurple
|
||||
textfieldErrorColor: hotPink
|
||||
textfieldHintColor: mainTextColor
|
||||
toolbarIconColor: settings # whiteishPurple
|
||||
topbarColor: header # darkGreyPurple
|
||||
chatImage: Cwtch.png
|
||||
chatImageColor: peerBubble
|
||||
light:
|
||||
colors:
|
||||
background: whitePurple
|
||||
header: softPurple
|
||||
userBubble: purple
|
||||
peerBubble: softPurple
|
||||
font: 0x281831
|
||||
settings: 0x281831
|
||||
accent: hotPink
|
||||
theme:
|
||||
backgroundHilightElementColor: softPurple
|
||||
backgroundMainColor: background # whitePurple
|
||||
backgroundPaneColor: background # whitePurple
|
||||
defaultButtonColor: accent # hotPink
|
||||
defaultButtonDisabledColor: softGrey
|
||||
defaultButtonTextColor: whitePurple # ?
|
||||
dropShadowColor: purple
|
||||
hilightElementColor: purple
|
||||
mainTextColor: settings
|
||||
messageFromMeBackgroundColor: userBubble # brightPurple
|
||||
messageFromMeTextColor: font # mainTextColor
|
||||
messageFromOtherBackgroundColor: peerBubble # purple
|
||||
messageFromOtherTextColor: font # darkPurple
|
||||
portraitBackgroundColor: softPurple
|
||||
portraitBlockedBorderColor: softGrey
|
||||
portraitBlockedTextColor: softGrey
|
||||
portraitContactBadgeColor: accent
|
||||
portraitContactBadgeTextColor: whitePurple
|
||||
portraitOfflineBorderColor: greyPurple
|
||||
portraitOnlineBorderColor: font
|
||||
portraitProfileBadgeColor: accent
|
||||
portraitProfileBadgeTextColor: whitePurple
|
||||
scrollbarDefaultColor: accent
|
||||
sendHintTextColor: purple
|
||||
chatReactionIconColor: purple
|
||||
textfieldBackgroundColor: purple
|
||||
textfieldBorderColor: purple
|
||||
textfieldErrorColor: hotPink
|
||||
textfieldHintColor: font
|
||||
toolbarIconColor: background # darkPurple
|
||||
topbarColor: header # softPurple
|
||||
chatImage: Cwtch.png
|
||||
chatImageColor: 0xf1dff0
|
Before Width: | Height: | Size: 20 KiB |
|
@ -1,86 +0,0 @@
|
|||
---
|
||||
colors:
|
||||
darkDarkBlue: 0x0E1628
|
||||
darkLightBlue: 0x19243E
|
||||
white: 0xE6E9F4
|
||||
darkBlue: 0x131B2E
|
||||
lighterDarkBlue: 0x19243E
|
||||
lightBlue: 0xC0C8E5
|
||||
|
||||
themes:
|
||||
name: ghost
|
||||
dark:
|
||||
colors:
|
||||
background: 0x131B2E
|
||||
header: 0x0E1628
|
||||
userBubble: 0x25355A
|
||||
peerBubble: 0x19243E
|
||||
font: 0xE6E9F4
|
||||
settings: 0xE6E9F4
|
||||
accent: 0xD20070
|
||||
reaction: 0x96A5D4
|
||||
theme:
|
||||
backgroundHilightElementColor: darkDarkBlue
|
||||
backgroundMainColor: background
|
||||
backgroundPaneColor: header
|
||||
defaultButtonColor: accent
|
||||
dropShadowColor: darkBlue
|
||||
mainTextColor: font
|
||||
messageFromMeBackgroundColor: userBubble
|
||||
messageFromMeTextColor: font
|
||||
messageFromOtherBackgroundColor: peerBubble
|
||||
messageFromOtherTextColor: font
|
||||
portraitOfflineBorderColor: 0x96A5D4
|
||||
portraitOnlineBorderColor: font
|
||||
portraitBackgroundColor: background
|
||||
scrollbarDefaultColor: darkLightBlue
|
||||
sendHintTextColor: userBubble
|
||||
textfieldBackgroundColor: peerBubble
|
||||
textfieldBorderColor: userBubble
|
||||
textfieldHintColor: font
|
||||
toolbarIconColor: settings
|
||||
topbarColor: header
|
||||
chatReactionIconColor: reaction
|
||||
chatImage: Ghost.png
|
||||
chatImageColor: userBubble
|
||||
snackbarBackgroundColor: accent
|
||||
snackbarTextColor: 0xE6E9F4
|
||||
light:
|
||||
colors:
|
||||
background: 0xE6E9F4
|
||||
header: 0x96A5D4
|
||||
userBubble: 0x96A5D4
|
||||
peerBubble: 0xC0C8E5
|
||||
font: 0x131B2E
|
||||
settings: 0x131B2E
|
||||
accent: 0xD20070
|
||||
reaction: 0x96A5D4
|
||||
theme:
|
||||
backgroundHilightElementColor: peerBubble
|
||||
backgroundMainColor: background
|
||||
backgroundPaneColor: background
|
||||
defaultButtonColor: accent
|
||||
defaultButtonActiveColor: lighterDarkBlue
|
||||
defaultButtonDisabledColor: userBubble
|
||||
dropShadowColor: darkBlue
|
||||
mainTextColor: settings
|
||||
messageFromMeBackgroundColor: userBubble
|
||||
messageFromMeTextColor: font
|
||||
messageFromOtherBackgroundColor: peerBubble
|
||||
messageFromOtherTextColor: font
|
||||
portraitContactBadgeColor: accent
|
||||
portraitOfflineBorderColor: header
|
||||
portraitOnlineBorderColor: font
|
||||
portraitBackgroundColor: background
|
||||
scrollbarDefaultColor: accent
|
||||
sendHintTextColor: peerBubble
|
||||
textfieldBackgroundColor: peerBubble
|
||||
textfieldBorderColor: userBubble
|
||||
textfieldHintColor: font
|
||||
toolbarIconColor: 0xffffff
|
||||
topbarColor: header
|
||||
chatReactionIconColor: reaction
|
||||
chatImage: Ghost.png
|
||||
chatImageColor: peerBubble
|
||||
snackbarBackgroundColor: accent
|
||||
snackbarTextColor: background
|
Before Width: | Height: | Size: 19 KiB |
|
@ -1,53 +0,0 @@
|
|||
---
|
||||
|
||||
themes:
|
||||
name: juniper
|
||||
dark:
|
||||
colors:
|
||||
background: 0x1B1B1B
|
||||
backgroundAlt: 0x494949
|
||||
header: 0x1B1B1B
|
||||
userBubble: 0x373737
|
||||
peerBubble: 0x494949
|
||||
font: 0xFFFFFF
|
||||
settings: 0xFFFDFF
|
||||
accent: 0x9E6A56
|
||||
accentAlt: 0x9E6A56
|
||||
theme:
|
||||
backgroundMainColor: background
|
||||
backgroundPaneColor: header
|
||||
topbarColor: header
|
||||
mainTextColor: font
|
||||
defaultButtonColor: accent
|
||||
textfieldHintColor: mainTextColor
|
||||
toolbarIconColor: settings
|
||||
messageFromMeBackgroundColor: userBubble
|
||||
messageFromMeTextColor: font
|
||||
messageFromOtherBackgroundColor: peerBubble
|
||||
messageFromOtherTextColor: font
|
||||
textfieldBackgroundColor: peerBubble
|
||||
textfieldBorderColor: userBubble
|
||||
backgroundHilightElementColor: accent
|
||||
sendHintTextColor: accentAlt
|
||||
hilightElementColor: accentAlt
|
||||
defaultButtonTextColor: mainTextColor
|
||||
defaultButtonDisabledColor: peerBubble
|
||||
defaultButtonDisabledTextColor: peerBubble
|
||||
textfieldErrorColor: accent
|
||||
scrollbarDefaultColor: accent
|
||||
portraitBackgroundColor: header
|
||||
portraitOnlineBorderColor: font
|
||||
portraitOfflineBorderColor: peerBubble
|
||||
portraitBlockedBorderColor: peerBubble
|
||||
portraitBlockedTextColor: peerBubble
|
||||
portraitContactBadgeColor: accent
|
||||
portraitContactBadgeTextColor: mainTextColor
|
||||
portraitProfileBadgeColor: accent
|
||||
portraitProfileBadgeTextColor: mainTextColor
|
||||
dropShadowColor: accentAlt
|
||||
chatReactionIconColor: accentAlt
|
||||
chatImage: JuniperDark.png
|
||||
chatImageColor: userBubble
|
||||
messageSelectionColor: accent
|
||||
textfieldSelectionColor: accent
|
||||
menuBackgroundColor: accent
|
Before Width: | Height: | Size: 22 KiB |
|
@ -1,91 +0,0 @@
|
|||
---
|
||||
colors:
|
||||
lavender: 0xB194C1
|
||||
|
||||
themes:
|
||||
name: mermaid
|
||||
dark:
|
||||
colors:
|
||||
background: 0x15282A
|
||||
header: 0x15282A
|
||||
userBubble: 0x1d5754
|
||||
peerBubble: 0x253D3F
|
||||
font: 0xEDFAFC
|
||||
settings: 0xEDFAFC
|
||||
accent: 0x8E64A5
|
||||
reaction: 0x8E64A5
|
||||
theme:
|
||||
backgroundHilightElementColor: peerBubble
|
||||
backgroundMainColor: background # darkGreyPurple
|
||||
backgroundPaneColor: header # darkGreyPurple
|
||||
defaultButtonColor: accent # hotPink
|
||||
dropShadowColor: lavender
|
||||
mainTextColor: font # whiteishPurple
|
||||
messageFromMeBackgroundColor: userBubble # mauvePurple
|
||||
messageFromMeTextColor: font # whiteishPurple
|
||||
messageFromOtherBackgroundColor: peerBubble # deepPurple
|
||||
messageFromOtherTextColor: font # whiteishPurple
|
||||
portraitOfflineBorderColor: userBubble
|
||||
portraitOnlineBorderColor: font
|
||||
portraitContactBadgeColor: accent
|
||||
portraitContactBadgeTextColor: 0xffffff
|
||||
portraitProfileBadgeColor: accent
|
||||
portraitProfileBadgeTextColor: 0xffffff
|
||||
portraitBackgroundColor: background
|
||||
textfieldBackgroundColor: peerBubble
|
||||
textfieldBorderColor: userBubble
|
||||
textfieldHintColor: mainTextColor
|
||||
toolbarIconColor: settings # whiteishPurple
|
||||
topbarColor: header # darkGreyPurple
|
||||
sendHintTextColor: userBubble
|
||||
chatReactionIconColor: reaction
|
||||
chatImage: Mermaid.png
|
||||
chatImageColor: peerBubble
|
||||
snackbarBackgroundColor: accent
|
||||
snackbarTextColor: 0xEDFAFC
|
||||
messageSelectionColor: accent
|
||||
textfieldSelectionColor: accent
|
||||
menuBackgroundColor: accent
|
||||
light:
|
||||
colors:
|
||||
background: 0xEDFAFC
|
||||
header: 0x71C1BF
|
||||
userBubble: 0x71C1BF
|
||||
peerBubble: 0xD2EFF3
|
||||
font: 0x15282A
|
||||
settings: 0x15282A
|
||||
accent: 0x8E64A5
|
||||
reaction: 0x71C1BF
|
||||
theme:
|
||||
backgroundHilightElementColor: peerBubble
|
||||
backgroundMainColor: background # whitePurple
|
||||
backgroundPaneColor: background # whitePurple
|
||||
defaultButtonColor: accent # hotPink
|
||||
dropShadowColor: peerBubble
|
||||
mainTextColor: settings
|
||||
messageFromMeBackgroundColor: userBubble # brightPurple
|
||||
messageFromMeTextColor: font # mainTextColor
|
||||
messageFromOtherBackgroundColor: peerBubble # purple
|
||||
messageFromOtherTextColor: font # darkPurple
|
||||
portraitContactBadgeColor: accent
|
||||
portraitContactBadgeTextColor: 0xffffff
|
||||
portraitProfileBadgeColor: accent
|
||||
portraitProfileBadgeTextColor: 0xffffff
|
||||
portraitOfflineBorderColor: userBubble
|
||||
portraitOnlineBorderColor: font
|
||||
portraitBackgroundColor: background
|
||||
scrollbarDefaultColor: accent
|
||||
textfieldBackgroundColor: peerBubble
|
||||
textfieldBorderColor: userBubble
|
||||
textfieldHintColor: font
|
||||
toolbarIconColor: 0xffffff
|
||||
topbarColor: header # softPurple
|
||||
sendHintTextColor: userBubble
|
||||
chatReactionIconColor: reaction
|
||||
chatImage: Mermaid.png
|
||||
chatImageColor: peerBubble
|
||||
snackbarBackgroundColor: accent
|
||||
snackbarTextColor: background
|
||||
messageSelectionColor: 0xb1e3ea
|
||||
textfieldSelectionColor: 0xb1e3ea
|
||||
menuBackgroundColor: 0xb1e3ea
|
Before Width: | Height: | Size: 26 KiB |
|
@ -1,77 +0,0 @@
|
|||
---
|
||||
|
||||
themes:
|
||||
name: midnight
|
||||
dark:
|
||||
colors:
|
||||
accentGray: 0xE0E0E0
|
||||
background: 0x111111
|
||||
backgroundAlt: 0x494949
|
||||
header: 0x111111
|
||||
userBubble: 0x2D2D2D
|
||||
peerBubble: 0x1B1B1B
|
||||
font: 0xF0F1F1
|
||||
settings: 0xF0F1F1
|
||||
accent: 0xD20070
|
||||
reaction: 0xD20070
|
||||
theme:
|
||||
backgroundHilightElementColor: backgroundAlt
|
||||
backgroundMainColor: background # darkGreyPurple
|
||||
backgroundPaneColor: header # darkGreyPurple
|
||||
defaultButtonColor: accent # hotPink
|
||||
dropShadowColor: accentGray
|
||||
mainTextColor: font # whiteishPurple
|
||||
messageFromMeBackgroundColor: userBubble # mauvePurple
|
||||
messageFromMeTextColor: font # whiteishPurple
|
||||
messageFromOtherBackgroundColor: peerBubble # deepPurple
|
||||
messageFromOtherTextColor: font # whiteishPurple
|
||||
scrollbarDefaultColor: accentGray
|
||||
textfieldBackgroundColor: peerBubble
|
||||
textfieldBorderColor: userBubble
|
||||
textfieldHintColor: mainTextColor
|
||||
portraitOfflineBorderColor: 0x676767
|
||||
portraitOnlineBorderColor: font
|
||||
portraitBackgroundColor: background
|
||||
toolbarIconColor: settings # whiteishPurple
|
||||
topbarColor: header # darkGreyPurple
|
||||
sendHintTextColor: userBubble
|
||||
chatReactionIconColor: reaction
|
||||
chatImage: Midnight.png
|
||||
chatImageColor: userBubble
|
||||
snackbarBackgroundColor: accent
|
||||
snackbarTextColor: 0xF0F1F1
|
||||
light:
|
||||
colors:
|
||||
background: 0xF0F1F1 # Color( 0xFFFDFF)
|
||||
header: 0xE0E0E0
|
||||
userBubble: 0xBABDBE
|
||||
peerBubble: 0xE0E0E0
|
||||
font: 0x111111
|
||||
settings: 0x111111
|
||||
accent: 0xD20070
|
||||
reaction: 0xD20070
|
||||
theme:
|
||||
backgroundHilightElementColor: peerBubble
|
||||
backgroundMainColor: background # whitePurple
|
||||
backgroundPaneColor: background # whitePurple
|
||||
defaultButtonColor: accent # hotPink
|
||||
mainTextColor: settings
|
||||
messageFromMeBackgroundColor: userBubble # brightPurple
|
||||
messageFromMeTextColor: font # mainTextColor
|
||||
messageFromOtherBackgroundColor: peerBubble # purple
|
||||
messageFromOtherTextColor: font # darkPurple
|
||||
portraitContactBadgeColor: accent
|
||||
portraitOfflineBorderColor: userBubble
|
||||
portraitOnlineBorderColor: font
|
||||
portraitBackgroundColor: background
|
||||
scrollbarDefaultColor: accent
|
||||
textfieldBackgroundColor: userBubble
|
||||
textfieldHintColor: font
|
||||
toolbarIconColor: 0xffffff
|
||||
topbarColor: header # softPurple
|
||||
sendHintTextColor: userBubble
|
||||
chatReactionIconColor: reaction
|
||||
chatImage: Midnight.png
|
||||
chatImageColor: peerBubble
|
||||
snackbarBackgroundColor: accent
|
||||
snackbarTextColor: background
|
Before Width: | Height: | Size: 17 KiB |
|
@ -1,86 +0,0 @@
|
|||
---
|
||||
|
||||
themes:
|
||||
name: neon1
|
||||
dark:
|
||||
colors:
|
||||
background: 0x281831
|
||||
header: 0x281831
|
||||
userBubble: 0x7F00C5
|
||||
peerBubble: 0x422850
|
||||
font: 0xFBF3FF
|
||||
settings: 0x281831
|
||||
accent: 0x56DCD8
|
||||
reaction: 0xD891FF
|
||||
theme:
|
||||
backgroundMainColor: background # darkGreyPurple
|
||||
backgroundPaneColor: header # darkGreyPurple
|
||||
defaultButtonColor: accent # hotPink
|
||||
mainTextColor: 0xFBF3FF # whiteishPurple
|
||||
messageFromMeBackgroundColor: userBubble # mauvePurple
|
||||
messageFromMeTextColor: font # whiteishPurple
|
||||
messageFromOtherBackgroundColor: peerBubble # deepPurple
|
||||
messageFromOtherTextColor: font # whiteishPurple
|
||||
portraitContactBadgeColor: accent
|
||||
portraitContactBadgeTextColor: background
|
||||
portraitProfileBadgeColor: accent
|
||||
portraitProfileBadgeTextColor: background
|
||||
portraitBackgroundColor: background
|
||||
portraitOfflineBorderColor: 0x775F84
|
||||
portraitOnlineBorderColor: font
|
||||
scrollbarDefaultColor: accent
|
||||
textfieldHintColor: mainTextColor
|
||||
toolbarIconColor: settings # whiteishPurple
|
||||
topbarColor: header # darkGreyPurple
|
||||
sendHintTextColor: userBubble
|
||||
chatReactionIconColor: reaction
|
||||
defaultButtonTextColor: 0x281831
|
||||
chatImage: Neon1.png
|
||||
chatImageColor: 0x4f3060
|
||||
snackbarBackgroundColor: accent
|
||||
snackbarTextColor: background
|
||||
messageSelectionColor: 0x775F84
|
||||
textfieldSelectionColor: 0x775F84
|
||||
menuBackgroundColor: 0x775F84
|
||||
light:
|
||||
colors:
|
||||
background: 0xFBF3FF
|
||||
header: 0x56DCD8
|
||||
userBubble: 0x56DCD8
|
||||
peerBubble: 0xF5E1FF
|
||||
font: 0x281831
|
||||
settings: 0x281831
|
||||
accent: 0xD891FF
|
||||
reaction: 0xD891FF
|
||||
theme:
|
||||
backgroundMainColor: background # whitePurple
|
||||
backgroundPaneColor: background # whitePurple
|
||||
defaultButtonColor: accent # hotPink
|
||||
dropShadowColor: userBubble
|
||||
mainTextColor: settings
|
||||
messageFromMeBackgroundColor: userBubble # brightPurple
|
||||
messageFromMeTextColor: font # mainTextColor
|
||||
messageFromOtherBackgroundColor: peerBubble # purple
|
||||
messageFromOtherTextColor: font # darkPurple
|
||||
portraitOfflineBorderColor: 0xeac1ff
|
||||
portraitOnlineBorderColor: font
|
||||
portraitContactBadgeColor: accent
|
||||
portraitContactBadgeTextColor: font
|
||||
portraitProfileBadgeColor: accent
|
||||
portraitProfileBadgeTextColor: font
|
||||
scrollbarDefaultColor: accent
|
||||
textfieldBackgroundColor: peerBubble
|
||||
textfieldBorderColor: userBubble
|
||||
textfieldHintColor: font
|
||||
toolbarIconColor: settings # darkPurple
|
||||
topbarColor: header # softPurple
|
||||
sendHintTextColor: 0xeac1ff
|
||||
chatReactionIconColor: reaction
|
||||
chatImage: Neon1.png
|
||||
chatImageColor: 0xeac1ff
|
||||
defaultButtonTextColor: font
|
||||
snackbarBackgroundColor: accent
|
||||
snackbarTextColor: font
|
||||
messageSelectionColor: accent
|
||||
textfieldSelectionColor: accent
|
||||
menuBackgroundColor: accent
|
Before Width: | Height: | Size: 17 KiB |
|
@ -1,83 +0,0 @@
|
|||
---
|
||||
|
||||
themes:
|
||||
name: neon2
|
||||
dark:
|
||||
colors:
|
||||
background: 0x281831
|
||||
header: 0x281831
|
||||
userBubble: 0x7F00C5
|
||||
peerBubble: 0x422850
|
||||
font: 0xFBF3FF
|
||||
settings: 0x281831
|
||||
accent: 0x90EE02
|
||||
reaction: 0xD891FF
|
||||
theme:
|
||||
backgroundMainColor: background # darkGreyPurple
|
||||
backgroundPaneColor: header # darkGreyPurple
|
||||
defaultButtonColor: accent # hotPink
|
||||
mainTextColor: font # whiteishPurple
|
||||
messageFromMeBackgroundColor: userBubble # mauvePurple
|
||||
messageFromMeTextColor: font # whiteishPurple
|
||||
messageFromOtherBackgroundColor: peerBubble # deepPurple
|
||||
messageFromOtherTextColor: font # whiteishPurple
|
||||
portraitContactBadgeColor: accent
|
||||
portraitContactBadgeTextColor: 0x281831
|
||||
portraitProfileBadgeColor: accent
|
||||
portraitProfileBadgeTextColor: 0x281831
|
||||
scrollbarDefaultColor: accent
|
||||
textfieldHintColor: mainTextColor
|
||||
toolbarIconColor: settings # whiteishPurple
|
||||
topbarColor: header # darkGreyPurple
|
||||
sendHintTextColor: userBubble
|
||||
chatReactionIconColor: reaction
|
||||
defaultButtonTextColor: background
|
||||
chatImage: Neon2.png
|
||||
chatImageColor: 0x573569
|
||||
snackbarBackgroundColor: accent
|
||||
snackbarTextColor: background
|
||||
messageSelectionColor: 0x775F84
|
||||
textfieldSelectionColor: 0x775F84
|
||||
menuBackgroundColor: 0x775F84
|
||||
light:
|
||||
colors:
|
||||
paleGreen: 0xE7F6F6
|
||||
background: 0xFBFFF6
|
||||
header: 0x90EE02
|
||||
userBubble: 0x90EE02
|
||||
peerBubble: 0xF3FFE4
|
||||
font: 0x281831
|
||||
settings: 0x281831
|
||||
accent: 0x7F00C5
|
||||
reaction: 0x7F00C5
|
||||
theme:
|
||||
backgroundMainColor: background # whitePurple
|
||||
backgroundPaneColor: background # whitePurple
|
||||
defaultButtonColor: accent # hotPink
|
||||
dropShadowColor: userBubble
|
||||
mainTextColor: settings
|
||||
messageFromMeBackgroundColor: userBubble # brightPurple
|
||||
messageFromMeTextColor: font # mainTextColor
|
||||
messageFromOtherBackgroundColor: peerBubble # purple
|
||||
messageFromOtherTextColor: font # darkPurple
|
||||
portraitOfflineBorderColor: 0x775F84
|
||||
portraitOnlineBorderColor: font
|
||||
portraitContactBadgeColor: accent
|
||||
portraitContactBadgeTextColor: background
|
||||
portraitProfileBadgeColor: accent
|
||||
portraitProfileBadgeTextColor: background
|
||||
portraitBackgroundColor: background
|
||||
scrollbarDefaultColor: accent
|
||||
textfieldBackgroundColor: paleGreen
|
||||
textfieldBorderColor: peerBubble
|
||||
textfieldHintColor: font
|
||||
toolbarIconColor: background # darkPurple
|
||||
topbarColor: header # softPurple
|
||||
chatReactionIconColor: accent
|
||||
chatImage: Neon2.png
|
||||
chatImageColor: 0xd9ffa8
|
||||
snackbarBackgroundColor: accent
|
||||
snackbarTextColor: background
|
||||
messageSelectionColor: 0xd9ffa8
|
||||
textfieldSelectionColor: 0xd9ffa8
|
||||
menuBackgroundColor: 0xd9ffa8
|
Before Width: | Height: | Size: 19 KiB |
|
@ -1,84 +0,0 @@
|
|||
---
|
||||
|
||||
themes:
|
||||
name: pumpkin
|
||||
dark:
|
||||
colors:
|
||||
background: 0x281831
|
||||
header: 0x281831
|
||||
userBubble: 0x873C14
|
||||
peerBubble: 0x422850
|
||||
font: 0xFFFAF2
|
||||
settings: 0xFFFAF2
|
||||
accent: 0x873C14
|
||||
reaction: 0x873C14
|
||||
theme:
|
||||
backgroundMainColor: background # darkGreyPurple
|
||||
backgroundPaneColor: header # darkGreyPurple
|
||||
defaultButtonColor: accent # hotPink
|
||||
mainTextColor: font # whiteishPurple
|
||||
messageFromMeBackgroundColor: userBubble # mauvePurple
|
||||
messageFromMeTextColor: font # whiteishPurple
|
||||
messageFromOtherBackgroundColor: peerBubble # deepPurple
|
||||
messageFromOtherTextColor: font # whiteishPurple
|
||||
scrollbarDefaultColor: accent
|
||||
portraitContactBadgeColor: accent
|
||||
portraitContactBadgeTextColor: 0xFFFAF2
|
||||
portraitProfileBadgeColor: accent
|
||||
portraitProfileBadgeTextColor: 0xFFFAF2
|
||||
portraitOfflineBorderColor: 0x775F84
|
||||
portraitOnlineBorderColor: font
|
||||
textfieldHintColor: mainTextColor
|
||||
toolbarIconColor: settings # whiteishPurple
|
||||
topbarColor: header # darkGreyPurple
|
||||
sendHintTextColor: peerBubble
|
||||
chatReactionIconColor: reaction
|
||||
chatImage: Pumpkin.png
|
||||
chatImageColor: 0x573569
|
||||
snackbarBackgroundColor: accent
|
||||
snackbarTextColor: 0xFFFAF2
|
||||
messageSelectionColor: 0x775F84
|
||||
textfieldSelectionColor: 0x775F84
|
||||
menuBackgroundColor: 0x775F84
|
||||
light:
|
||||
colors:
|
||||
background: 0xFFFAF2
|
||||
header: 0xFF9800
|
||||
userBubble: 0xFF9800
|
||||
peerBubble: 0xFFF3E0
|
||||
font: 0x281831
|
||||
settings: 0x281831
|
||||
accent: 0x422850
|
||||
reaction: 0xFF9800
|
||||
theme:
|
||||
backgroundHilightElementColor: peerBubble
|
||||
backgroundMainColor: background # whitePurple
|
||||
backgroundPaneColor: background # whitePurple
|
||||
defaultButtonColor: accent # hotPink
|
||||
dropShadowColor: peerBubble
|
||||
mainTextColor: settings
|
||||
messageFromMeBackgroundColor: userBubble # brightPurple
|
||||
messageFromMeTextColor: font # mainTextColor
|
||||
messageFromOtherBackgroundColor: peerBubble # purple
|
||||
messageFromOtherTextColor: font # darkPurple
|
||||
portraitContactBadgeColor: accent
|
||||
portraitContactBadgeTextColor: 0xFFFAF2
|
||||
portraitProfileBadgeColor: accent
|
||||
portraitProfileBadgeTextColor: 0xFFFAF2
|
||||
portraitOfflineBorderColor: 0x775F84
|
||||
portraitOnlineBorderColor: font
|
||||
scrollbarDefaultColor: accent
|
||||
textfieldBackgroundColor: background
|
||||
textfieldBorderColor: userBubble
|
||||
textfieldHintColor: mainTextColor
|
||||
toolbarIconColor: background # darkPurple
|
||||
topbarColor: header # softPurple
|
||||
sendHintTextColor: 0xffd494
|
||||
chatReactionIconColor: reaction
|
||||
chatImage: Pumpkin.png
|
||||
chatImageColor: 0xFFDCA8
|
||||
snackbarBackgroundColor: accent
|
||||
snackbarTextColor: background
|
||||
messageSelectionColor: 0xFFDCA8
|
||||
textfieldSelectionColor: 0xFFDCA8
|
||||
menuBackgroundColor: 0xFFDCA8
|
Before Width: | Height: | Size: 20 KiB |
|
@ -1,85 +0,0 @@
|
|||
---
|
||||
|
||||
themes:
|
||||
name: vampire
|
||||
dark:
|
||||
colors:
|
||||
background: 0x27141B
|
||||
header: 0x27141B
|
||||
userBubble: 0x422850
|
||||
peerBubble: 0x502033
|
||||
font: 0xFBF4F7
|
||||
settings: 0xFBF4F7
|
||||
accent: 0x502033
|
||||
reaction: 0xC86B89
|
||||
theme:
|
||||
backgroundMainColor: background # darkGreyPurple
|
||||
backgroundPaneColor: header # darkGreyPurple
|
||||
defaultButtonColor: accent # hotPink
|
||||
mainTextColor: font # whiteishPurple
|
||||
messageFromMeBackgroundColor: userBubble # mauvePurple
|
||||
messageFromMeTextColor: font # whiteishPurple
|
||||
messageFromOtherBackgroundColor: peerBubble # deepPurple
|
||||
messageFromOtherTextColor: font # whiteishPurple
|
||||
portraitContactBadgeColor: 0x863655
|
||||
portraitContactBadgeTextColor: 0xFBF4F7
|
||||
portraitProfileBadgeColor: 0x863655
|
||||
portraitProfileBadgeTextColor: 0xFBF4F7
|
||||
portraitBackgroundColor: peerBubble
|
||||
portraitOfflineBorderColor: 0x863655
|
||||
portraitOnlineBorderColor: font
|
||||
scrollbarDefaultColor: accent
|
||||
textfieldHintColor: mainTextColor
|
||||
toolbarIconColor: settings # whiteishPurple
|
||||
topbarColor: header # darkGreyPurple
|
||||
sendHintTextColor: peerBubble
|
||||
chatReactionIconColor: reaction
|
||||
chatImage: Vampire.png
|
||||
chatImageColor: peerBubble
|
||||
snackbarBackgroundColor: accent
|
||||
snackbarTextColor: 0xFBF4F7
|
||||
messageSelectionColor: 0x863655
|
||||
textfieldSelectionColor: 0x863655
|
||||
menuBackgroundColor: 0x863655
|
||||
light:
|
||||
colors:
|
||||
background: 0xFBF4F7
|
||||
header: 0xC86B89
|
||||
userBubble: 0xDA94A9
|
||||
peerBubble: 0xF7EAF0
|
||||
font: 0x27141B
|
||||
settings: 0xFBF4F7
|
||||
accent: 0x502033
|
||||
reaction: 0xDA94A9
|
||||
theme:
|
||||
backgroundMainColor: background # whitePurple
|
||||
backgroundPaneColor: background # whitePurple
|
||||
defaultButtonColor: accent # hotPink
|
||||
dropShadowColor: userBubble
|
||||
mainTextColor: font
|
||||
messageFromMeBackgroundColor: userBubble # brightPurple
|
||||
messageFromMeTextColor: font # mainTextColor
|
||||
messageFromOtherBackgroundColor: peerBubble # purple
|
||||
messageFromOtherTextColor: font # darkPurple
|
||||
portraitContactBadgeColor: accent
|
||||
portraitContactBadgeTextColor: 0xFBF4F7
|
||||
portraitProfileBadgeColor: accent
|
||||
portraitProfileBadgeTextColor: 0xFBF4F7
|
||||
portraitOfflineBorderColor: 0x775F84
|
||||
portraitOnlineBorderColor: font
|
||||
portraitBackgroundColor: background
|
||||
scrollbarDefaultColor: accent
|
||||
textfieldBackgroundColor: peerBubble
|
||||
textfieldBorderColor: userBubble
|
||||
textfieldHintColor: font
|
||||
toolbarIconColor: settings # darkPurple
|
||||
topbarColor: header # softPurple
|
||||
sendHintTextColor: userBubble
|
||||
chatReactionIconColor: reaction
|
||||
chatImage: Vampire.png
|
||||
chatImageColor: 0xE9BFCD
|
||||
snackbarBackgroundColor: accent
|
||||
snackbarTextColor: background
|
||||
messageSelectionColor: header
|
||||
textfieldSelectionColor: header
|
||||
menuBackgroundColor: header
|
Before Width: | Height: | Size: 26 KiB |
|
@ -1,86 +0,0 @@
|
|||
---
|
||||
|
||||
themes:
|
||||
name: witch
|
||||
dark:
|
||||
colors:
|
||||
background: 0x111b11
|
||||
header: 0x0E1E0E
|
||||
userBubble: 0x3B5132
|
||||
peerBubble: 0x152716
|
||||
font: 0xF1F3EC
|
||||
settings: 0xE3ECD3
|
||||
accent: 0x8E64A5
|
||||
reaction: 0x97AF6E
|
||||
theme:
|
||||
backgroundHilightElementColor: peerBubble
|
||||
backgroundMainColor: background # darkGreyPurple
|
||||
backgroundPaneColor: header # darkGreyPurple
|
||||
defaultButtonColor: accent # hotPink
|
||||
mainTextColor: font # whiteishPurple
|
||||
messageFromMeBackgroundColor: userBubble # mauvePurple
|
||||
messageFromMeTextColor: font # whiteishPurple
|
||||
messageFromOtherBackgroundColor: peerBubble # deepPurple
|
||||
messageFromOtherTextColor: font # whiteishPurple
|
||||
portraitContactBadgeColor: accent
|
||||
portraitContactBadgeTextColor: 0xF1F3EC
|
||||
portraitProfileBadgeColor: accent
|
||||
portraitProfileBadgeTextColor: 0xF1F3EC
|
||||
portraitOfflineBorderColor: 0x355934
|
||||
portraitOnlineBorderColor: font
|
||||
portraitBackgroundColor: peerBubble
|
||||
scrollbarDefaultColor: accent
|
||||
textfieldBackgroundColor: peerBubble
|
||||
textfieldBorderColor: userBubble
|
||||
textfieldHintColor: mainTextColor
|
||||
toolbarIconColor: settings # whiteishPurple
|
||||
topbarColor: header # darkGreyPurple
|
||||
chatReactionIconColor: reaction
|
||||
chatImage: Witch.png
|
||||
chatImageColor: 0x1E321D
|
||||
snackbarBackgroundColor: accent
|
||||
snackbarTextColor: 0xF1F3EC
|
||||
messageSelectionColor: accent
|
||||
textfieldSelectionColor: accent
|
||||
menuBackgroundColor: accent
|
||||
light:
|
||||
colors:
|
||||
background: 0xF1F3EC
|
||||
header: 0x97af6e
|
||||
userBubble: 0x97AF6E
|
||||
peerBubble: 0xE3ECD3
|
||||
font: 0x111b11
|
||||
settings: 0x0E1E0E
|
||||
accent: 0x8E64A5
|
||||
reaction: 0x97AF6E
|
||||
theme:
|
||||
backgroundHilightElementColor: peerBubble
|
||||
backgroundMainColor: background # whitePurple
|
||||
backgroundPaneColor: background # whitePurple
|
||||
defaultButtonColor: accent # hotPink
|
||||
mainTextColor: settings
|
||||
messageFromMeBackgroundColor: userBubble # brightPurple
|
||||
messageFromMeTextColor: font # mainTextColor
|
||||
messageFromOtherBackgroundColor: peerBubble # purple
|
||||
messageFromOtherTextColor: font # darkPurple
|
||||
portraitContactBadgeColor: accent
|
||||
portraitContactBadgeTextColor: 0xF1F3EC
|
||||
portraitProfileBadgeColor: accent
|
||||
portraitProfileBadgeTextColor: 0xF1F3EC
|
||||
portraitOfflineBorderColor: userBubble
|
||||
portraitOnlineBorderColor: font
|
||||
portraitBackgroundColor: background
|
||||
scrollbarDefaultColor: accent
|
||||
textfieldBackgroundColor: background
|
||||
textfieldBorderColor: userBubble
|
||||
textfieldHintColor: font
|
||||
toolbarIconColor: settings # darkPurple
|
||||
topbarColor: header # softPurple
|
||||
chatReactionIconColor: reaction
|
||||
chatImage: Witch.png
|
||||
chatImageColor: 0xD0DDBA
|
||||
snackbarBackgroundColor: accent
|
||||
snackbarTextColor: background
|
||||
messageSelectionColor: accent
|
||||
textfieldSelectionColor: accent
|
||||
menuBackgroundColor: accent
|
|
@ -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/app/cwtch/cwtch.aar
|
||||
curl --fail https://build.openprivacy.ca/files/libCwtch-autobindings-$VERSION/android/cwtch.aar --output android/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,7 +1,7 @@
|
|||
#!/bin/sh
|
||||
|
||||
cd macos
|
||||
curl https://git.openprivacy.ca/openprivacy/buildfiles/raw/branch/master/tor/tor-0.4.8.9-macos.tar.gz --output tor.tar.gz
|
||||
curl https://git.openprivacy.ca/openprivacy/buildfiles/raw/branch/master/tor/tor-macos-0.4.7.8.tar.gz --output tor.tar.gz
|
||||
tar -xzf tor.tar.gz
|
||||
chmod a+x Tor/tor.real
|
||||
cd ..
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
Invoke-WebRequest -Uri https://git.openprivacy.ca/openprivacy/buildfiles/raw/branch/master/tor/tor-0.4.8.9-win64.zip -OutFile tor.zip
|
||||
Invoke-WebRequest -Uri https://git.openprivacy.ca/openprivacy/buildfiles/raw/branch/master/tor/tor-win64-0.4.7.8.zip -OutFile tor.zip
|
||||
|
||||
if ((Get-FileHash tor.zip -Algorithm sha512).Hash -ne 'a1c90d9a2f82df5f3d973e260bbfec76e413417cfa276fb70d1668214e2e607cf65be86a25e30c6f7814261dc154a02568459945f31389ae6a22e03d6d0d3c4c' ) { Write-Error 'tor.zip sha512sum mismatch' }
|
||||
if ((Get-FileHash tor.zip -Algorithm sha512).Hash -ne '5b8f900a37f6e90d7a945b3903d769383c7478042cb43b2105d2374186e1a536f1a4758a2823d1d5be71d53a81dcfd8243293e04f82812d355983df322823cf4' ) { Write-Error 'tor.zip sha512sum mismatch' }
|
||||
|
||||
Expand-Archive -Path tor.zip -DestinationPath Tor
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
#!/bin/sh
|
||||
|
||||
cd linux
|
||||
wget https://git.openprivacy.ca/openprivacy/buildfiles/raw/branch/master/tor/tor-0.4.8.9-linux-x86_64.tar.gz -O tor.tar.gz
|
||||
wget https://git.openprivacy.ca/openprivacy/buildfiles/raw/branch/master/tor/tor-0.4.7.8-linux-x86_64.tar.gz -O tor.tar.gz
|
||||
tar -xzf tor.tar.gz
|
||||
cd ..
|
||||
|
||||
mkdir -p android/app/src/main/jniLibs/arm64-v8a
|
||||
wget https://git.openprivacy.ca/openprivacy/buildfiles/raw/branch/master/tor/tor-0.4.8.9-android-arm64 -O android/app/src/main/jniLibs/arm64-v8a/libtor.so
|
||||
wget https://git.openprivacy.ca/openprivacy/buildfiles/raw/branch/master/tor/tor-0.4.7.10-arm64 -O android/app/src/main/jniLibs/arm64-v8a/libtor.so
|
||||
chmod a+x android/app/src/main/jniLibs/arm64-v8a/libtor.so
|
||||
|
||||
mkdir -p android/app/src/main/jniLibs/armeabi-v7a
|
||||
wget https://git.openprivacy.ca/openprivacy/buildfiles/raw/branch/master/tor/tor-0.4.8.9-android-arm7 -O android/app/src/main/jniLibs/armeabi-v7a/libtor.so
|
||||
wget https://git.openprivacy.ca/openprivacy/buildfiles/raw/branch/master/tor/tor-0.4.7.10-arm7 -O android/app/src/main/jniLibs/armeabi-v7a/libtor.so
|
||||
chmod a+x android/app/src/main/jniLibs/armeabi-v7a/libtor.so
|
||||
|
|
|
@ -12,16 +12,9 @@ Feature: Settings pane opens and can save settings persistently
|
|||
Given I tap the 'OpenSettingsView' button
|
||||
And I wait until the text 'Use Light Themes' is present
|
||||
When I tap the widget that contains the text "Use Light Themes"
|
||||
And I tap the widget that contains the text "Block Unknown Contacts"
|
||||
And I tap the widget that contains the text "Streamer/Presentation Mode"
|
||||
And I expect the switch that contains the text "Streamer/Presentation Mode" to be checked
|
||||
Then I expect the switch that contains the text "Use Light Themes" to be checked
|
||||
When I tap the 'OpenSettingsBehaviour' button
|
||||
And I wait until the text 'Notification Policy' is present
|
||||
When I tap the widget that contains the text "Block Unknown Contacts"
|
||||
And I expect the switch that contains the text "Block Unknown Contacts" to be checked
|
||||
When I tap the 'OpenSettingsExperiments' button
|
||||
And I wait until the text 'Enable Experiments' is present
|
||||
When I tap the widget that contains the text "Enable Experiments"
|
||||
And I tap the widget that contains the text "Enable Experiments"
|
||||
Then I wait until the text 'Enable Group Chat' is present
|
||||
And I tap the widget that contains the text "Enable Group Chat"
|
||||
And I tap the widget that contains the text "Hosting Servers"
|
||||
|
@ -31,6 +24,9 @@ Feature: Settings pane opens and can save settings persistently
|
|||
And I wait until the text 'Download Folder' is present
|
||||
And I fill the "DownloadFolderPicker" field with "/this/is/a/test"
|
||||
And I tap the widget that contains the text "Enable Clickable Links"
|
||||
Then I expect the switch that contains the text "Use Light Themes" to be checked
|
||||
And I expect the switch that contains the text "Block Unknown Contacts" to be checked
|
||||
And I expect the switch that contains the text "Streamer/Presentation Mode" to be checked
|
||||
And I expect the switch that contains the text "Enable Experiments" to be checked
|
||||
And I expect the switch that contains the text "Enable Group Chat" to be checked
|
||||
# Not every version of Cwtch Supports Hosting Servers..
|
||||
|
@ -46,14 +42,8 @@ Feature: Settings pane opens and can save settings persistently
|
|||
Given I tap the 'OpenSettingsView' button
|
||||
And I wait until the text 'Use Light Themes' is present
|
||||
Then I expect the switch that contains the text "Use Light Themes" to be checked
|
||||
And I expect the switch that contains the text "Block Unknown Contacts" to be checked
|
||||
And I expect the switch that contains the text "Streamer/Presentation Mode" to be checked
|
||||
When I tap the 'OpenSettingsBehaviour' button
|
||||
And I wait until the text 'Notification Policy' is present
|
||||
And I expect the switch that contains the text "Block Unknown Contacts" to be checked
|
||||
And I expect the switch that contains the text "Block Unknown Contacts" to be checked
|
||||
When I tap the 'OpenSettingsExperiments' button
|
||||
And I wait until the text 'Enable Experiments' is present
|
||||
And I wait until the text 'Enable Experiments' is present
|
||||
And I expect the switch that contains the text "Enable Experiments" to be checked
|
||||
And I expect the switch that contains the text "Enable Group Chat" to be checked
|
||||
# And I expect the switch that contains the text "Hosting Servers" to be checked
|
||||
|
|
|
@ -3,8 +3,6 @@ Feature: Block unknown contacts setting
|
|||
Scenario: Carol adds Alice but Alice doesn't see it because Block Unknowns is enabled
|
||||
Given I wait until the widget with type 'ProfileMgrView' is present
|
||||
Given I tap the 'OpenSettingsView' button
|
||||
And I wait until the text "Behaviour" is present
|
||||
When I tap the 'OpenSettingsBehaviour button
|
||||
And I wait until the text "Block Unknown Contacts" is present
|
||||
When I tap the widget that contains the text "Block Unknown Contacts"
|
||||
Then I expect the switch that contains the text "Block Unknown Contacts" to be checked
|
||||
|
|
|
@ -1,8 +1,17 @@
|
|||
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,7 +1,10 @@
|
|||
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 }
|
||||
|
||||
|
@ -14,7 +17,6 @@ class SwitchStateParameter extends CustomParameter<SwitchState> {
|
|||
case "unchecked":
|
||||
return SwitchState.unchecked;
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
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';
|
||||
|
@ -37,7 +38,7 @@ void modalOpenLink(BuildContext ctx, LinkableElement link) {
|
|||
final snackBar = SnackBar(
|
||||
content: Text(
|
||||
AppLocalizations.of(bcontext)!.copiedToClipboardNotification,
|
||||
style: Provider.of<Settings>(bcontext, listen: false).scaleFonts(defaultTextButtonStyle),
|
||||
style: Provider.of<Settings>(bcontext).scaleFonts(defaultTextButtonStyle),
|
||||
),
|
||||
);
|
||||
|
||||
|
|
|
@ -11,10 +11,8 @@ abstract class Cwtch {
|
|||
|
||||
// ignore: non_constant_identifier_names
|
||||
Future<void> Start();
|
||||
|
||||
Future<String> getCwtchDir();
|
||||
|
||||
String getAssetsDir();
|
||||
// ignore: non_constant_identifier_names
|
||||
Future<void> ReconnectCwtchForeground();
|
||||
|
||||
// ignore: non_constant_identifier_names
|
||||
void CreateProfile(String nick, String pass, bool autostart);
|
||||
|
@ -158,6 +156,4 @@ abstract class Cwtch {
|
|||
void DeleteServerInfo(String profile, String handle);
|
||||
void PublishServerUpdate(String onion);
|
||||
Future<void> ConfigureConnections(String onion, bool listen, bool peers, bool servers);
|
||||
|
||||
bool IsLoaded();
|
||||
}
|
||||
|
|
|
@ -3,10 +3,15 @@ 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';
|
||||
|
||||
|
@ -58,14 +63,7 @@ class CwtchNotifier {
|
|||
// EnvironmentConfig.debugLog("NewEvent $type $data");
|
||||
switch (type) {
|
||||
case "CwtchStarted":
|
||||
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);
|
||||
}
|
||||
|
||||
flwtchState.cwtch.LoadProfiles(DefaultPassword);
|
||||
appState.SetCwtchInit();
|
||||
break;
|
||||
case "CwtchStartError":
|
||||
|
@ -160,7 +158,7 @@ class CwtchNotifier {
|
|||
lastMessageTime: DateTime.now(),
|
||||
notificationPolicy: data["notificationPolicy"] ?? "ConversationNotificationPolicy.Default"));
|
||||
|
||||
profileCN.getProfile(data["ProfileOnion"])?.contactList.updateLastMessageReceivedTime(int.parse(data["ConversationID"]), DateTime.now());
|
||||
profileCN.getProfile(data["ProfileOnion"])?.contactList.updateLastMessageTime(int.parse(data["ConversationID"]), DateTime.now());
|
||||
}
|
||||
break;
|
||||
case "PeerDeleted":
|
||||
|
@ -195,9 +193,21 @@ 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,
|
||||
|
@ -210,19 +220,6 @@ 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":
|
||||
|
@ -257,7 +254,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 (idx >= currentTotal) {
|
||||
if (currentTotal != null && 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
|
||||
|
@ -305,7 +302,6 @@ class CwtchNotifier {
|
|||
break;
|
||||
case "UpdateGlobalSettings":
|
||||
settings.handleUpdate(jsonDecode(data["Data"]));
|
||||
appState.settingsLoaded = true;
|
||||
break;
|
||||
case "UpdatedProfileAttribute":
|
||||
if (data["Key"] == "public.profile.name") {
|
||||
|
@ -350,7 +346,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...
|
||||
}
|
||||
|
@ -380,7 +376,7 @@ class CwtchNotifier {
|
|||
isGroup: true,
|
||||
lastMessageTime: DateTime.now()));
|
||||
|
||||
profileCN.getProfile(data["ProfileOnion"])?.contactList.updateLastMessageReceivedTime(identifier, DateTime.fromMillisecondsSinceEpoch(0));
|
||||
profileCN.getProfile(data["ProfileOnion"])?.contactList.updateLastMessageTime(identifier, DateTime.fromMillisecondsSinceEpoch(0));
|
||||
}
|
||||
// request a new server update...
|
||||
// NOTE: In the future this should also update the TokenManagerInfo
|
||||
|
|
|
@ -3,6 +3,7 @@ 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;
|
||||
|
||||
|
@ -12,6 +13,7 @@ import 'package:cwtch/cwtch/cwtch.dart';
|
|||
import '../config.dart';
|
||||
|
||||
import "package:path/path.dart" show dirname, join;
|
||||
import 'dart:io' show Platform;
|
||||
|
||||
/////////////////////
|
||||
/// Cwtch API ///
|
||||
|
@ -132,8 +134,6 @@ class CwtchFfi implements Cwtch {
|
|||
late Isolate cwtchIsolate;
|
||||
ReceivePort _receivePort = ReceivePort();
|
||||
bool _isL10nInit = false;
|
||||
String _assetsDir = path.join(Directory.current.path, "data", "flutter_assets");
|
||||
String _cwtchDir = "";
|
||||
|
||||
static String getLibraryPath() {
|
||||
if (Platform.isWindows) {
|
||||
|
@ -168,12 +168,13 @@ class CwtchFfi implements Cwtch {
|
|||
String home = "";
|
||||
String bundledTor = "";
|
||||
Map<String, String> envVars = Platform.environment;
|
||||
String cwtchDir = "";
|
||||
if (Platform.isLinux) {
|
||||
home = envVars['HOME'] ?? "";
|
||||
if (EnvironmentConfig.TEST_MODE) {
|
||||
_cwtchDir = envVars['CWTCH_HOME']!;
|
||||
cwtchDir = envVars['CWTCH_HOME']!;
|
||||
} else {
|
||||
_cwtchDir = envVars['CWTCH_HOME'] ?? path.join(envVars['HOME']!, ".cwtch");
|
||||
cwtchDir = envVars['CWTCH_HOME'] ?? path.join(envVars['HOME']!, ".cwtch");
|
||||
}
|
||||
|
||||
if (await File("linux/Tor/tor").exists()) {
|
||||
|
@ -182,44 +183,38 @@ class CwtchFfi implements Cwtch {
|
|||
bundledTor = "lib/Tor/tor";
|
||||
} else if (await File(path.join(home, ".local/lib/cwtch/Tor/tor")).exists()) {
|
||||
bundledTor = path.join(home, ".local/lib/cwtch/Tor/tor");
|
||||
_assetsDir = path.join(home, ".local", "share", "cwtch", "data", "flutter_assets");
|
||||
} else if (await File("/usr/lib/cwtch/Tor/tor").exists()) {
|
||||
bundledTor = "/usr/lib/cwtch/Tor/tor";
|
||||
_assetsDir = path.join("usr", "share", "cwtch", "data", "flutter_assets");
|
||||
} else {
|
||||
bundledTor = "tor";
|
||||
}
|
||||
} else if (Platform.isWindows) {
|
||||
_cwtchDir = envVars['CWTCH_DIR'] ?? path.join(envVars['UserProfile']!, ".cwtch");
|
||||
cwtchDir = envVars['CWTCH_DIR'] ?? path.join(envVars['UserProfile']!, ".cwtch");
|
||||
String currentTor = path.join(Directory.current.absolute.path, "Tor\\Tor\\tor.exe");
|
||||
if (await File(currentTor).exists()) {
|
||||
bundledTor = currentTor;
|
||||
_assetsDir = path.join(Directory.current.absolute.path, "data", "flutter_assets");
|
||||
} else {
|
||||
String exeDir = path.dirname(Platform.resolvedExecutable);
|
||||
bundledTor = path.join(exeDir, "Tor\\Tor\\tor.exe");
|
||||
_assetsDir = path.join(exeDir, "data", "flutter_assets");
|
||||
}
|
||||
} else if (Platform.isMacOS) {
|
||||
_cwtchDir = envVars['CWTCH_HOME'] ?? path.join(envVars['HOME']!, "Library/Application Support/Cwtch");
|
||||
_assetsDir = "/Applications/Cwtch.app/Contents/Frameworks/App.framework/Versions/Current/Resources/flutter_assets/";
|
||||
if (await File("Cwtch.app/Contents/MacOS/Tor/tor").exists()) {
|
||||
bundledTor = "Cwtch.app/Contents/MacOS/Tor/tor";
|
||||
_assetsDir = "Cwtch.app/Contents/Frameworks/App.framework/Versions/Current/Resources/flutter_assets/";
|
||||
} else if (await File("/Applications/Cwtch.app/Contents/MacOS/Tor/tor").exists()) {
|
||||
bundledTor = "/Applications/Cwtch.app/Contents/MacOS/Tor/tor";
|
||||
} else if (await File("/Volumes/Cwtch/Cwtch.app/Contents/MacOS/Tor/tor").exists()) {
|
||||
bundledTor = "/Volumes/Cwtch/Cwtch.app/Contents/MacOS/Tor/tor";
|
||||
} else if (await File("/Applications/Tor Browser.app/Contents/MacOS/Tor/tor").exists()) {
|
||||
bundledTor = "/Applications/Tor Browser.app/Contents/MacOS/Tor/tor";
|
||||
cwtchDir = envVars['CWTCH_HOME'] ?? path.join(envVars['HOME']!, "Library/Application Support/Cwtch");
|
||||
if (await File("Cwtch.app/Contents/MacOS/Tor/tor.real").exists()) {
|
||||
bundledTor = "Cwtch.app/Contents/MacOS/Tor/tor.real";
|
||||
} else if (await File("/Applications/Cwtch.app/Contents/MacOS/Tor/tor.real").exists()) {
|
||||
bundledTor = "/Applications/Cwtch.app/Contents/MacOS/Tor/tor.real";
|
||||
} else if (await File("/Volumes/Cwtch/Cwtch.app/Contents/MacOS/Tor/tor.real").exists()) {
|
||||
bundledTor = "/Volumes/Cwtch/Cwtch.app/Contents/MacOS/Tor/tor.real";
|
||||
} else if (await File("/Applications/Tor Browser.app/Contents/MacOS/Tor/tor.real").exists()) {
|
||||
bundledTor = "/Applications/Tor Browser.app/Contents/MacOS/Tor/tor.real";
|
||||
print("We couldn't find Tor in the Cwtch app directory, however we can fall back to the Tor Browser binary");
|
||||
} else {
|
||||
var splitPath = path.split(dirname(Platform.script.path));
|
||||
if (splitPath[0] == "/" && splitPath[1] == "Applications") {
|
||||
var appName = splitPath[2];
|
||||
print("We're running in /Applications in a non standard app name: $appName");
|
||||
if (await File("/Applications/$appName/Contents/MacOS/Tor/tor").exists()) {
|
||||
bundledTor = "/Applications/$appName/Contents/MacOS/Tor/tor";
|
||||
if (await File("/Applications/$appName/Contents/MacOS/Tor/tor.real").exists()) {
|
||||
bundledTor = "/Applications/$appName/Contents/MacOS/Tor/tor.real";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -230,27 +225,27 @@ class CwtchFfi implements Cwtch {
|
|||
// if macOs and release build and no profile and is dev profile
|
||||
// copy dev profile to release profile
|
||||
if (Platform.isMacOS && EnvironmentConfig.BUILD_VER != dev_version) {
|
||||
var devProfileExists = await Directory(path.join(_cwtchDir, "dev", "profiles")).exists();
|
||||
var releaseProfileExists = await Directory(path.join(_cwtchDir, "profiles")).exists();
|
||||
var devProfileExists = await Directory(path.join(cwtchDir, "dev", "profiles")).exists();
|
||||
var releaseProfileExists = await Directory(path.join(cwtchDir, "profiles")).exists();
|
||||
if (devProfileExists && !releaseProfileExists) {
|
||||
print("MacOS one time dev -> release profile migration...");
|
||||
await Process.run("cp", ["-r", "-p", path.join(_cwtchDir, "dev", "profiles"), _cwtchDir]);
|
||||
await Process.run("cp", ["-r", "-p", path.join(_cwtchDir, "dev", "SALT"), _cwtchDir]);
|
||||
await Process.run("cp", ["-r", "-p", path.join(_cwtchDir, "dev", "ui.globals"), _cwtchDir]);
|
||||
await Process.run("cp", ["-r", "-p", path.join(cwtchDir, "dev", "profiles"), cwtchDir]);
|
||||
await Process.run("cp", ["-r", "-p", path.join(cwtchDir, "dev", "SALT"), cwtchDir]);
|
||||
await Process.run("cp", ["-r", "-p", path.join(cwtchDir, "dev", "ui.globals"), cwtchDir]);
|
||||
}
|
||||
}
|
||||
|
||||
if (EnvironmentConfig.BUILD_VER == dev_version) {
|
||||
_cwtchDir = path.join(_cwtchDir, "dev");
|
||||
cwtchDir = path.join(cwtchDir, "dev");
|
||||
}
|
||||
|
||||
print("StartCwtch( cwtchdir: $_cwtchDir, torPath: $bundledTor )");
|
||||
print("StartCwtch( cwtchdir: $cwtchDir, torPath: $bundledTor )");
|
||||
|
||||
var startCwtchC = library.lookup<NativeFunction<start_cwtch_function>>("c_StartCwtch");
|
||||
// ignore: non_constant_identifier_names
|
||||
final StartCwtch = startCwtchC.asFunction<StartCwtchFn>();
|
||||
|
||||
final utf8CwtchDir = _cwtchDir.toNativeUtf8();
|
||||
final utf8CwtchDir = cwtchDir.toNativeUtf8();
|
||||
StartCwtch(utf8CwtchDir, utf8CwtchDir.length, bundledTor.toNativeUtf8(), bundledTor.length);
|
||||
malloc.free(utf8CwtchDir);
|
||||
|
||||
|
@ -262,19 +257,17 @@ class CwtchFfi implements Cwtch {
|
|||
});
|
||||
}
|
||||
|
||||
String getAssetsDir() {
|
||||
return _assetsDir;
|
||||
}
|
||||
|
||||
Future<String> getCwtchDir() async {
|
||||
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() {
|
||||
EnvironmentConfig.debugLog("tearing down cwtch FFI isolate");
|
||||
library.close();
|
||||
cwtchIsolate.kill(priority: Isolate.immediate);
|
||||
}
|
||||
|
||||
|
@ -1128,11 +1121,4 @@ class CwtchFfi implements Cwtch {
|
|||
PublishServerUpdate(utf8profile, utf8profile.length);
|
||||
malloc.free(utf8profile);
|
||||
}
|
||||
|
||||
@override
|
||||
bool IsLoaded() {
|
||||
bool check = library.providesSymbol("c_UpdateSettings");
|
||||
EnvironmentConfig.debugLog("Checking that the FFI Interface is Correctly Loaded... $check");
|
||||
return check;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,7 +30,6 @@ class CwtchGomobile implements Cwtch {
|
|||
late Future<dynamic> androidLibraryDir;
|
||||
late Future<dynamic> androidHomeDirectory;
|
||||
String androidHomeDirectoryStr = "";
|
||||
String _cwtchDir = "";
|
||||
late CwtchNotifier cwtchNotifier;
|
||||
bool _isL10nInit = false;
|
||||
|
||||
|
@ -63,27 +62,23 @@ class CwtchGomobile implements Cwtch {
|
|||
appbusEventChannel.setMethodCallHandler(this._handleAppbusEvent);
|
||||
}
|
||||
|
||||
String getAssetsDir() {
|
||||
// TODO
|
||||
return "";
|
||||
}
|
||||
|
||||
// Requires Start() to have been run to initialize
|
||||
Future<String> getCwtchDir() async {
|
||||
return _cwtchDir;
|
||||
}
|
||||
|
||||
// ignore: non_constant_identifier_names
|
||||
Future<void> Start() async {
|
||||
print("gomobile.dart: Start()...");
|
||||
androidHomeDirectoryStr = (await androidHomeDirectory).path;
|
||||
_cwtchDir = path.join(androidHomeDirectoryStr, ".cwtch");
|
||||
var cwtchDir = path.join(androidHomeDirectoryStr, ".cwtch");
|
||||
if (EnvironmentConfig.BUILD_VER == dev_version) {
|
||||
_cwtchDir = path.join(_cwtchDir, "dev");
|
||||
cwtchDir = path.join(cwtchDir, "dev");
|
||||
}
|
||||
String torPath = path.join(await androidLibraryDir, "libtor.so");
|
||||
print("gomobile.dart: Start invokeMethod Start($_cwtchDir, $torPath)...");
|
||||
cwtchPlatform.invokeMethod("Start", {"appDir": _cwtchDir, "torPath": torPath});
|
||||
print("gomobile.dart: Start invokeMethod Start($cwtchDir, $torPath)...");
|
||||
return 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
|
||||
|
@ -474,9 +469,4 @@ class CwtchGomobile implements Cwtch {
|
|||
void PublishServerUpdate(String profile) {
|
||||
cwtchPlatform.invokeMethod("PublishServerUpdate", {"ProfileOnion": profile});
|
||||
}
|
||||
|
||||
@override
|
||||
bool IsLoaded() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -648,20 +648,4 @@ 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,17 +1,6 @@
|
|||
{
|
||||
"@@locale": "cy",
|
||||
"@@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",
|
||||
"settingsThemeErrorInvalid": "Error: Could not import $themeName, theme.yml missing, not a theme directory",
|
||||
"settingThemeOverwriteQuestion": "Theme $themeName already exists, confirm overwrite?",
|
||||
"settingThemeOverwriteConfirm": "Confirm",
|
||||
"settingsThemeImagesDescription": "Enable display of images from themes",
|
||||
"settingsThemeImages": "Theme Images",
|
||||
"settingsGroupAbout": "About",
|
||||
"@@last_modified": "2023-09-25T21:29:34+02:00",
|
||||
"localeUzbek": "Uzbek \/ Oʻzbekcha",
|
||||
"profileOfflineAtStart": "Appear Offline at Startup",
|
||||
"now": "Now",
|
||||
|
|
|
@ -1,17 +1,6 @@
|
|||
{
|
||||
"@@locale": "da",
|
||||
"@@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",
|
||||
"settingsThemeErrorInvalid": "Error: Could not import $themeName, theme.yml missing, not a theme directory",
|
||||
"settingThemeOverwriteQuestion": "Theme $themeName already exists, confirm overwrite?",
|
||||
"settingThemeOverwriteConfirm": "Confirm",
|
||||
"settingsThemeImagesDescription": "Enable display of images from themes",
|
||||
"settingsThemeImages": "Theme Images",
|
||||
"settingsGroupAbout": "About",
|
||||
"@@last_modified": "2023-09-25T21:29:34+02:00",
|
||||
"localeUzbek": "Uzbek \/ Oʻzbekcha",
|
||||
"profileOfflineAtStart": "Appear Offline at Startup",
|
||||
"now": "Now",
|
||||
|
|
|
@ -1,40 +1,27 @@
|
|||
{
|
||||
"@@locale": "de",
|
||||
"@@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:",
|
||||
"@@last_modified": "2023-09-25T21:29:34+02:00",
|
||||
"localeUzbek": "Uzbek \/ Oʻzbekcha",
|
||||
"profileOfflineAtStart": "Appear Offline at Startup",
|
||||
"now": "Now",
|
||||
"xSecondsAgo": "$seconds seconds ago",
|
||||
"xMinutesAgo": "$minutes minutes ago",
|
||||
"xHoursAgo": "$hours hours ago",
|
||||
"xDaysAgo": "$days days ago",
|
||||
"profileAllowUnknownContacts": "Allow Unknown Contacts",
|
||||
"profileBlockUnknownContacts": "Block Unknown Contacts",
|
||||
"profileDisableProfile": "Disable Profile",
|
||||
"profileEnableProfile": "Enable Profile",
|
||||
"profileAppearOnline": "Appear Online",
|
||||
"contactDisconnect": "Disconnect from Contact (if you do not have Appear Offline set this contact may still be able to reestablish a connection to you)",
|
||||
"profileAppearOfflineDescription": "By default, when Cwtch profile is enabled it automatically attempts to connect to know contacts, and allows inbound connections. This settings disables those actions and allows you to choose, manually, which contacts to connect to.",
|
||||
"profileAppearOffline": "Appear Offline",
|
||||
"deleteServerConfirmBtn": "Server wirklich löschen",
|
||||
"cannotDeleteServerIfActiveGroups": "There are active groups associated with this Cwtch Server. Please delete them prior to deleting this Cwtch Server entry.",
|
||||
"groupsOnThisServerLabel": "Gruppen, in denen ich bin, werden auf diesem Server gehostet",
|
||||
"profileEnabledDescription": "Starten oder Stoppen des Profils",
|
||||
"defaultPreserveHistorySetting": "Konversationsverlauf bewahren",
|
||||
"preserveHistorySettingDescription": "Standardmäßig löscht Cwtch den Gesprächsverlauf, wenn Cwtch heruntergefahren wird. Wenn diese Einstellung aktiviert ist, bewahrt Cwtch den Gesprächsverlauf von Peer-Unterhaltungen auf.",
|
||||
"serverinfoNoGroupInfo": "Es gibt keine Gruppen, die mit diesem Cwtch Server verbunden sind.",
|
||||
"cannotDeleteServerIfActiveGroups": "Es gibt aktive Gruppen, die mit diesem Cwtch Server verbunden sind. Bitte lösche diese, bevor du diesen Cwtch-Server-Eintrag löschst.",
|
||||
"profileAppearOnline": "Online erscheinen",
|
||||
"profileAppearOffline": "Offline erscheinen",
|
||||
"profileAppearOfflineDescription": "Standardmäßig wird bei aktiviertem Cwtch-Profil automatisch versucht, eine Verbindung zu bekannten Kontakten herzustellen und es werden eingehende Verbindungen zugelassen. Mit dieser Einstellung werden diese Aktionen deaktiviert und du kannst manuell auswählen, mit welchen Kontakten eine Verbindung hergestellt werden soll.",
|
||||
"contactDisconnect": "Trenne die Verbindung mit dem Kontakt (wenn du die Funktion Offline erscheinen nicht aktiviert habst, kann der Kontakt trotzdem eine Verbindung zu dir herstellen)",
|
||||
"profileEnableProfile": "Profil aktivieren",
|
||||
"profileDisableProfile": "Profil deaktivieren",
|
||||
"profileBlockUnknownContacts": "Unbekannte Kontakte blockieren",
|
||||
"profileAllowUnknownContacts": "Unbekannte Kontakte zulassen",
|
||||
"profileOfflineAtStart": "Beim Start offline erscheinen",
|
||||
"xDaysAgo": "vor $days Tagen",
|
||||
"xHoursAgo": "vor $hours Stunden",
|
||||
"xMinutesAgo": "vor $minutes Minuten",
|
||||
"xSecondsAgo": "vor $seconds Sekunden",
|
||||
"now": "Jetzt",
|
||||
"localeUzbek": "Usbekisch \/ Oʻzbekcha",
|
||||
"settingsGroupAbout": "Über",
|
||||
"settingsThemeImages": "Theme Bilder",
|
||||
"settingsThemeImagesDescription": "Aktiviere die Anzeige von Bildern aus Themes",
|
||||
"settingThemeOverwriteConfirm": "Bestätigen",
|
||||
"settingThemeOverwriteQuestion": "Theme $themeName existiert bereits, Überschreiben bestätigen?",
|
||||
"settingsThemeErrorInvalid": "Fehler: Konnte $themeName nicht importieren, theme.yml fehlt, kein Theme-Verzeichnis",
|
||||
"settingsImportThemeTitle": "Theme importieren",
|
||||
"settingsImportThemeDescription": "Wähle das Theme-Verzeichnis aus, das zur Verwendung in Cwtch importiert werden soll",
|
||||
"settingsImportThemeButton": "Theme importieren",
|
||||
"serverinfoNoGroupInfo": "There are no groups associated with this Cwtch Server.",
|
||||
"preserveHistorySettingDescription": "By default, Cwtch will purge conversation history when Cwtch is shutdown. If this setting is enabled, Cwtch will preserve the conversation history of peer conversations.",
|
||||
"defaultPreserveHistorySetting": "Preserve Conversation History",
|
||||
"retryConnection": "Wiederholen",
|
||||
"retryConnectionTooltip": "Cwtch wiederholt die Versuche regelmäßig, aber du kannst Cwtch anweisen, es früher zu versuchen, indem du diese Taste drückst.",
|
||||
"localeJa": "Japanisch \/ 日本語",
|
||||
|
@ -42,6 +29,8 @@
|
|||
"localeSv": "Schwedisch \/ Svenska",
|
||||
"localeSw": "Suaheli \/ Kiswahili",
|
||||
"localeUk": "Ukrainisch \/ українською",
|
||||
"profileEnabledDescription": "Starten oder Stoppen des Profils",
|
||||
"defaultScalingText": "Text in Standardgröße (Skalierungsfaktor:",
|
||||
"blodeuweddExperimentEnable": "Blodeuwedd Assistent",
|
||||
"blodeuweddDescription": "Der Blodeuwedd-Assistent erweitert Cwtch um neue Funktionen wie die Zusammenfassung von Chat-Transkripten und die Übersetzung von Nachrichten über ein lokal gehostetes Sprachmodell.",
|
||||
"blodeuweddNotSupported": "Diese Version von Cwtch wurde ohne Unterstützung für den Blodeuwedd-Assistenten kompiliert.",
|
||||
|
|
|
@ -1,17 +1,6 @@
|
|||
{
|
||||
"@@locale": "el",
|
||||
"@@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",
|
||||
"settingsThemeErrorInvalid": "Error: Could not import $themeName, theme.yml missing, not a theme directory",
|
||||
"settingThemeOverwriteQuestion": "Theme $themeName already exists, confirm overwrite?",
|
||||
"settingThemeOverwriteConfirm": "Confirm",
|
||||
"settingsThemeImagesDescription": "Enable display of images from themes",
|
||||
"settingsThemeImages": "Theme Images",
|
||||
"settingsGroupAbout": "About",
|
||||
"@@last_modified": "2023-09-25T21:29:34+02:00",
|
||||
"localeUzbek": "Uzbek \/ Oʻzbekcha",
|
||||
"profileOfflineAtStart": "Appear Offline at Startup",
|
||||
"now": "Now",
|
||||
|
|
|
@ -1,17 +1,6 @@
|
|||
{
|
||||
"@@locale": "en",
|
||||
"@@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",
|
||||
"settingsImportThemeTitle": "Import Theme",
|
||||
"settingsImportThemeDescription": "Select theme directory to import for use in Cwtch",
|
||||
"settingsImportThemeButton": "Import Theme",
|
||||
"settingsThemeImagesDescription": "Enable display of images from themes",
|
||||
"settingsThemeImages": "Theme Images",
|
||||
"settingsGroupAbout": "About",
|
||||
"@@last_modified": "2023-09-25T21:29:34+02:00",
|
||||
"localeUzbek": "Uzbek \/ Oʻzbekcha",
|
||||
"profileOfflineAtStart": "Appear Offline at Startup",
|
||||
"now": "Now",
|
||||
|
|
|
@ -1,73 +1,62 @@
|
|||
{
|
||||
"@@locale": "es",
|
||||
"@@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",
|
||||
"settingsThemeErrorInvalid": "Error: Could not import $themeName, theme.yml missing, not a theme directory",
|
||||
"settingThemeOverwriteQuestion": "Theme $themeName already exists, confirm overwrite?",
|
||||
"settingThemeOverwriteConfirm": "Confirm",
|
||||
"settingsThemeImagesDescription": "Enable display of images from themes",
|
||||
"settingsThemeImages": "Theme Images",
|
||||
"settingsGroupAbout": "About",
|
||||
"deleteServerConfirmBtn": "¿Realmente desea borrar el servidor?",
|
||||
"defaultScalingText": "Factor de escala del texto",
|
||||
"groupsOnThisServerLabel": "Grupos alojados en este servidor de Cwtch",
|
||||
"shareMenuQRCode": "Mostrar código QR",
|
||||
"experimentQRCodeDescription": "La compatibilidad con códigos QR permite compartir datos (como la identidad del perfil) mediante códigos QR",
|
||||
"enableExperimentQRCode": "Códigos QR",
|
||||
"localeNl": "Holandés \/ Dutch",
|
||||
"localePtBr": "Portugués brasileño \/ Português do Brasil",
|
||||
"profileAutostartLabel": "Inicio automático",
|
||||
"profileEnabled": "Habilitar",
|
||||
"profileAutostartDescription": "Controla si el perfil se iniciará automáticamente al iniciar Cwtch",
|
||||
"profileEnabledDescription": "Activar o Desactivar el perfil.",
|
||||
"localeSk": "Eslovaco \/ Slovák",
|
||||
"localeKo": "Coreano \/ 한국어",
|
||||
"blodeuweddExperimentEnable": "Asistente Blodeuwedd",
|
||||
"blodeuweddDescription": "El asistente Blodeuwedd agrega nuevas funciones a Cwtch, como el resumen de la transcripción del chat y la traducción de mensajes a través de un modelo de lenguaje alojado localmente.",
|
||||
"blodeuweddNotSupported": "Esta versión de Cwtch se ha compilado sin soporte para Blodeuwedd Assistant.",
|
||||
"blodeuweddPath": "El directorio donde se encuentra Blodeuwedd está en tu computadora.",
|
||||
"blodeuweddSummarize": "Resumir la conversación",
|
||||
"blodeuweddWarning": "Blodeuwedd utiliza un modelo de idioma local y un conjunto de modelos auxiliares para potenciar su funcionalidad. Estas técnicas suelen ser muy efectivas y no están exentas de errores. \n\nSi bien nos hemos esforzado por minimizar el riesgo, todavía existe la posibilidad de que los resultados de Blodeuwedd sean incorrectos, sin-sentido y\/u ofensivos. \n\nDebido a eso, Blodeuwedd requiere descargar dos componentes adicionales separados de Cwtch, el modelo Blodeuwedd (o un modelo compatible) y el Blodeuwedd Runner. \n\nConsulta https:\/\/docs.cwtch.im\/docs\/settings\/experiments\/blodeuwedd para obtener más información sobre cómo obtener estos componentes y configurarlos.",
|
||||
"blodeuweddTranslate": "Traducir mensaje",
|
||||
"blodeuweddProcessing": "Blodeuwedd está procesando...",
|
||||
"availabilityStatusBusy": "Ocupad()",
|
||||
"availabilityStatusAvailable": "Disponible",
|
||||
"availabilityStatusAway": "Ausente",
|
||||
"shareProfileMenuTooltop": "Comparte éste perfil por medio de...",
|
||||
"availabilityStatusTooltip": "Establece tu estado",
|
||||
"profileInfoHint": "Agrega información sobre tí, por ejemplo un blog, sitio web o una breve biografía.",
|
||||
"profileInfoHint2": "Puedes agregar hasta 3 campos.",
|
||||
"profileInfoHint3": "Los contactos podrán ver esta información en la Configuración de la Conversación ",
|
||||
"retryConnection": "Reintentar",
|
||||
"fontScalingDescription": "Ajusta el factor de escala de fuente relativo aplicado al texto y los widgets.",
|
||||
"retryConnectionTooltip": "Cwtch reintenta conectarse a sus pares regularmente, pero puedes decirle a Cwtch que lo intente antes presionando este botón.",
|
||||
"localeJa": "Japonés \/ 日本語",
|
||||
"localeSv": "Sueco \/ Svenska",
|
||||
"localeSw": "Suajili \/ Kiswahili",
|
||||
"localeUk": "Ucraniano \/ українською",
|
||||
"defaultPreserveHistorySetting": "Preservar el historial de conversaciones",
|
||||
"preserveHistorySettingDescription": "De forma predeterminada, Cwtch borrará el historial de conversaciones cuando se cierre Cwtch. Si esta configuración está habilitada, Cwtch preservará el historial de conversaciones de pares.",
|
||||
"serverinfoNoGroupInfo": "No hay grupos asociados co este servidor de Cwtch.",
|
||||
"cannotDeleteServerIfActiveGroups": "Hay grupos activos asociados con este servidor de Cwtch. Elimínalos antes de eliminar esta entrada del servidor de Cwtch.",
|
||||
"profileAppearOffline": "Aparecer sin conexión",
|
||||
"profileAppearOfflineDescription": "De forma predeterminada, cuando el perfil Cwtch está habilitado, intenta conectarse automáticamente para conocer contactos y permite conexiones entrantes. Esta configuración desactiva esas acciones y te permite elegir, manualmente, a qué contactos conectarte.",
|
||||
"contactDisconnect": "Desconectarse del contacto (si no tienes configurado Aparecer sin conexión, es posible que este contacto aún pueda restablecer la conexión contigo)",
|
||||
"profileAppearOnline": "Aparecer en línea",
|
||||
"profileEnableProfile": "Habilitar perfil",
|
||||
"profileDisableProfile": "Deshabilitar perfil",
|
||||
"profileBlockUnknownContacts": "Bloquear contactos desconocidos",
|
||||
"profileAllowUnknownContacts": "Permitir contactos desconocidos",
|
||||
"profileOfflineAtStart": "Aparecer sin conexión al iniciar",
|
||||
"xDaysAgo": "Hace $days días",
|
||||
"xHoursAgo": "Hace $hours horas",
|
||||
"xMinutesAgo": "Hace $minutes minutos",
|
||||
"xSecondsAgo": "Hace $seconds segundos",
|
||||
"now": "Ahora",
|
||||
"localeUzbek": "Uzbeko \/ O'zbekcha",
|
||||
"@@last_modified": "2023-09-25T21:29:34+02:00",
|
||||
"localeUzbek": "Uzbek \/ Oʻzbekcha",
|
||||
"profileOfflineAtStart": "Appear Offline at Startup",
|
||||
"now": "Now",
|
||||
"xSecondsAgo": "$seconds seconds ago",
|
||||
"xMinutesAgo": "$minutes minutes ago",
|
||||
"xHoursAgo": "$hours hours ago",
|
||||
"xDaysAgo": "$days days ago",
|
||||
"profileAllowUnknownContacts": "Allow Unknown Contacts",
|
||||
"profileBlockUnknownContacts": "Block Unknown Contacts",
|
||||
"profileDisableProfile": "Disable Profile",
|
||||
"profileEnableProfile": "Enable Profile",
|
||||
"profileAppearOnline": "Appear Online",
|
||||
"contactDisconnect": "Disconnect from Contact (if you do not have Appear Offline set this contact may still be able to reestablish a connection to you)",
|
||||
"profileAppearOfflineDescription": "By default, when Cwtch profile is enabled it automatically attempts to connect to know contacts, and allows inbound connections. This settings disables those actions and allows you to choose, manually, which contacts to connect to.",
|
||||
"profileAppearOffline": "Appear Offline",
|
||||
"deleteServerConfirmBtn": "Realmente eliminar el servidor",
|
||||
"cannotDeleteServerIfActiveGroups": "There are active groups associated with this Cwtch Server. Please delete them prior to deleting this Cwtch Server entry.",
|
||||
"groupsOnThisServerLabel": "Grupos alojados en este servidor en los que estoy",
|
||||
"serverinfoNoGroupInfo": "There are no groups associated with this Cwtch Server.",
|
||||
"preserveHistorySettingDescription": "By default, Cwtch will purge conversation history when Cwtch is shutdown. If this setting is enabled, Cwtch will preserve the conversation history of peer conversations.",
|
||||
"defaultPreserveHistorySetting": "Preserve Conversation History",
|
||||
"localeUk": "Ukrainian \/ українською",
|
||||
"profileEnabledDescription": "Activate or Deactivate the profile.",
|
||||
"localeSw": "Swahili \/ Kiswahili",
|
||||
"localeSv": "Swedish \/ Svenska",
|
||||
"fontScalingDescription": "Adjust the relative font scaling factor applied to text and widgets.",
|
||||
"defaultScalingText": "Tamaño predeterminado de texto (factor de escala:",
|
||||
"localeJa": "Japanese \/ 日本語",
|
||||
"retryConnectionTooltip": "Cwtch retries peers regularly, but you can tell Cwtch to try sooner by pushing this button.",
|
||||
"retryConnection": "Retry",
|
||||
"availabilityStatusTooltip": "Set your availability status",
|
||||
"profileInfoHint3": "Contacts will be able to see this information in Conversation Settings ",
|
||||
"profileInfoHint2": "You can add up to 3 fields.",
|
||||
"profileInfoHint": "Add some public information about yourself here e.g. blog, websites, brief bio.",
|
||||
"availabilityStatusBusy": "Busy",
|
||||
"availabilityStatusAway": "Away",
|
||||
"availabilityStatusAvailable": "Available",
|
||||
"blodeuweddWarning": "Blodeuwedd uses a local language model and a set of small auxiliary models to power its functionality. These techniques are often very effective they are not without error. \n\nWhile we have taken efforts to minimize the risk, there is still the possibility that Blodeuwedd outputs will be incorrect, hallucinated and\/or offensive.\n\nBecause of that Blodeuwedd requires downloading two additional components separate from Cwtch, the Blodeuwedd Model (or a compatible model) and the Blodeuwedd Runner. \n\nSee https:\/\/docs.cwtch.im\/docs\/settings\/experiments\/blodeuwedd for more information on obtaining these components and setting them up.",
|
||||
"blodeuweddProcessing": "Blodeuwedd is processing...",
|
||||
"blodeuweddTranslate": "Translate Message",
|
||||
"blodeuweddSummarize": "Summarize Conversation",
|
||||
"blodeuweddPath": "The directory where the Blodeuwedd is located on your computer.",
|
||||
"blodeuweddNotSupported": "This version of Cwtch has been compiled without support for the Blodeuwedd Assistant.",
|
||||
"blodeuweddDescription": "The Blodeuwedd assistant adds new features to Cwtch such as chat transcript summarization and message translation via a locally hosted language model.",
|
||||
"blodeuweddExperimentEnable": "Blodeuwedd Assistant",
|
||||
"localeKo": "Korean \/ 한국어",
|
||||
"localeSk": "Slovak \/ Slovák",
|
||||
"profileAutostartDescription": "Controls if the profile will be automatically launched on startup",
|
||||
"profileEnabled": "Enable",
|
||||
"profileAutostartLabel": "Autostart",
|
||||
"localePtBr": "Brazilian Portuguese \/ Português do Brasil",
|
||||
"localeNl": "Dutch \/ Dutch",
|
||||
"experimentQRCodeDescription": "QR Code support allows sharing data (such as profile identity) by QR Codes",
|
||||
"enableExperimentQRCode": "QR Codes",
|
||||
"shareMenuQRCode": "Show QR Code",
|
||||
"shareProfileMenuTooltop": "Share profile via...",
|
||||
"tooltipPinConversation": "Fija la conversación en la parte superior de \"Conversaciones\"",
|
||||
"errorDownloadDirectoryDoesNotExist": "No se puede habilitar el uso compartido de archivos porque la carpeta de descarga no se ha configurado o se configuró en una carpeta que no existe.",
|
||||
"acquiringTicketsFromServer": "Realizando Desafío Antispam",
|
||||
|
|
|
@ -1,17 +1,6 @@
|
|||
{
|
||||
"@@locale": "fr",
|
||||
"@@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",
|
||||
"settingsThemeErrorInvalid": "Error: Could not import $themeName, theme.yml missing, not a theme directory",
|
||||
"settingThemeOverwriteQuestion": "Theme $themeName already exists, confirm overwrite?",
|
||||
"settingThemeOverwriteConfirm": "Confirm",
|
||||
"settingsThemeImagesDescription": "Enable display of images from themes",
|
||||
"settingsThemeImages": "Theme Images",
|
||||
"settingsGroupAbout": "About",
|
||||
"@@last_modified": "2023-09-25T21:29:34+02:00",
|
||||
"localeUzbek": "Uzbek \/ Oʻzbekcha",
|
||||
"profileOfflineAtStart": "Appear Offline at Startup",
|
||||
"now": "Now",
|
||||
|
|
|
@ -1,17 +1,6 @@
|
|||
{
|
||||
"@@locale": "it",
|
||||
"@@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",
|
||||
"settingsThemeErrorInvalid": "Error: Could not import $themeName, theme.yml missing, not a theme directory",
|
||||
"settingThemeOverwriteQuestion": "Theme $themeName already exists, confirm overwrite?",
|
||||
"settingThemeOverwriteConfirm": "Confirm",
|
||||
"settingsThemeImagesDescription": "Enable display of images from themes",
|
||||
"settingsThemeImages": "Theme Images",
|
||||
"settingsGroupAbout": "About",
|
||||
"@@last_modified": "2023-09-25T21:29:34+02:00",
|
||||
"localeUzbek": "Uzbek \/ Oʻzbekcha",
|
||||
"profileOfflineAtStart": "Appear Offline at Startup",
|
||||
"now": "Now",
|
||||
|
|
|
@ -1,17 +1,6 @@
|
|||
{
|
||||
"@@locale": "ja",
|
||||
"@@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",
|
||||
"settingsThemeErrorInvalid": "Error: Could not import $themeName, theme.yml missing, not a theme directory",
|
||||
"settingThemeOverwriteQuestion": "Theme $themeName already exists, confirm overwrite?",
|
||||
"settingThemeOverwriteConfirm": "Confirm",
|
||||
"settingsThemeImagesDescription": "Enable display of images from themes",
|
||||
"settingsThemeImages": "Theme Images",
|
||||
"settingsGroupAbout": "About",
|
||||
"@@last_modified": "2023-09-25T21:29:34+02:00",
|
||||
"localeUzbek": "Uzbek \/ Oʻzbekcha",
|
||||
"profileOfflineAtStart": "Appear Offline at Startup",
|
||||
"now": "Now",
|
||||
|
|
|
@ -1,45 +1,6 @@
|
|||
{
|
||||
"@@locale": "ko",
|
||||
"@@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",
|
||||
"invalidImportString": "잘못된 가져오기 문자열",
|
||||
"settingsImportThemeButton": "Import Theme",
|
||||
"settingsImportThemeDescription": "Select theme directory to import for use in Cwtch",
|
||||
"settingsImportThemeTitle": "Import Theme",
|
||||
"settingsThemeErrorInvalid": "Error: Could not import $themeName, theme.yml missing, not a theme directory",
|
||||
"settingThemeOverwriteQuestion": "Theme $themeName already exists, confirm overwrite?",
|
||||
"settingThemeOverwriteConfirm": "Confirm",
|
||||
"resetTor": "초기화",
|
||||
"torStatus": "Tor 상태",
|
||||
"torVersion": "Tor 버전",
|
||||
"passwordChangeError": "암호 변경 오류: 제공된 암호가 거부되었습니다.",
|
||||
"enterProfilePassword": "프로필을 보려면 암호를 입력하세요.",
|
||||
"todoPlaceholder": "할 일...",
|
||||
"addNewItem": "목록에 새 항목 추가",
|
||||
"addListItem": "새 목록 항목 추가",
|
||||
"networkStatusConnecting": "네트워크 및 연락처에 연결 중...",
|
||||
"networkStatusAttemptingTor": "Tor 네트워크에 연결을 시도 중",
|
||||
"networkStatusDisconnected": "인터넷 연결 끊김, 연결 확인하세요",
|
||||
"viewGroupMembershipTooltip": "그룹 구성원 보기",
|
||||
"defaultScalingText": "글꼴 크기 조정",
|
||||
"experimentsEnabled": "실험 사용",
|
||||
"loadingTor": "tor 로딩 중...",
|
||||
"builddate": "빌드 대상: %2",
|
||||
"version": "버전: %1",
|
||||
"versionTor": "버전 %1 및 tor %2",
|
||||
"settingInterfaceZoom": "확대\/축소 수준",
|
||||
"versionBuilddate": "버전: %1 빌드 대상: %2",
|
||||
"error0ProfilesLoadedForPassword": "해당 비밀번호가 포함된 프로필이 0개 로드되었습니다.",
|
||||
"deleteConfirmText": "삭제",
|
||||
"unblockBtn": "연락처 차단 해제",
|
||||
"savePeerHistoryDescription": "연락처와 연결된 기록을 삭제할지 여부를 결정합니다.",
|
||||
"settingsThemeImagesDescription": "Enable display of images from themes",
|
||||
"settingsThemeImages": "Theme Images",
|
||||
"settingsGroupAbout": "About",
|
||||
"@@last_modified": "2023-09-25T21:29:34+02:00",
|
||||
"localeUzbek": "Uzbek \/ Oʻzbekcha",
|
||||
"profileOfflineAtStart": "Appear Offline at Startup",
|
||||
"now": "Now",
|
||||
|
@ -152,6 +113,7 @@
|
|||
"server": "서버",
|
||||
"peerName": "이름",
|
||||
"peerAddress": "주소",
|
||||
"builddate": "Built on: %2",
|
||||
"deleteProfileConfirmBtn": "프로필 삭제 확인",
|
||||
"deleteConfirmLabel": "DELETE를 입력하여 확인",
|
||||
"deleteProfileBtn": "프로필 삭제",
|
||||
|
@ -187,6 +149,7 @@
|
|||
"localeSw": "Swahili \/ Kiswahili",
|
||||
"localeSv": "Swedish \/ Svenska",
|
||||
"fontScalingDescription": "Adjust the relative font scaling factor applied to text and widgets.",
|
||||
"defaultScalingText": "Font Scaling",
|
||||
"localeJa": "Japanese \/ 日本語",
|
||||
"retryConnectionTooltip": "Cwtch retries peers regularly, but you can tell Cwtch to try sooner by pushing this button.",
|
||||
"retryConnection": "Retry",
|
||||
|
@ -410,6 +373,11 @@
|
|||
"nickChangeSuccess": "Profile nickname changed successfully",
|
||||
"addServerFirst": "You need to add a server before you can create a group",
|
||||
"deleteProfileSuccess": "Successfully deleted profile",
|
||||
"sendInvite": "Send a contact or group invite",
|
||||
"resetTor": "Reset",
|
||||
"torStatus": "Tor Status",
|
||||
"torVersion": "Tor Version",
|
||||
"sendAnInvitation": "You sent an invitation for: ",
|
||||
"contactSuggestion": "This is a contact suggestion for: ",
|
||||
"chatHistoryDefault": "This conversation will be deleted when Cwtch is closed! Message history can be enabled per-conversation via the Settings menu in the upper right.",
|
||||
"reallyLeaveThisGroupPrompt": "Are you sure you want to leave this conversation? All messages and attributes will be deleted.",
|
||||
|
@ -417,5 +385,26 @@
|
|||
"descriptionBlockUnknownConnections": "If turned on, this option will automatically close connections from Cwtch users that have not been added to your contact list.",
|
||||
"descriptionExperimentsGroups": "The group experiment allows Cwtch to connect with untrusted server infrastructure to facilitate communication with more than one contact.",
|
||||
"descriptionExperiments": "Cwtch experiments are optional, opt-in features that add additional functionality to Cwtch that may have different privacy considerations than traditional 1:1 metadata resistant chat e.g. group chat, bot integration etc.",
|
||||
"tooltipUnlockProfiles": "Unlock encrypted profiles by entering their password."
|
||||
"tooltipUnlockProfiles": "Unlock encrypted profiles by entering their password.",
|
||||
"invalidImportString": "Invalid import string",
|
||||
"todoPlaceholder": "Todo...",
|
||||
"addNewItem": "Add a new item to the list",
|
||||
"addListItem": "Add a New List Item",
|
||||
"networkStatusConnecting": "Connecting to network and contacts...",
|
||||
"networkStatusAttemptingTor": "Attempting to connect to Tor network",
|
||||
"networkStatusDisconnected": "Disconnected from the internet, check your connection",
|
||||
"viewGroupMembershipTooltip": "View Group Membership",
|
||||
"loadingTor": "Loading tor...",
|
||||
"version": "Version %1",
|
||||
"versionTor": "Version %1 with tor %2",
|
||||
"experimentsEnabled": "Enable Experiments",
|
||||
"settingInterfaceZoom": "Zoom level",
|
||||
"versionBuilddate": "Version: %1 Built on: %2",
|
||||
"error0ProfilesLoadedForPassword": "0 profiles loaded with that password",
|
||||
"enterProfilePassword": "Enter a password to view your profiles",
|
||||
"deleteConfirmText": "DELETE",
|
||||
"passwordChangeError": "Error changing password: Supplied password rejected",
|
||||
"unblockBtn": "Unblock Contact",
|
||||
"savePeerHistoryDescription": "Determines whether to delete any history associated with the contact.",
|
||||
"pasteAddressToAddContact": "Paste a cwtch address, invitation or key bundle here to add a new conversation"
|
||||
}
|
|
@ -1,17 +1,6 @@
|
|||
{
|
||||
"@@locale": "lb",
|
||||
"@@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",
|
||||
"settingsThemeErrorInvalid": "Error: Could not import $themeName, theme.yml missing, not a theme directory",
|
||||
"settingThemeOverwriteQuestion": "Theme $themeName already exists, confirm overwrite?",
|
||||
"settingThemeOverwriteConfirm": "Confirm",
|
||||
"settingsThemeImagesDescription": "Enable display of images from themes",
|
||||
"settingsThemeImages": "Theme Images",
|
||||
"settingsGroupAbout": "About",
|
||||
"@@last_modified": "2023-09-25T21:29:34+02:00",
|
||||
"localeUzbek": "Uzbek \/ Oʻzbekcha",
|
||||
"profileOfflineAtStart": "Appear Offline at Startup",
|
||||
"now": "Now",
|
||||
|
|
|
@ -1,17 +1,6 @@
|
|||
{
|
||||
"@@locale": "nl",
|
||||
"@@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",
|
||||
"settingsThemeErrorInvalid": "Error: Could not import $themeName, theme.yml missing, not a theme directory",
|
||||
"settingThemeOverwriteQuestion": "Theme $themeName already exists, confirm overwrite?",
|
||||
"settingThemeOverwriteConfirm": "Confirm",
|
||||
"settingsThemeImagesDescription": "Enable display of images from themes",
|
||||
"settingsThemeImages": "Theme Images",
|
||||
"settingsGroupAbout": "About",
|
||||
"@@last_modified": "2023-09-25T21:29:34+02:00",
|
||||
"localeUzbek": "Uzbek \/ Oʻzbekcha",
|
||||
"profileOfflineAtStart": "Appear Offline at Startup",
|
||||
"now": "Now",
|
||||
|
|
|
@ -1,17 +1,6 @@
|
|||
{
|
||||
"@@locale": "no",
|
||||
"@@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",
|
||||
"settingsThemeErrorInvalid": "Error: Could not import $themeName, theme.yml missing, not a theme directory",
|
||||
"settingThemeOverwriteQuestion": "Theme $themeName already exists, confirm overwrite?",
|
||||
"settingThemeOverwriteConfirm": "Confirm",
|
||||
"settingsThemeImagesDescription": "Enable display of images from themes",
|
||||
"settingsThemeImages": "Theme Images",
|
||||
"settingsGroupAbout": "About",
|
||||
"@@last_modified": "2023-09-25T21:29:34+02:00",
|
||||
"localeUzbek": "Uzbek \/ Oʻzbekcha",
|
||||
"profileOfflineAtStart": "Appear Offline at Startup",
|
||||
"now": "Now",
|
||||
|
|
|
@ -1,17 +1,6 @@
|
|||
{
|
||||
"@@locale": "pl",
|
||||
"@@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",
|
||||
"settingsThemeErrorInvalid": "Error: Could not import $themeName, theme.yml missing, not a theme directory",
|
||||
"settingThemeOverwriteQuestion": "Theme $themeName already exists, confirm overwrite?",
|
||||
"settingThemeOverwriteConfirm": "Confirm",
|
||||
"settingsThemeImagesDescription": "Enable display of images from themes",
|
||||
"settingsThemeImages": "Theme Images",
|
||||
"settingsGroupAbout": "About",
|
||||
"@@last_modified": "2023-09-25T21:29:34+02:00",
|
||||
"localeUzbek": "Uzbek \/ Oʻzbekcha",
|
||||
"profileOfflineAtStart": "Appear Offline at Startup",
|
||||
"now": "Now",
|
||||
|
|
|
@ -1,17 +1,6 @@
|
|||
{
|
||||
"@@locale": "pt",
|
||||
"@@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",
|
||||
"settingsThemeErrorInvalid": "Error: Could not import $themeName, theme.yml missing, not a theme directory",
|
||||
"settingThemeOverwriteQuestion": "Theme $themeName already exists, confirm overwrite?",
|
||||
"settingThemeOverwriteConfirm": "Confirm",
|
||||
"settingsThemeImagesDescription": "Enable display of images from themes",
|
||||
"settingsThemeImages": "Theme Images",
|
||||
"settingsGroupAbout": "About",
|
||||
"@@last_modified": "2023-09-25T21:29:34+02:00",
|
||||
"localeUzbek": "Uzbek \/ Oʻzbekcha",
|
||||
"profileOfflineAtStart": "Appear Offline at Startup",
|
||||
"now": "Now",
|
||||
|
|
|
@ -1,17 +1,6 @@
|
|||
{
|
||||
"@@locale": "pt_BR",
|
||||
"@@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",
|
||||
"settingsThemeErrorInvalid": "Error: Could not import $themeName, theme.yml missing, not a theme directory",
|
||||
"settingThemeOverwriteQuestion": "Theme $themeName already exists, confirm overwrite?",
|
||||
"settingThemeOverwriteConfirm": "Confirm",
|
||||
"settingsThemeImagesDescription": "Enable display of images from themes",
|
||||
"settingsThemeImages": "Theme Images",
|
||||
"settingsGroupAbout": "About",
|
||||
"@@last_modified": "2023-09-25T21:29:34+02:00",
|
||||
"localeUzbek": "Uzbek \/ Oʻzbekcha",
|
||||
"profileOfflineAtStart": "Appear Offline at Startup",
|
||||
"now": "Now",
|
||||
|
|
|
@ -1,17 +1,6 @@
|
|||
{
|
||||
"@@locale": "ro",
|
||||
"@@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",
|
||||
"settingsThemeErrorInvalid": "Error: Could not import $themeName, theme.yml missing, not a theme directory",
|
||||
"settingThemeOverwriteQuestion": "Theme $themeName already exists, confirm overwrite?",
|
||||
"settingThemeOverwriteConfirm": "Confirm",
|
||||
"settingsThemeImagesDescription": "Enable display of images from themes",
|
||||
"settingsThemeImages": "Theme Images",
|
||||
"settingsGroupAbout": "About",
|
||||
"@@last_modified": "2023-09-25T21:29:34+02:00",
|
||||
"localeUzbek": "Uzbek \/ Oʻzbekcha",
|
||||
"profileOfflineAtStart": "Appear Offline at Startup",
|
||||
"now": "Now",
|
||||
|
|
|
@ -1,17 +1,6 @@
|
|||
{
|
||||
"@@locale": "ru",
|
||||
"@@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",
|
||||
"settingsThemeErrorInvalid": "Error: Could not import $themeName, theme.yml missing, not a theme directory",
|
||||
"settingThemeOverwriteQuestion": "Theme $themeName already exists, confirm overwrite?",
|
||||
"settingThemeOverwriteConfirm": "Confirm",
|
||||
"settingsThemeImagesDescription": "Enable display of images from themes",
|
||||
"settingsThemeImages": "Theme Images",
|
||||
"settingsGroupAbout": "About",
|
||||
"@@last_modified": "2023-09-25T21:29:34+02:00",
|
||||
"localeUzbek": "Uzbek \/ Oʻzbekcha",
|
||||
"profileOfflineAtStart": "Appear Offline at Startup",
|
||||
"now": "Now",
|
||||
|
|
|
@ -1,17 +1,6 @@
|
|||
{
|
||||
"@@locale": "sk",
|
||||
"@@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",
|
||||
"settingsThemeErrorInvalid": "Error: Could not import $themeName, theme.yml missing, not a theme directory",
|
||||
"settingThemeOverwriteQuestion": "Theme $themeName already exists, confirm overwrite?",
|
||||
"settingThemeOverwriteConfirm": "Confirm",
|
||||
"settingsThemeImagesDescription": "Enable display of images from themes",
|
||||
"settingsThemeImages": "Theme Images",
|
||||
"settingsGroupAbout": "About",
|
||||
"@@last_modified": "2023-09-25T21:29:34+02:00",
|
||||
"localeUzbek": "Uzbek \/ Oʻzbekcha",
|
||||
"profileOfflineAtStart": "Appear Offline at Startup",
|
||||
"now": "Now",
|
||||
|
|
|
@ -1,17 +1,6 @@
|
|||
{
|
||||
"@@locale": "sv",
|
||||
"@@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",
|
||||
"settingsThemeErrorInvalid": "Error: Could not import $themeName, theme.yml missing, not a theme directory",
|
||||
"settingThemeOverwriteQuestion": "Theme $themeName already exists, confirm overwrite?",
|
||||
"settingThemeOverwriteConfirm": "Confirm",
|
||||
"settingsThemeImagesDescription": "Enable display of images from themes",
|
||||
"settingsThemeImages": "Theme Images",
|
||||
"settingsGroupAbout": "About",
|
||||
"@@last_modified": "2023-09-25T21:29:34+02:00",
|
||||
"localeUzbek": "Uzbek \/ Oʻzbekcha",
|
||||
"profileOfflineAtStart": "Appear Offline at Startup",
|
||||
"now": "Now",
|
||||
|
|
|
@ -1,17 +1,6 @@
|
|||
{
|
||||
"@@locale": "sw",
|
||||
"@@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",
|
||||
"settingsThemeErrorInvalid": "Error: Could not import $themeName, theme.yml missing, not a theme directory",
|
||||
"settingThemeOverwriteQuestion": "Theme $themeName already exists, confirm overwrite?",
|
||||
"settingThemeOverwriteConfirm": "Confirm",
|
||||
"settingsThemeImagesDescription": "Enable display of images from themes",
|
||||
"settingsThemeImages": "Theme Images",
|
||||
"settingsGroupAbout": "About",
|
||||
"@@last_modified": "2023-09-25T21:29:34+02:00",
|
||||
"localeUzbek": "Uzbek \/ Oʻzbekcha",
|
||||
"profileOfflineAtStart": "Appear Offline at Startup",
|
||||
"now": "Now",
|
||||
|
|
|
@ -1,17 +1,6 @@
|
|||
{
|
||||
"@@locale": "tr",
|
||||
"@@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",
|
||||
"settingsThemeErrorInvalid": "Error: Could not import $themeName, theme.yml missing, not a theme directory",
|
||||
"settingThemeOverwriteQuestion": "Theme $themeName already exists, confirm overwrite?",
|
||||
"settingThemeOverwriteConfirm": "Confirm",
|
||||
"settingsThemeImagesDescription": "Enable display of images from themes",
|
||||
"settingsThemeImages": "Theme Images",
|
||||
"settingsGroupAbout": "About",
|
||||
"@@last_modified": "2023-09-25T21:29:34+02:00",
|
||||
"localeUzbek": "Uzbek \/ Oʻzbekcha",
|
||||
"profileOfflineAtStart": "Appear Offline at Startup",
|
||||
"now": "Now",
|
||||
|
|
|
@ -1,17 +1,6 @@
|
|||
{
|
||||
"@@locale": "uk",
|
||||
"@@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",
|
||||
"settingsThemeErrorInvalid": "Error: Could not import $themeName, theme.yml missing, not a theme directory",
|
||||
"settingThemeOverwriteQuestion": "Theme $themeName already exists, confirm overwrite?",
|
||||
"settingThemeOverwriteConfirm": "Confirm",
|
||||
"settingsThemeImagesDescription": "Enable display of images from themes",
|
||||
"settingsThemeImages": "Theme Images",
|
||||
"settingsGroupAbout": "About",
|
||||
"@@last_modified": "2023-09-25T21:29:34+02:00",
|
||||
"localeUzbek": "Uzbek \/ Oʻzbekcha",
|
||||
"profileOfflineAtStart": "Appear Offline at Startup",
|
||||
"now": "Now",
|
||||
|
|
|
@ -1,17 +1,6 @@
|
|||
{
|
||||
"@@locale": "uz",
|
||||
"@@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",
|
||||
"settingsThemeErrorInvalid": "Error: Could not import $themeName, theme.yml missing, not a theme directory",
|
||||
"settingThemeOverwriteQuestion": "Theme $themeName already exists, confirm overwrite?",
|
||||
"settingThemeOverwriteConfirm": "Confirm",
|
||||
"settingsThemeImagesDescription": "Enable display of images from themes",
|
||||
"settingsThemeImages": "Theme Images",
|
||||
"settingsGroupAbout": "About",
|
||||
"@@last_modified": "2023-09-25T21:29:34+02:00",
|
||||
"localeUzbek": "Uzbek \/ Oʻzbekcha",
|
||||
"profileOfflineAtStart": "Appear Offline at Startup",
|
||||
"now": "Now",
|
||||
|
|
|
@ -2,6 +2,7 @@ import 'dart:async';
|
|||
import 'dart:convert';
|
||||
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';
|
||||
|
@ -31,7 +32,9 @@ import 'themes/opaque.dart';
|
|||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
import 'package:connectivity_plus/connectivity_plus.dart';
|
||||
|
||||
var globalSettings = Settings(Locale("en", ''));
|
||||
import 'package:intl/intl.dart' as intl;
|
||||
|
||||
var globalSettings = Settings(Locale("en", ''), CwtchDark());
|
||||
var globalErrorHandler = ErrorHandler();
|
||||
var globalTorStatus = TorStatus();
|
||||
var globalAppState = AppState();
|
||||
|
@ -76,7 +79,7 @@ class FlwtchState extends State<Flwtch> with WindowListener {
|
|||
@override
|
||||
initState() {
|
||||
print("initState() started, setting up handlers");
|
||||
globalSettings = Settings(Locale("en", ''));
|
||||
globalSettings = Settings(Locale("en", ''), CwtchDark());
|
||||
globalErrorHandler = ErrorHandler();
|
||||
globalTorStatus = TorStatus();
|
||||
globalAppState = AppState();
|
||||
|
@ -103,15 +106,8 @@ class FlwtchState extends State<Flwtch> with WindowListener {
|
|||
new CwtchNotifier(profs, globalSettings, globalErrorHandler, globalTorStatus, newDesktopNotificationsManager(_notificationSelectConvo), globalAppState, globalServersList, this);
|
||||
cwtch = CwtchFfi(cwtchNotifier);
|
||||
}
|
||||
// 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: 100), () {
|
||||
print("initState delayed: invoking cwtch.Start()");
|
||||
cwtch.Start().then((v) {
|
||||
cwtch.getCwtchDir().then((dir) {
|
||||
globalSettings.themeloader.LoadThemes(dir);
|
||||
});
|
||||
});
|
||||
});
|
||||
print("initState: invoking cwtch.Start()");
|
||||
cwtch.Start();
|
||||
print("initState: starting connectivityListener");
|
||||
if (EnvironmentConfig.TEST_MODE == false) {
|
||||
startConnectivityListener();
|
||||
|
@ -127,7 +123,7 @@ class FlwtchState extends State<Flwtch> with WindowListener {
|
|||
// gracefully fails and NOPs, as it's not a required functionality
|
||||
startConnectivityListener() async {
|
||||
try {
|
||||
connectivityStream = Connectivity().onConnectivityChanged.listen((ConnectivityResult result) {
|
||||
connectivityStream = await Connectivity().onConnectivityChanged.listen((ConnectivityResult result) {
|
||||
// Got a new connectivity status!
|
||||
if (result == ConnectivityResult.none) {
|
||||
connectivityState = ConnectivityState.confirmed_offline;
|
||||
|
@ -160,7 +156,6 @@ class FlwtchState extends State<Flwtch> with WindowListener {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
globalSettings.initPackageInfo();
|
||||
|
||||
return MultiProvider(
|
||||
providers: [
|
||||
getFlwtchStateProvider(),
|
||||
|
@ -189,7 +184,7 @@ class FlwtchState extends State<Flwtch> with WindowListener {
|
|||
title: 'Cwtch',
|
||||
showSemanticsDebugger: settings.useSemanticDebugger,
|
||||
theme: mkThemeData(settings),
|
||||
home: (!appState.loaded) ? SplashView() : ProfileMgrView(),
|
||||
home: (!appState.cwtchInit || appState.modalState != ModalState.none) ? SplashView() : ProfileMgrView(),
|
||||
),
|
||||
);
|
||||
},
|
||||
|
@ -252,6 +247,7 @@ class FlwtchState extends State<Flwtch> with WindowListener {
|
|||
exit(0);
|
||||
}
|
||||
}
|
||||
;
|
||||
}
|
||||
|
||||
// Invoked via notificationClickChannel by MyBroadcastReceiver in MainActivity.kt
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import 'package:cwtch/themes/cwtch.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
@ -7,14 +8,16 @@ 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", ''));
|
||||
var globalSettings = Settings(Locale("en", ''), CwtchDark());
|
||||
var globalErrorHandler = ErrorHandler();
|
||||
|
||||
Future<void> main() async {
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:cwtch/config.dart';
|
||||
import 'package:cwtch/main.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
enum ModalState { none, storageMigration, shutdown }
|
||||
|
@ -18,8 +17,6 @@ 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;
|
||||
|
@ -35,13 +32,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();
|
||||
}
|
||||
|
||||
|
@ -88,18 +85,6 @@ 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,3 +1,5 @@
|
|||
import 'dart:ffi';
|
||||
|
||||
import 'package:cwtch/main.dart';
|
||||
import 'package:cwtch/models/message_draft.dart';
|
||||
import 'package:cwtch/models/profile.dart';
|
||||
|
@ -11,6 +13,7 @@ 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 {
|
||||
|
@ -49,8 +52,7 @@ class ContactInfoState extends ChangeNotifier {
|
|||
late String _savePeerHistory;
|
||||
late int _unreadMessages = 0;
|
||||
late int _totalMessages = 0;
|
||||
late DateTime _lastMessageReceivedTime; // last time we received a message, for sorting
|
||||
late DateTime _lastMessageSentTime; // last time a message reported being sent, for display
|
||||
late DateTime _lastMessageTime;
|
||||
late Map<String, GlobalKey<MessageRowState>> keys;
|
||||
int _newMarkerMsgIndex = -1;
|
||||
late MessageCache messageCache;
|
||||
|
@ -72,8 +74,6 @@ class ContactInfoState extends ChangeNotifier {
|
|||
DateTime _lastRetryTime = DateTime.now();
|
||||
DateTime loaded = DateTime.now();
|
||||
|
||||
List<ContactEvent> contactEvents = List.empty(growable: true);
|
||||
|
||||
ContactInfoState(
|
||||
this.profileOnion,
|
||||
this.identifier,
|
||||
|
@ -106,8 +106,7 @@ class ContactInfoState extends ChangeNotifier {
|
|||
this._totalMessages = numMessages;
|
||||
this._unreadMessages = numUnread;
|
||||
this._savePeerHistory = savePeerHistory;
|
||||
this._lastMessageReceivedTime = lastMessageTime == null ? DateTime.fromMillisecondsSinceEpoch(0) : lastMessageTime;
|
||||
this._lastMessageSentTime = _lastMessageReceivedTime;
|
||||
this._lastMessageTime = lastMessageTime == null ? DateTime.fromMillisecondsSinceEpoch(0) : lastMessageTime;
|
||||
this._server = server;
|
||||
this._archived = archived;
|
||||
this._notificationPolicy = notificationPolicyFromString(notificationPolicy);
|
||||
|
@ -197,7 +196,6 @@ class ContactInfoState extends ChangeNotifier {
|
|||
|
||||
set status(String newVal) {
|
||||
this._status = newVal;
|
||||
this.contactEvents.add(ContactEvent("Update Peer Status Received: $newVal"));
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
|
@ -258,21 +256,10 @@ class ContactInfoState extends ChangeNotifier {
|
|||
notifyListeners();
|
||||
}
|
||||
|
||||
// This is last message received time (local) and to be used for sorting only
|
||||
// for instance, group sync, we want to pop to the top, so we set to time.Now() for new messages
|
||||
// but it should not be used for display
|
||||
DateTime get lastMessageReceivedTime => this._lastMessageReceivedTime;
|
||||
DateTime get lastMessageTime => this._lastMessageTime;
|
||||
|
||||
set lastMessageReceivedTime(DateTime newVal) {
|
||||
this._lastMessageReceivedTime = newVal;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
// This is last message sent time and is based on message reports of sent times
|
||||
// this can be used to display in the contact list a last time a message was received
|
||||
DateTime get lastMessageSentTime => this._lastMessageSentTime;
|
||||
set lastMessageSentTime(DateTime newVal) {
|
||||
this._lastMessageSentTime = newVal;
|
||||
set lastMessageTime(DateTime newVal) {
|
||||
this._lastMessageTime = newVal;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
|
@ -335,8 +322,7 @@ class ContactInfoState extends ChangeNotifier {
|
|||
_newMarkerMsgIndex++;
|
||||
}
|
||||
|
||||
this._lastMessageReceivedTime = timestamp;
|
||||
this._lastMessageSentTime = timestamp;
|
||||
this._lastMessageTime = timestamp;
|
||||
this.messageCache.addNew(profileOnion, identifier, messageID, timestamp, senderHandle, senderImage, isAuto, data, contenthash);
|
||||
this.totalMessages += 1;
|
||||
|
||||
|
@ -486,11 +472,3 @@ class ContactInfoState extends ChangeNotifier {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ContactEvent {
|
||||
String summary;
|
||||
late DateTime timestamp;
|
||||
ContactEvent(this.summary) {
|
||||
this.timestamp = DateTime.now();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ class ContactListState extends ChangeNotifier {
|
|||
if (!a.isInvitation && b.isInvitation) return 1;
|
||||
|
||||
// special sorting for contacts with no messages in either history
|
||||
if (a.lastMessageReceivedTime.millisecondsSinceEpoch == 0 && b.lastMessageReceivedTime.millisecondsSinceEpoch == 0) {
|
||||
if (a.lastMessageTime.millisecondsSinceEpoch == 0 && b.lastMessageTime.millisecondsSinceEpoch == 0) {
|
||||
// online contacts first
|
||||
if (a.isOnline() && !b.isOnline()) return -1;
|
||||
if (!a.isOnline() && b.isOnline()) return 1;
|
||||
|
@ -90,27 +90,27 @@ class ContactListState extends ChangeNotifier {
|
|||
return a.onion.toString().compareTo(b.onion.toString());
|
||||
}
|
||||
// finally... most recent history first
|
||||
if (a.lastMessageReceivedTime.millisecondsSinceEpoch == 0) return 1;
|
||||
if (b.lastMessageReceivedTime.millisecondsSinceEpoch == 0) return -1;
|
||||
return b.lastMessageReceivedTime.compareTo(a.lastMessageReceivedTime);
|
||||
if (a.lastMessageTime.millisecondsSinceEpoch == 0) return 1;
|
||||
if (b.lastMessageTime.millisecondsSinceEpoch == 0) return -1;
|
||||
return b.lastMessageTime.compareTo(a.lastMessageTime);
|
||||
});
|
||||
//<todo> if(changed) {
|
||||
notifyListeners();
|
||||
//} </todo>
|
||||
}
|
||||
|
||||
void updateLastMessageReceivedTime(int forIdentifier, DateTime newMessageTime) {
|
||||
void updateLastMessageTime(int forIdentifier, DateTime newMessageTime) {
|
||||
var contact = getContact(forIdentifier);
|
||||
if (contact == null) return;
|
||||
|
||||
// Assert that the new time is after the current last message time AND that
|
||||
// new message time is before the current time.
|
||||
if (newMessageTime.isAfter(contact.lastMessageReceivedTime)) {
|
||||
if (newMessageTime.isAfter(contact.lastMessageTime)) {
|
||||
if (newMessageTime.isBefore(DateTime.now().toLocal())) {
|
||||
contact.lastMessageReceivedTime = newMessageTime;
|
||||
contact.lastMessageTime = newMessageTime;
|
||||
} else {
|
||||
// Otherwise set the last message time to now...
|
||||
contact.lastMessageReceivedTime = DateTime.now().toLocal();
|
||||
contact.lastMessageTime = DateTime.now().toLocal();
|
||||
}
|
||||
resort();
|
||||
}
|
||||
|
@ -144,7 +144,7 @@ class ContactListState extends ChangeNotifier {
|
|||
|
||||
void newMessage(int identifier, int messageID, DateTime timestamp, String senderHandle, String senderImage, bool isAuto, String data, String contenthash, bool selectedConversation) {
|
||||
getContact(identifier)?.newMessage(identifier, messageID, timestamp, senderHandle, senderImage, isAuto, data, contenthash, selectedConversation);
|
||||
updateLastMessageReceivedTime(identifier, DateTime.now());
|
||||
updateLastMessageTime(identifier, DateTime.now());
|
||||
}
|
||||
|
||||
int cacheMemUsage() {
|
||||
|
|
|
@ -3,22 +3,12 @@ class FileDownloadProgress {
|
|||
int chunksTotal = 1;
|
||||
bool complete = false;
|
||||
bool gotManifest = false;
|
||||
bool _interrupted = false;
|
||||
|
||||
// we keep track of both an explicit interrupt flag (for when a request fails or is explicitly cancelled)
|
||||
set interrupted(isInterrupted) {
|
||||
this._interrupted = isInterrupted;
|
||||
}
|
||||
|
||||
// but we have a fuzzy get which depends on lastUpdate, if the file isn't complete, but the last update was more
|
||||
// that 30 seconds ago, we consider this download as failed.
|
||||
get interrupted => _interrupted || (DateTime.now().difference(lastUpdate).abs().inSeconds > 30 && !complete);
|
||||
|
||||
bool interrupted = false;
|
||||
String? downloadedTo;
|
||||
DateTime? timeStart;
|
||||
DateTime? timeEnd;
|
||||
DateTime? requested;
|
||||
DateTime lastUpdate = DateTime.fromMillisecondsSinceEpoch(0);
|
||||
DateTime lastUpdate = DateTime.now();
|
||||
|
||||
FileDownloadProgress(this.chunksTotal, this.timeStart);
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ abstract class Message {
|
|||
|
||||
Widget getWidget(BuildContext context, Key key, int index);
|
||||
|
||||
Widget getPreviewWidget(BuildContext context, {BoxConstraints? constraints});
|
||||
Widget getPreviewWidget(BuildContext context);
|
||||
}
|
||||
|
||||
Message compileOverlay(MessageInfo messageInfo) {
|
||||
|
@ -64,7 +64,6 @@ 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 {
|
||||
|
@ -129,8 +128,7 @@ class ByIndex implements CacheHandler {
|
|||
List<dynamic> messagesWrapper = jsonDecode(msgs);
|
||||
|
||||
for (; i < messagesWrapper.length; i++) {
|
||||
var messageInfo = MessageWrapperToInfo(profileOnion, conversationIdentifier, messagesWrapper[i]);
|
||||
messageInfo.metadata.lastChecked = DateTime.now();
|
||||
var messageInfo = messageWrapperToInfo(profileOnion, conversationIdentifier, messagesWrapper[i]);
|
||||
cache.addIndexed(messageInfo, start + i);
|
||||
}
|
||||
} catch (e, stacktrace) {
|
||||
|
@ -145,13 +143,6 @@ 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 {
|
||||
|
@ -181,11 +172,6 @@ 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 {
|
||||
|
@ -214,11 +200,6 @@ 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) {
|
||||
|
@ -276,16 +257,6 @@ 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 {
|
||||
|
@ -301,14 +272,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'])!;
|
||||
|
@ -341,7 +312,6 @@ class MessageMetadata extends ChangeNotifier {
|
|||
|
||||
final String? signature;
|
||||
final String contenthash;
|
||||
DateTime? lastChecked;
|
||||
|
||||
dynamic get attributes => this._attributes;
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
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.
|
||||
|
@ -49,8 +50,6 @@ class MessageDraft extends ChangeNotifier {
|
|||
void clearDraft() {
|
||||
this._quotedReference = null;
|
||||
this.ctrlCompose.clear();
|
||||
this.ctrlCompose.clearComposing();
|
||||
this.ctrlCompose.text = "";
|
||||
this._inviteHandle = null;
|
||||
notifyListeners();
|
||||
}
|
||||
|
|
|
@ -30,27 +30,22 @@ class LocalIndexMessage {
|
|||
this.messageId = messageId;
|
||||
this.cacheOnly = cacheOnly;
|
||||
this.isLoading = isLoading;
|
||||
loader = Completer<void>();
|
||||
loaded = loader.future;
|
||||
if (!isLoading) {
|
||||
loader.complete(); // complete this
|
||||
if (isLoading) {
|
||||
loader = Completer<void>();
|
||||
loaded = loader.future;
|
||||
}
|
||||
}
|
||||
|
||||
void finishLoad(int messageId) {
|
||||
this.messageId = messageId;
|
||||
if (!loader.isCompleted) {
|
||||
isLoading = false;
|
||||
loader.complete(true);
|
||||
}
|
||||
isLoading = false;
|
||||
loader.complete(true);
|
||||
}
|
||||
|
||||
void failLoad() {
|
||||
this.messageId = null;
|
||||
if (!loader.isCompleted) {
|
||||
isLoading = false;
|
||||
loader.complete(true);
|
||||
}
|
||||
isLoading = false;
|
||||
loader.complete(true);
|
||||
}
|
||||
|
||||
Future<void> waitForLoad() {
|
||||
|
@ -100,7 +95,7 @@ class MessageCache extends ChangeNotifier {
|
|||
this._storageMessageCount = newval;
|
||||
}
|
||||
|
||||
// On android reconnect, if backend supplied message count > UI message count, add the difference to the front of the index
|
||||
// On android reconnect, if backend supplied message count > UI message count, add the differnce to the front of the index
|
||||
void addFrontIndexGap(int count) {
|
||||
this._indexUnsynced = count;
|
||||
}
|
||||
|
@ -128,9 +123,8 @@ 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 != "") {
|
||||
if (contenthash != null && contenthash != "") {
|
||||
this.cacheByHash[contenthash] = messageID;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,27 +49,24 @@ class FileMessage extends Message {
|
|||
}
|
||||
|
||||
@override
|
||||
Widget getPreviewWidget(BuildContext context, {BoxConstraints? constraints}) {
|
||||
Widget getPreviewWidget(BuildContext context) {
|
||||
return ChangeNotifierProvider.value(
|
||||
value: this.metadata,
|
||||
builder: (bcontext, child) {
|
||||
dynamic shareObj = jsonDecode(this.content);
|
||||
if (shareObj == null) {
|
||||
return MalformedBubble();
|
||||
return MessageRow(MalformedBubble(), 0);
|
||||
}
|
||||
String nameSuggestion = shareObj['f'] as String;
|
||||
String rootHash = shareObj['h'] as String;
|
||||
String nonce = shareObj['n'] as String;
|
||||
int fileSize = shareObj['s'] as int;
|
||||
if (!validHash(rootHash, nonce)) {
|
||||
return MalformedBubble();
|
||||
return MessageRow(MalformedBubble(), 0);
|
||||
}
|
||||
return Container(
|
||||
padding: EdgeInsets.all(1.0),
|
||||
decoration: BoxDecoration(),
|
||||
clipBehavior: Clip.antiAliasWithSaveLayer,
|
||||
constraints: BoxConstraints(minHeight: 50, maxHeight: 50, minWidth: 50, maxWidth: 300),
|
||||
alignment: Alignment.centerLeft,
|
||||
alignment: Alignment.center,
|
||||
height: 100,
|
||||
child: FileBubble(
|
||||
nameSuggestion,
|
||||
rootHash,
|
||||
|
|
|
@ -48,7 +48,7 @@ class InviteMessage extends Message {
|
|||
}
|
||||
|
||||
@override
|
||||
Widget getPreviewWidget(BuildContext context, {BoxConstraints? constraints}) {
|
||||
Widget getPreviewWidget(BuildContext context) {
|
||||
return ChangeNotifierProvider.value(
|
||||
value: this.metadata,
|
||||
builder: (bcontext, child) {
|
||||
|
|
|
@ -18,7 +18,7 @@ class MalformedMessage extends Message {
|
|||
}
|
||||
|
||||
@override
|
||||
Widget getPreviewWidget(BuildContext context, {BoxConstraints? constraints}) {
|
||||
Widget getPreviewWidget(BuildContext context) {
|
||||
return ChangeNotifierProvider.value(
|
||||
value: this.metadata,
|
||||
builder: (bcontext, child) {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
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';
|
||||
|
@ -10,6 +11,7 @@ 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;
|
||||
|
@ -28,7 +30,7 @@ class QuotedMessage extends Message {
|
|||
QuotedMessage(this.metadata, this.content);
|
||||
|
||||
@override
|
||||
Widget getPreviewWidget(BuildContext context, {BoxConstraints? constraints}) {
|
||||
Widget getPreviewWidget(BuildContext context) {
|
||||
return ChangeNotifierProvider.value(
|
||||
value: this.metadata,
|
||||
builder: (bcontext, child) {
|
||||
|
@ -38,7 +40,7 @@ class QuotedMessage extends Message {
|
|||
);
|
||||
var content = message["body"];
|
||||
var formatMessages = Provider.of<Settings>(bcontext).isExperimentEnabled(FormattingExperiment);
|
||||
return compileMessageContentWidget(context, constraints ?? BoxConstraints.loose(MediaQuery.sizeOf(context)), false, content, FocusNode(), formatMessages, false);
|
||||
return compileMessageContentWidget(context, false, content, FocusNode(), formatMessages, false);
|
||||
} catch (e) {
|
||||
return MalformedBubble();
|
||||
}
|
||||
|
|
|
@ -1,11 +1,17 @@
|
|||
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 {
|
||||
|
@ -15,12 +21,13 @@ class TextMessage extends Message {
|
|||
TextMessage(this.metadata, this.content);
|
||||
|
||||
@override
|
||||
Widget getPreviewWidget(BuildContext context, {BoxConstraints? constraints}) {
|
||||
Widget getPreviewWidget(BuildContext context) {
|
||||
return ChangeNotifierProvider.value(
|
||||
value: this.metadata,
|
||||
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);
|
||||
return compileMessageContentWidget(context, false, content, FocusNode(), formatMessages, false);
|
||||
;
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:cwtch/config.dart';
|
||||
import 'package:cwtch/models/remoteserver.dart';
|
||||
|
@ -14,6 +13,8 @@ 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 {
|
||||
|
@ -35,7 +36,6 @@ class ProfileInfoState extends ChangeNotifier {
|
|||
bool _autostart = true;
|
||||
bool _enabled = false;
|
||||
bool _appearOffline = false;
|
||||
bool _appearOfflineAtStartup = false;
|
||||
|
||||
ProfileInfoState({
|
||||
required this.onion,
|
||||
|
@ -62,7 +62,6 @@ class ProfileInfoState extends ChangeNotifier {
|
|||
this._enabled = true;
|
||||
}
|
||||
this._appearOffline = appearOffline;
|
||||
this._appearOfflineAtStartup = appearOffline;
|
||||
this._encrypted = encrypted;
|
||||
|
||||
_contacts.connectServers(this._servers);
|
||||
|
@ -95,7 +94,7 @@ class ProfileInfoState extends ChangeNotifier {
|
|||
|
||||
// dummy set to invoke sort-on-load
|
||||
if (this._contacts.num > 0) {
|
||||
this._contacts.updateLastMessageReceivedTime(this._contacts.contacts.first.identifier, this._contacts.contacts.first.lastMessageReceivedTime);
|
||||
this._contacts.updateLastMessageTime(this._contacts.contacts.first.identifier, this._contacts.contacts.first.lastMessageTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -186,12 +185,6 @@ class ProfileInfoState extends ChangeNotifier {
|
|||
notifyListeners();
|
||||
}
|
||||
|
||||
bool get appearOfflineAtStartup => this._appearOfflineAtStartup;
|
||||
set appearOfflineAtStartup(bool newVal) {
|
||||
this._appearOfflineAtStartup = newVal;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
bool get appearOffline => this._appearOffline;
|
||||
set appearOffline(bool newVal) {
|
||||
this._appearOffline = newVal;
|
||||
|
@ -239,7 +232,7 @@ class ProfileInfoState extends ChangeNotifier {
|
|||
this._unreadMessages = 0;
|
||||
this.replaceServers(serverJson);
|
||||
|
||||
if (contactsJson != "" && contactsJson != "null") {
|
||||
if (contactsJson != null && contactsJson != "" && contactsJson != "null") {
|
||||
List<dynamic> contacts = jsonDecode(contactsJson);
|
||||
contacts.forEach((contact) {
|
||||
var profileContact = this._contacts.getContact(contact["identifier"]);
|
||||
|
@ -247,27 +240,13 @@ class ProfileInfoState extends ChangeNotifier {
|
|||
if (profileContact != null) {
|
||||
profileContact.status = contact["status"];
|
||||
|
||||
var newCount = contact["numMessages"] as int;
|
||||
var newCount = contact["numMessages"];
|
||||
if (newCount != profileContact.totalMessages) {
|
||||
if (newCount < profileContact.totalMessages) {
|
||||
// on Android, when sharing a file the UI may be briefly unloaded for the
|
||||
// OS to display the file management/selection screen. Afterwards a
|
||||
// call to ReconnectCwtchForeground will be made which will refresh all values (including count of numMessages)
|
||||
// **at the same time** the foreground will increment .totalMessages and send a new message to the backend.
|
||||
// This will result in a negative number of messages being calculated here, and an incorrect totalMessage count.
|
||||
// This bug is exacerbated in debug mode, and when multiple files are sent in succession. Both cases result in multiple ReconnectCwtchForeground
|
||||
// events that have the potential to conflict with currentMessageCounts.
|
||||
// Note that *if* a new message came in at the same time, we would be unable to distinguish this case - as such this is specific instance of a more general problem
|
||||
// TODO: A true-fix to this bug is to implement a syncing step in the foreground where totalMessages and inFlightMessages can be distinguished
|
||||
// This requires a change to the backend to confirm submission of an inFlightMessage, which will be implemented in #664
|
||||
EnvironmentConfig.debugLog("Conflicting message counts: $newCount ${profileContact.totalMessages}");
|
||||
newCount = max(newCount, profileContact.totalMessages);
|
||||
}
|
||||
profileContact.messageCache.addFrontIndexGap(newCount - profileContact.totalMessages);
|
||||
}
|
||||
profileContact.totalMessages = newCount;
|
||||
profileContact.unreadMessages = contact["numUnread"];
|
||||
profileContact.lastMessageReceivedTime = DateTime.fromMillisecondsSinceEpoch(1000 * int.parse(contact["lastMsgTime"]));
|
||||
profileContact.lastMessageTime = DateTime.fromMillisecondsSinceEpoch(1000 * int.parse(contact["lastMsgTime"]));
|
||||
} else {
|
||||
this._contacts.add(ContactInfoState(
|
||||
this.onion,
|
||||
|
@ -381,6 +360,19 @@ class ProfileInfoState extends ChangeNotifier {
|
|||
if (this._downloads[fileKey]!.interrupted) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (this._downloads[fileKey]!.requested != null) {
|
||||
if (DateTime.now().difference(this._downloads[fileKey]!.requested!) > Duration(minutes: 1)) {
|
||||
this._downloads[fileKey]!.requested = null;
|
||||
this._downloads[fileKey]!.interrupted = true;
|
||||
return true;
|
||||
}
|
||||
if (DateTime.now().difference(this._downloads[fileKey]!.lastUpdate) > Duration(minutes: 1)) {
|
||||
this._downloads[fileKey]!.requested = null;
|
||||
this._downloads[fileKey]!.interrupted = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|