Merge pull request 'dep-upgrades-3.10.0' (#673) from dep-upgrades-3.10.0 into trunk
continuous-integration/drone/push Build is passing Details

Reviewed-on: #673
This commit is contained in:
Sarah Jamie Lewis 2023-06-02 20:31:25 +00:00
commit 59c5004153
85 changed files with 1965 additions and 672 deletions

View File

@ -8,7 +8,7 @@ clone:
steps:
- name: clone
image: openpriv/flutter-desktop:linux-fstable-3.7.1
image: openpriv/flutter-desktop:linux-fstable-3.10.2
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.7.1
image: openpriv/flutter-desktop:linux-fstable-3.10.2
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.7.1
image: openpriv/flutter-desktop:linux-fstable-3.10.2
volumes:
- name: deps
path: /root/.pub-cache
@ -61,7 +61,7 @@ steps:
- rm -r cwtch
- name: linux-ui-tests
image: openpriv/flutter-desktop:linux-fstable-3.7.1
image: openpriv/flutter-desktop:linux-fstable-3.10.2
volumes:
- name: deps
path: /root/.pub-cache
@ -70,7 +70,7 @@ steps:
- ./run-tests-headless.sh "01_general|02_global_settings|04_profile_mgmt"
- name: test-build-android
image: openpriv/flutter-desktop:linux-fstable-3.7.1
image: openpriv/flutter-desktop:linux-fstable-3.10.2
when:
event: pull_request
volumes:
@ -80,7 +80,7 @@ steps:
- flutter build apk --debug
- name: build-android
image: openpriv/flutter-desktop:linux-fstable-3.7.1
image: openpriv/flutter-desktop:linux-fstable-3.10.2
when:
event: push
environment:
@ -104,7 +104,7 @@ steps:
#- cp build/app/outputs/flutter-apk/app-debug.apk deploy/android
- name: widget-tests
image: openpriv/flutter-desktop:linux-fstable-3.7.1
image: openpriv/flutter-desktop:linux-fstable-3.10.2
volumes:
- name: deps
path: /root/.pub-cache
@ -177,7 +177,7 @@ clone:
steps:
- name: clone
image: openpriv/flutter-desktop:windows-sdk30-fstable-3.7.1
image: openpriv/flutter-desktop:windows-sdk30-fstable-3.10.2
environment:
buildbot_key_b64:
from_secret: buildbot_key_b64
@ -195,7 +195,7 @@ steps:
- git checkout $Env:DRONE_COMMIT
- name: fetch
image: openpriv/flutter-desktop:windows-sdk30-fstable-3.7.1
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
@ -203,7 +203,7 @@ steps:
- .\fetch-libcwtch-go.ps1
- name: build-windows
image: openpriv/flutter-desktop:windows-sdk30-fstable-3.7.1
image: openpriv/flutter-desktop:windows-sdk30-fstable-3.10.2
commands:
- flutter pub get
- $Env:version += type .\VERSION
@ -214,9 +214,9 @@ steps:
# flutter hasn't worked out it's packaging of required dll's so we have to resort to this manual nonsense
# https://github.com/google/flutter-desktop-embedding/issues/587
# https://github.com/flutter/flutter/issues/53167
- copy C:\BuildTools\VC\Redist\MSVC\14.29.30133\x64\Microsoft.VC142.CRT\vcruntime140.dll $Env:releasedir
- copy C:\BuildTools\VC\Redist\MSVC\14.29.30133\x64\Microsoft.VC142.CRT\vcruntime140_1.dll $Env:releasedir
- copy C:\BuildTools\VC\Redist\MSVC\14.29.30133\x64\Microsoft.VC142.CRT\msvcp140.dll $Env:releasedir
- copy 'C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Redist\MSVC\14.36.32532\x64\Microsoft.VC143.CRT\vcruntime140.dll' $Env:releasedir
- copy 'C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Redist\MSVC\14.36.32532\x64\Microsoft.VC143.CRT\vcruntime140_1.dll' $Env:releasedir
- copy 'C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Redist\MSVC\14.36.32532\x64\Microsoft.VC143.CRT\msvcp140.dll' $Env:releasedir
- copy README.md $Env:releasedir\
- copy windows\*.bat $Env:releasedir\
- powershell -command "Expand-Archive -Path tor.zip -DestinationPath $Env:releasedir\Tor"
@ -260,7 +260,7 @@ steps:
- move *.sha512.txt deploy\$Env:builddir
- name: deploy-windows
image: openpriv/flutter-desktop:windows-sdk30-fstable-3.7.1
image: openpriv/flutter-desktop:windows-sdk30-fstable-3.10.2
when:
event: push
status: [ success ]

1
.gitignore vendored
View File

@ -13,6 +13,7 @@ package-lock.json
libCwtch*
cwtch.aar
node_modules
test_home
# IntelliJ related
*.iml

View File

@ -1,10 +1,30 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.
# This file should be version controlled.
version:
revision: 78910062997c3a836feee883712c241a5fd22983
revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf
channel: stable
project_type: app
# Tracks metadata for the flutter migrate command
migration:
platforms:
- platform: root
create_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf
base_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf
- platform: macos
create_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf
base_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf
# User provided section
# List of Local paths (relative to this file) that should be
# ignored by the migrate tool.
#
# Files that are not part of the templates will be ignored by default.
unmanaged_files:
- 'lib/main.dart'
- 'ios/Runner.xcodeproj/project.pbxproj'

View File

@ -1 +1 @@
2023-05-09-13-30-v0.0.3-24-g5b2f3cf
2023-05-16-16-25-v0.0.4

View File

@ -64,10 +64,14 @@ To build a release version and load normal profiles, use `build-release.sh X` in
### Building on MacOS
- Cocaopods is required, you may need to `gem install cocaopods -v 1.9.3`
- copy `libCwtch.x64.dylib` and `libCwtch.arm/dylib` into the root folder, or run `fetch-libcwtch-go-macos.sh` to download it
- Cocoapods is required. Mac and Ruby don't seem to care about version stability and compatibility so good luck. The version of Ruby Mac seems to ship is very incompatible with software in the gem repo. You will probablly need to manually specify a specific older version of cocoapods that is compatible with your system. First you will also probably need to make sure you are on the latest MacOS version and then try `gem install cocoapods -v 1.x.x`
- For MacOS 13.4 `gem install cocoapods -v 1.11.3` worked on 2023.05.28
- copy `libCwtch.x64.dylib` and `libCwtch.arm.dylib` into the root folder, or run `fetch-libcwtch-go-macos.sh` to download it
- The error 'Podfile not found' has still been seen on fresh repos, depending on varios versions. To fix run `flutter create --platforms=macos . --org im.cwtch`
- You may have to temporarily rename the project folder a "dart project suitable name" like "cwtch"
- run `fetch-tor-macos.sh` to fetch Tor or Download and install Tor Browser and `cp -r /Applications/Tor\ Browser.app/Contents/MacOS/Tor ./macos/`
- `flutter build macos`
- If you are building on Mac Arm Silicon you may need to append `--no-tree-shake-icons` as the build seems to invoke a mac x64 binary that Arm Mac "cannot verify" and therefor will not run on some versions of Flutter
- optional: launch cwtch-ui release build with `./build/macos/Build/Products/Release/Cwtch.app/Contents/MacOS/Cwtch`
- To package the UI: `./macos/package-release.sh`, which results in a Cwtch.dmg that has libCwtch.dylib and tor in it as well and can be installed into Applications

View File

@ -53,7 +53,7 @@ android {
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "im.cwtch.flwtch"
minSdkVersion 16
minSdkVersion 19
targetSdkVersion 31
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName

View File

@ -84,6 +84,7 @@ class FlwtchWorker(context: Context, parameters: WorkerParameters) :
Log.i(TAG, "startCwtch success, starting coroutine AppbusEvent loop...")
val downloadIDs = mutableMapOf<String, Int>()
val downloadFinishedIDs = mutableMapOf<String, Int>()
var flags = PendingIntent.FLAG_UPDATE_CURRENT
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
flags = flags or PendingIntent.FLAG_IMMUTABLE
@ -167,32 +168,36 @@ class FlwtchWorker(context: Context, parameters: WorkerParameters) :
val title = data.getString("NameSuggestion");
val progress = data.getString("Progress").toInt();
val progressMax = data.getString("FileSizeInChunks").toInt();
if (!downloadIDs.containsKey(fileKey)) {
downloadIDs.put(fileKey, downloadIDs.count());
}
var dlID = downloadIDs.get(fileKey);
if (dlID == null) {
dlID = 0;
}
if (progress >= 0) {
val channelId =
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
createDownloadNotificationChannel(fileKey, fileKey)
} else {
// If earlier version channel ID is not used
// https://developer.android.com/reference/android/support/v4/app/NotificationCompat.Builder.html#NotificationCompat.Builder(android.content.Context)
""
};
val newNotification = NotificationCompat.Builder(applicationContext, channelId)
.setOngoing(true)
.setContentTitle("Downloading")//todo: translate
.setContentText(title)
.setSmallIcon(android.R.drawable.stat_sys_download)
.setProgress(progressMax, progress, false)
.setSound(null)
//.setSilent(true)
.build();
notificationManager.notify(dlID, newNotification);
// if we have seen a download finished update for this key then ignore it
if (!downloadFinishedIDs.containsKey(fileKey)) {
if (!downloadIDs.containsKey(fileKey)) {
downloadIDs.put(fileKey, downloadIDs.count());
}
var dlID = downloadIDs.get(fileKey);
if (dlID == null) {
dlID = 0;
}
if (progress >= 0) {
val channelId =
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
createDownloadNotificationChannel(fileKey, fileKey)
} else {
// If earlier version channel ID is not used
// https://developer.android.com/reference/android/support/v4/app/NotificationCompat.Builder.html#NotificationCompat.Builder(android.content.Context)
""
};
val newNotification = NotificationCompat.Builder(applicationContext, channelId)
.setOngoing(true)
.setContentTitle("Downloading")//todo: translate
.setContentText(title)
.setSmallIcon(android.R.drawable.stat_sys_download)
.setProgress(progressMax, progress, false)
.setSound(null)
//.setSilent(true)
.build();
notificationManager.notify(dlID, newNotification);
}
}
} catch (e: Exception) {
Log.d("FlwtchWorker->FileDownloadProgressUpdate", e.toString() + " :: " + e.getStackTrace());
@ -216,6 +221,8 @@ class FlwtchWorker(context: Context, parameters: WorkerParameters) :
Files.delete(sourcePath);
}
}
// Suppress future notifications...
downloadFinishedIDs.put(fileKey, downloadIDs.count());
if (downloadIDs.containsKey(fileKey)) {
notificationManager.cancel(downloadIDs.get(fileKey) ?: 0);
}

View File

@ -360,8 +360,7 @@ class MainActivity: FlutterActivity() {
"PeerWithOnion" -> {
val profile: String = call.argument("ProfileOnion") ?: ""
val onion: String = call.argument("onion") ?: ""
result.success(Cwtch.peerWithOnion(profile, onion))
return
Cwtch.peerWithOnion(profile, onion)
}
@ -493,14 +492,17 @@ class MainActivity: FlutterActivity() {
}
"GetProfileAttribute" -> {
val profile: String = call.argument("ProfileOnion") ?: ""
val key: String = call.argument("Key") ?: ""
Data.Builder().putString("result", Cwtch.getProfileAttribute(profile, key)).build()
val key: String = call.argument("key") ?: ""
var resultjson = Cwtch.getProfileAttribute(profile, key);
return result.success(resultjson)
}
"GetConversationAttribute" -> {
val profile: String = call.argument("ProfileOnion") ?: ""
val conversation: Int = call.argument("conversation") ?: 0
val key: String = call.argument("Key") ?: ""
Data.Builder().putString("result", Cwtch.getConversationAttribute(profile, conversation.toLong(), key)).build()
val key: String = call.argument("key") ?: ""
var resultjson = Cwtch.getConversationAttribute(profile, conversation.toLong(), key);
result.success(resultjson)
return
}
"SetConversationAttribute" -> {
val profile: String = call.argument("ProfileOnion") ?: ""
@ -512,7 +514,8 @@ class MainActivity: FlutterActivity() {
"ImportProfile" -> {
val file: String = call.argument("file") ?: ""
val pass: String = call.argument("pass") ?: ""
Data.Builder().putString("result", Cwtch.importProfile(file, pass)).build()
result.success(Cwtch.importProfile(file, pass))
return
}
"ReconnectCwtchForeground" -> {
Cwtch.reconnectCwtchForeground()

View File

@ -1,5 +1,5 @@
buildscript {
ext.kotlin_version = '1.6.21'
ext.kotlin_version = '1.8.21'
repositories {
google()
// jCenter() no longer exists... https://blog.gradle.org/jcenter-shutdown
@ -7,7 +7,7 @@ buildscript {
}
dependencies {
classpath 'com.android.tools.build:gradle:4.1.0'
classpath 'com.android.tools.build:gradle:7.0.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}

View File

@ -2,7 +2,7 @@
distributionBase=GRADLE_USER_HOME
# third party plugin connectivity_plus should match, so when updating, also update
# lib/third_party/connectivity_plus/connectivity_plus/android/gradle/wrapper/gradle-wrapper.properties
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-all.zip
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME

View File

@ -1 +1,2 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Generated.xcconfig"

View File

@ -1 +1,2 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Generated.xcconfig"

View File

@ -1,16 +1,20 @@
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:url_launcher/url_launcher.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:provider/provider.dart';
import 'package:url_launcher/url_launcher_string.dart';
import '../settings.dart';
void modalOpenLink(BuildContext ctx, LinkableElement link) {
showModalBottomSheet<void>(
context: ctx,
builder: (BuildContext bcontext) {
return Container(
height: 200, // bespoke value courtesy of the [TextField] docs
height: 200,
child: Center(
child: Padding(
padding: EdgeInsets.all(30.0),
@ -18,17 +22,24 @@ void modalOpenLink(BuildContext ctx, LinkableElement link) {
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text(AppLocalizations.of(bcontext)!.clickableLinksWarning),
Text(
AppLocalizations.of(bcontext)!.clickableLinksWarning,
style: Provider.of<Settings>(bcontext).scaleFonts(defaultTextStyle),
),
Flex(direction: Axis.horizontal, mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[
Container(
margin: EdgeInsets.symmetric(vertical: 20, horizontal: 10),
child: ElevatedButton(
child: Text(AppLocalizations.of(bcontext)!.clickableLinksCopy, semanticsLabel: AppLocalizations.of(bcontext)!.clickableLinksCopy),
child: Text(AppLocalizations.of(bcontext)!.clickableLinksCopy,
style: Provider.of<Settings>(bcontext).scaleFonts(defaultTextButtonStyle), semanticsLabel: AppLocalizations.of(bcontext)!.clickableLinksCopy),
onPressed: () {
Clipboard.setData(new ClipboardData(text: link.url));
final snackBar = SnackBar(
content: Text(AppLocalizations.of(bcontext)!.copiedToClipboardNotification),
content: Text(
AppLocalizations.of(bcontext)!.copiedToClipboardNotification,
style: Provider.of<Settings>(bcontext).scaleFonts(defaultTextButtonStyle),
),
);
Navigator.pop(bcontext);
@ -39,15 +50,14 @@ void modalOpenLink(BuildContext ctx, LinkableElement link) {
Container(
margin: EdgeInsets.symmetric(vertical: 20, horizontal: 10),
child: ElevatedButton(
child: Text(AppLocalizations.of(bcontext)!.clickableLinkOpen, semanticsLabel: AppLocalizations.of(bcontext)!.clickableLinkOpen),
child: Text(AppLocalizations.of(bcontext)!.clickableLinkOpen,
style: Provider.of<Settings>(bcontext).scaleFonts(defaultTextButtonStyle), semanticsLabel: AppLocalizations.of(bcontext)!.clickableLinkOpen),
onPressed: () async {
if (await canLaunch(link.url)) {
await launch(link.url);
if (await canLaunchUrlString(link.url)) {
await launchUrlString(link.url);
Navigator.pop(bcontext);
} else {
final snackBar = SnackBar(
content: Text(AppLocalizations.of(bcontext)!.clickableLinkError),
);
final snackBar = SnackBar(content: Text(AppLocalizations.of(bcontext)!.clickableLinkError, style: Provider.of<Settings>(bcontext).scaleFonts(defaultTextButtonStyle)));
ScaffoldMessenger.of(bcontext).showSnackBar(snackBar);
}
},

View File

@ -97,11 +97,11 @@ abstract class Cwtch {
Future<dynamic> ImportBundle(String profile, String bundle);
// ignore: non_constant_identifier_names
void SetProfileAttribute(String profile, String key, String val);
String? GetProfileAttribute(String profile, String key);
Future<String?> GetProfileAttribute(String profile, String key);
// ignore: non_constant_identifier_names
void SetConversationAttribute(String profile, int conversation, String key, String val);
// ignore: non_constant_identifier_names
String? GetConversationAttribute(String profile, int identifier, String s);
Future<String?> GetConversationAttribute(String profile, int identifier, String s);
// ignore: non_constant_identifier_names
void SetMessageAttribute(String profile, int conversation, int channel, int message, String key, String val);
// ignore: non_constant_identifier_names

View File

@ -68,25 +68,24 @@ class CwtchNotifier {
appState.SetAppError(data["Error"]);
break;
case "NewPeer":
// empty events can be caused by the testing framework
if (data["Online"] == null) {
break;
}
// EnvironmentConfig.debugLog("NewPeer $data");
// if tag != v1-defaultPassword then it is either encrypted OR it is an unencrypted account created during pre-beta...
profileCN.add(data["Identity"], data["name"], data["picture"], data["defaultPicture"], data["ContactsJson"], data["ServerList"], data["Online"] == "true", data["autostart"] == "true",
data["tag"] != "v1-defaultPassword");
// Update Profile Attributes
profileCN.getProfile(data["Identity"])?.setAttribute(0, flwtchState.cwtch.GetProfileAttribute(data["Identity"], "profile.profile-attribute-1"));
profileCN.getProfile(data["Identity"])?.setAttribute(1, flwtchState.cwtch.GetProfileAttribute(data["Identity"], "profile.profile-attribute-2"));
profileCN.getProfile(data["Identity"])?.setAttribute(2, flwtchState.cwtch.GetProfileAttribute(data["Identity"], "profile.profile-attribute-3"));
profileCN.getProfile(data["Identity"])?.setAvailabilityStatus(flwtchState.cwtch.GetProfileAttribute(data["Identity"], "profile.profile-status") ?? "");
EnvironmentConfig.debugLog("Looking up Profile Attributes ${data["Identity"]} ${profileCN.getProfile(data["Identity"])}");
flwtchState.cwtch.GetProfileAttribute(data["Identity"], "profile.profile-attribute-1").then((value) => profileCN.getProfile(data["Identity"])?.setAttribute(0, value));
flwtchState.cwtch.GetProfileAttribute(data["Identity"], "profile.profile-attribute-2").then((value) => profileCN.getProfile(data["Identity"])?.setAttribute(1, value));
flwtchState.cwtch.GetProfileAttribute(data["Identity"], "profile.profile-attribute-3").then((value) => profileCN.getProfile(data["Identity"])?.setAttribute(2, value));
flwtchState.cwtch.GetProfileAttribute(data["Identity"], "profile.profile-status").then((value) => profileCN.getProfile(data["Identity"])?.setAvailabilityStatus(value ?? ""));
EnvironmentConfig.debugLog("Looking up Profile Information for Contact...");
profileCN.getProfile(data["Identity"])?.contactList.contacts.forEach((contact) {
contact.setAttribute(0, flwtchState.cwtch.GetConversationAttribute(data["Identity"], contact.identifier, "public.profile.profile-attribute-1"));
contact.setAttribute(1, flwtchState.cwtch.GetConversationAttribute(data["Identity"], contact.identifier, "public.profile.profile-attribute-2"));
contact.setAttribute(2, flwtchState.cwtch.GetConversationAttribute(data["Identity"], contact.identifier, "public.profile.profile-attribute-3"));
contact.setAvailabilityStatus(flwtchState.cwtch.GetConversationAttribute(data["Identity"], contact.identifier, "public.profile.profile-status") ?? "");
flwtchState.cwtch.GetConversationAttribute(data["Identity"], contact.identifier, "public.profile.profile-attribute-1").then((value) => contact.setAttribute(0, value));
flwtchState.cwtch.GetConversationAttribute(data["Identity"], contact.identifier, "public.profile.profile-attribute-2").then((value) => contact.setAttribute(1, value));
flwtchState.cwtch.GetConversationAttribute(data["Identity"], contact.identifier, "public.profile.profile-attribute-3").then((value) => contact.setAttribute(2, value));
flwtchState.cwtch.GetConversationAttribute(data["Identity"], contact.identifier, "public.profile.profile-status").then((value) => contact.setAvailabilityStatus(value ?? ""));
});
break;
@ -392,6 +391,7 @@ class CwtchNotifier {
String fileKey = data['Data'];
var contact = profileCN.getProfile(data["ProfileOnion"])?.contactList.findContact(data["RemotePeer"]);
if (contact != null) {
EnvironmentConfig.debugLog("waiting for download from $contact");
profileCN.getProfile(data["ProfileOnion"])?.waitForDownloadComplete(contact.identifier, fileKey);
}
} else if (data['Path'] == "profile.profile-attribute-1" || data['Path'] == "profile.profile-attribute-2" || data['Path'] == "profile.profile-attribute-3") {

View File

@ -967,7 +967,7 @@ class CwtchFfi implements Cwtch {
}
@override
String? GetProfileAttribute(String profile, String key) {
Future<String?> GetProfileAttribute(String profile, String key) {
var getProfileAttributeC = library.lookup<NativeFunction<get_json_blob_from_str_str_function>>("c_GetProfileAttribute");
// ignore: non_constant_identifier_names
final GetProfileAttribute = getProfileAttributeC.asFunction<GetJsonBlobFromStrStrFn>();
@ -982,17 +982,17 @@ class CwtchFfi implements Cwtch {
try {
dynamic attributeResult = json.decode(jsonMessage);
if (attributeResult["Exists"]) {
return attributeResult["Value"];
return Future.value(attributeResult["Value"]);
}
} catch (e) {
EnvironmentConfig.debugLog("error getting profile attribute: $e");
}
return null;
return Future.value(null);
}
@override
String? GetConversationAttribute(String profile, int conversation, String key) {
Future<String?> GetConversationAttribute(String profile, int conversation, String key) {
var getConversationAttributeC = library.lookup<NativeFunction<get_json_blob_from_str_int_string_function>>("c_GetConversationAttribute");
// ignore: non_constant_identifier_names
final GetConversationAttribute = getConversationAttributeC.asFunction<GetJsonBlobFromStrIntStringFn>();
@ -1007,13 +1007,13 @@ class CwtchFfi implements Cwtch {
try {
dynamic attributeResult = json.decode(jsonMessage);
if (attributeResult["Exists"]) {
return attributeResult["Value"];
return Future.value(attributeResult["Value"]);
}
} catch (e) {
EnvironmentConfig.debugLog("error getting profile attribute: $e");
}
return null;
return Future.value(null);
}
@override

View File

@ -390,21 +390,25 @@ class CwtchGomobile implements Cwtch {
}
@override
String? GetProfileAttribute(String profile, String key) {
dynamic attributeResult = cwtchPlatform.invokeMethod("GetProfileAttribute", {"ProfileOnion": profile, "key": key});
if (attributeResult["Exists"]) {
return attributeResult["Value"];
}
return null;
Future<String?> GetProfileAttribute(String profile, String key) async {
return await cwtchPlatform.invokeMethod("GetProfileAttribute", {"ProfileOnion": profile, "key": key}).then((dynamic json) {
var value = jsonDecode(json);
if (value["Exists"]) {
return value["Value"];
}
return null;
});
}
@override
String? GetConversationAttribute(String profile, int conversation, String key) {
dynamic attributeResult = cwtchPlatform.invokeMethod("GetProfileAttribute", {"ProfileOnion": profile, "conversation": conversation, "key": key});
if (attributeResult["Exists"]) {
return attributeResult["Value"];
}
return null;
Future<String?> GetConversationAttribute(String profile, int conversation, String key) async {
return await cwtchPlatform.invokeMethod("GetConversationAttribute", {"ProfileOnion": profile, "conversation": conversation, "key": key}).then((dynamic json) {
var value = jsonDecode(json);
if (value["Exists"]) {
return value["Value"];
}
return null;
});
}
@override

View File

@ -622,4 +622,26 @@ class MaterialLocalizationLu extends MaterialLocalizations {
@override
// TODO: implement menuBarMenuLabel
String get menuBarMenuLabel => throw UnimplementedError();
@override
// TODO: implement bottomSheetLabel
String get bottomSheetLabel => throw UnimplementedError();
@override
// TODO: implement currentDateLabel
String get currentDateLabel => throw UnimplementedError();
@override
// TODO: implement keyboardKeyShift
String get keyboardKeyShift => throw UnimplementedError();
@override
// TODO: implement scrimLabel
String get scrimLabel => throw UnimplementedError();
@override
String scrimOnTapHint(String modalRouteContentName) {
// TODO: implement scrimOnTapHint
throw UnimplementedError();
}
}

View File

@ -1,6 +1,10 @@
{
"@@locale": "cy",
"@@last_modified": "2023-05-15T21:16:36+02:00",
"@@last_modified": "2023-05-29T14:05:23+02:00",
"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": "Testun maint rhagosodedig (ffactor graddfa:",
"localeJa": "Japanese \/ 日本語",
@ -23,7 +27,6 @@
"blodeuweddExperimentEnable": "Blodeuwedd Assistant",
"localeKo": "Korean \/ 한국어",
"localeSk": "Slovak \/ Slovák",
"profileEnabledDescription": "Start or stop the profile",
"profileAutostartDescription": "Controls if the profile will be automatically launched on startup",
"profileEnabled": "Enable",
"profileAutostartLabel": "Autostart",

View File

@ -1,6 +1,10 @@
{
"@@locale": "da",
"@@last_modified": "2023-05-15T21:16:36+02:00",
"@@last_modified": "2023-05-29T14:05:23+02:00",
"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": "Standard størrelse tekst (skaleringsfaktor:",
"localeJa": "Japanese \/ 日本語",
@ -23,7 +27,6 @@
"blodeuweddExperimentEnable": "Blodeuwedd Assistant",
"localeKo": "Korean \/ 한국어",
"localeSk": "Slovak \/ Slovák",
"profileEnabledDescription": "Start or stop the profile",
"profileAutostartDescription": "Controls if the profile will be automatically launched on startup",
"profileEnabled": "Enable",
"profileAutostartLabel": "Autostart",

View File

@ -1,6 +1,10 @@
{
"@@locale": "de",
"@@last_modified": "2023-05-15T21:16:36+02:00",
"@@last_modified": "2023-05-29T14:05:23+02:00",
"localeUk": "Ukrainian \/ українською",
"profileEnabledDescription": "Starten oder Stoppen des Profils",
"localeSw": "Swahili \/ Kiswahili",
"localeSv": "Swedish \/ Svenska",
"fontScalingDescription": "Adjust the relative font scaling factor applied to text and widgets.",
"defaultScalingText": "Text in Standardgröße (Skalierungsfaktor:",
"localeJa": "Japanese \/ 日本語",
@ -26,7 +30,6 @@
"profileAutostartLabel": "Autostart",
"profileEnabled": "Aktivieren",
"profileAutostartDescription": "Legt fest, ob das Profil beim Starten automatisch gestartet wird",
"profileEnabledDescription": "Starten oder Stoppen des Profils",
"acquiringTicketsFromServer": "Antispam-Herausforderung meistern",
"acquiredTicketsFromServer": "Antispam-Herausforderung abgeschlossen",
"shareProfileMenuTooltop": "Profil teilen über...",

View File

@ -1,6 +1,10 @@
{
"@@locale": "el",
"@@last_modified": "2023-05-15T21:16:36+02:00",
"@@last_modified": "2023-05-29T14:05:23+02:00",
"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": "Font Scaling",
"localeJa": "Japanese \/ 日本語",
@ -23,7 +27,6 @@
"blodeuweddExperimentEnable": "Blodeuwedd Assistant",
"localeKo": "Korean \/ 한국어",
"localeSk": "Slovak \/ Slovák",
"profileEnabledDescription": "Start or stop the profile",
"profileAutostartDescription": "Controls if the profile will be automatically launched on startup",
"profileEnabled": "Enable",
"profileAutostartLabel": "Autostart",

View File

@ -1,6 +1,10 @@
{
"@@locale": "en",
"@@last_modified": "2023-05-15T21:16:36+02:00",
"@@last_modified": "2023-05-29T14:05:23+02:00",
"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": "Font Scaling",
"localeJa": "Japanese \/ 日本語",
@ -23,7 +27,6 @@
"blodeuweddExperimentEnable": "Blodeuwedd Assistant",
"localeKo": "Korean \/ 한국어",
"localeSk": "Slovak \/ Slovák",
"profileEnabledDescription": "Start or stop the profile",
"profileAutostartDescription": "Controls if the profile will be automatically launched on startup",
"profileEnabled": "Enable",
"profileAutostartLabel": "Autostart",

View File

@ -1,6 +1,10 @@
{
"@@locale": "es",
"@@last_modified": "2023-05-15T21:16:36+02:00",
"@@last_modified": "2023-05-29T14:05:23+02:00",
"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 \/ 日本語",
@ -23,7 +27,6 @@
"blodeuweddExperimentEnable": "Blodeuwedd Assistant",
"localeKo": "Korean \/ 한국어",
"localeSk": "Slovak \/ Slovák",
"profileEnabledDescription": "Start or stop the profile",
"profileAutostartDescription": "Controls if the profile will be automatically launched on startup",
"profileEnabled": "Enable",
"profileAutostartLabel": "Autostart",

View File

@ -1,6 +1,10 @@
{
"@@locale": "fr",
"@@last_modified": "2023-05-15T21:16:36+02:00",
"@@last_modified": "2023-05-29T14:05:23+02:00",
"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": "Taille par défaut du texte (échelle:",
"localeJa": "Japanese \/ 日本語",
@ -23,7 +27,6 @@
"blodeuweddExperimentEnable": "Blodeuwedd Assistant",
"localeKo": "Korean \/ 한국어",
"localeSk": "Slovak \/ Slovák",
"profileEnabledDescription": "Start or stop the profile",
"profileAutostartDescription": "Controls if the profile will be automatically launched on startup",
"profileEnabled": "Enable",
"profileAutostartLabel": "Autostart",

View File

@ -1,6 +1,10 @@
{
"@@locale": "it",
"@@last_modified": "2023-05-15T21:16:36+02:00",
"@@last_modified": "2023-05-29T14:05:23+02:00",
"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": "Testo di dimensioni predefinite (fattore di scala:",
"localeJa": "Japanese \/ 日本語",
@ -23,7 +27,6 @@
"blodeuweddExperimentEnable": "Blodeuwedd Assistant",
"localeKo": "Korean \/ 한국어",
"localeSk": "Slovak \/ Slovák",
"profileEnabledDescription": "Start or stop the profile",
"profileAutostartDescription": "Controls if the profile will be automatically launched on startup",
"profileEnabled": "Enable",
"profileAutostartLabel": "Autostart",

View File

@ -1,6 +1,10 @@
{
"@@locale": "ja",
"@@last_modified": "2023-05-15T21:16:36+02:00",
"@@last_modified": "2023-05-29T14:05:23+02:00",
"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": "Font Scaling",
"localeJa": "Japanese \/ 日本語",
@ -64,7 +68,6 @@
"profileInfoHint": "ブログ、ウェブサイト、簡単な経歴など、ご自身に関する公開情報をここに追加してください。",
"localeKo": "Korean \/ 한국어",
"localeSk": "Slovak \/ Slovák",
"profileEnabledDescription": "Start or stop the profile",
"profileEnabled": "Enable",
"localeNl": "Dutch \/ Dutch",
"experimentQRCodeDescription": "QR Code support allows sharing data (such as profile identity) by QR Codes",

View File

@ -1,6 +1,10 @@
{
"@@locale": "ko",
"@@last_modified": "2023-05-15T21:16:36+02:00",
"@@last_modified": "2023-05-29T14:05:23+02:00",
"localeUk": "Ukrainian \/ українською",
"profileEnabledDescription": "프로필 시각 또는 중지",
"localeSw": "Swahili \/ Kiswahili",
"localeSv": "Swedish \/ Svenska",
"fontScalingDescription": "Adjust the relative font scaling factor applied to text and widgets.",
"defaultScalingText": "Font Scaling",
"localeJa": "Japanese \/ 日本語",
@ -124,7 +128,6 @@
"profileAutostartDescription": "시작 시 프로필이 자동으로 시작되는지 여부를 제어합니다.",
"profileAutostartLabel": "자동 시작",
"profileEnabled": "허락",
"profileEnabledDescription": "프로필 시각 또는 중지",
"replyingTo": "%1에 회신",
"tooltipCode": "Code \/ Monospace",
"tooltipStrikethrough": "Strikethrough",

View File

@ -1,6 +1,10 @@
{
"@@locale": "lb",
"@@last_modified": "2023-05-15T21:16:36+02:00",
"@@last_modified": "2023-05-29T14:05:23+02:00",
"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": "Font Scaling",
"localeJa": "Japanese \/ 日本語",
@ -23,7 +27,6 @@
"blodeuweddExperimentEnable": "Blodeuwedd Assistant",
"localeKo": "Korean \/ 한국어",
"localeSk": "Slovak \/ Slovák",
"profileEnabledDescription": "Start or stop the profile",
"profileAutostartDescription": "Controls if the profile will be automatically launched on startup",
"profileEnabled": "Enable",
"profileAutostartLabel": "Autostart",

View File

@ -1,6 +1,10 @@
{
"@@locale": "nl",
"@@last_modified": "2023-05-15T21:16:36+02:00",
"@@last_modified": "2023-05-29T14:05:23+02:00",
"localeUk": "Ukrainian \/ українською",
"profileEnabledDescription": "Start of stop het profiel",
"localeSw": "Swahili \/ Kiswahili",
"localeSv": "Swedish \/ Svenska",
"fontScalingDescription": "Adjust the relative font scaling factor applied to text and widgets.",
"defaultScalingText": "Standaardtekstgrootte (schaalfactor:",
"localeJa": "Japanese \/ 日本語",
@ -25,7 +29,6 @@
"profileAutostartDescription": "Regelt of het profiel automatisch wordt gestart bij het opstarten",
"profileAutostartLabel": "Automatisch starten",
"profileEnabled": "Inschakelen",
"profileEnabledDescription": "Start of stop het profiel",
"localeSk": "Slowaaks \/ Slovák",
"localePtBr": "Braziliaans Portugees \/ Português do Brasil",
"acquiredTicketsFromServer": "Anti-spam uitdaging voltooid",

View File

@ -1,6 +1,10 @@
{
"@@locale": "no",
"@@last_modified": "2023-05-15T21:16:36+02:00",
"@@last_modified": "2023-05-29T14:05:23+02:00",
"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": "Standard tekststørrelse (skaleringsfaktor:",
"localeJa": "Japanese \/ 日本語",
@ -23,7 +27,6 @@
"blodeuweddExperimentEnable": "Blodeuwedd Assistant",
"localeKo": "Korean \/ 한국어",
"localeSk": "Slovak \/ Slovák",
"profileEnabledDescription": "Start or stop the profile",
"profileAutostartDescription": "Controls if the profile will be automatically launched on startup",
"profileEnabled": "Enable",
"profileAutostartLabel": "Autostart",

View File

@ -1,6 +1,10 @@
{
"@@locale": "pl",
"@@last_modified": "2023-05-15T21:16:36+02:00",
"@@last_modified": "2023-05-29T14:05:23+02:00",
"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": "Domyślny rozmiar tekstu (skalowanie:",
"localeJa": "Japanese \/ 日本語",
@ -23,7 +27,6 @@
"blodeuweddExperimentEnable": "Blodeuwedd Assistant",
"localeKo": "Korean \/ 한국어",
"localeSk": "Slovak \/ Slovák",
"profileEnabledDescription": "Start or stop the profile",
"profileAutostartDescription": "Controls if the profile will be automatically launched on startup",
"profileEnabled": "Enable",
"profileAutostartLabel": "Autostart",

View File

@ -1,6 +1,10 @@
{
"@@locale": "pt",
"@@last_modified": "2023-05-15T21:16:36+02:00",
"@@last_modified": "2023-05-29T14:05:23+02:00",
"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": "Texto tamanho padrão (fator de escala: ",
"localeJa": "Japanese \/ 日本語",
@ -23,7 +27,6 @@
"blodeuweddExperimentEnable": "Blodeuwedd Assistant",
"localeKo": "Korean \/ 한국어",
"localeSk": "Slovak \/ Slovák",
"profileEnabledDescription": "Start or stop the profile",
"profileAutostartDescription": "Controls if the profile will be automatically launched on startup",
"profileEnabled": "Enable",
"profileAutostartLabel": "Autostart",

View File

@ -1,6 +1,10 @@
{
"@@locale": "pt_BR",
"@@last_modified": "2023-05-15T21:16:36+02:00",
"@@last_modified": "2023-05-29T14:05:23+02:00",
"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": "Texto tamanho padrão (fator de escala: ",
"localeJa": "Japanese \/ 日本語",
@ -23,7 +27,6 @@
"blodeuweddExperimentEnable": "Blodeuwedd Assistant",
"localeKo": "Korean \/ 한국어",
"localeSk": "Slovak \/ Slovák",
"profileEnabledDescription": "Start or stop the profile",
"profileAutostartDescription": "Controls if the profile will be automatically launched on startup",
"profileEnabled": "Enable",
"profileAutostartLabel": "Autostart",

View File

@ -1,6 +1,10 @@
{
"@@locale": "ro",
"@@last_modified": "2023-05-15T21:16:36+02:00",
"@@last_modified": "2023-05-29T14:05:23+02:00",
"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": "Dimensiunea implicită a textului (factor de scară:",
"localeJa": "Japanese \/ 日本語",
@ -23,7 +27,6 @@
"blodeuweddExperimentEnable": "Blodeuwedd Assistant",
"localeKo": "Korean \/ 한국어",
"localeSk": "Slovak \/ Slovák",
"profileEnabledDescription": "Start or stop the profile",
"profileAutostartDescription": "Controls if the profile will be automatically launched on startup",
"profileEnabled": "Enable",
"profileAutostartLabel": "Autostart",

View File

@ -1,6 +1,10 @@
{
"@@locale": "ru",
"@@last_modified": "2023-05-15T21:16:36+02:00",
"@@last_modified": "2023-05-29T14:05:23+02:00",
"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": "Размер текста по умолчанию (коэффициент масштабирования:",
"localeJa": "Japanese \/ 日本語",
@ -23,7 +27,6 @@
"blodeuweddExperimentEnable": "Blodeuwedd Assistant",
"localeKo": "Korean \/ 한국어",
"localeSk": "Slovak \/ Slovák",
"profileEnabledDescription": "Start or stop the profile",
"profileAutostartDescription": "Controls if the profile will be automatically launched on startup",
"profileEnabled": "Enable",
"profileAutostartLabel": "Autostart",

View File

@ -1,6 +1,10 @@
{
"@@locale": "sk",
"@@last_modified": "2023-05-15T21:16:36+02:00",
"@@last_modified": "2023-05-29T14:05:23+02:00",
"localeUk": "Ukrainian \/ українською",
"profileEnabledDescription": "Spustiť alebo zastaviť profil",
"localeSw": "Swahili \/ Kiswahili",
"localeSv": "Swedish \/ Svenska",
"fontScalingDescription": "Adjust the relative font scaling factor applied to text and widgets.",
"defaultScalingText": "Predvolená veľkosť textu (mierka):",
"localeJa": "Japanese \/ 日本語",
@ -383,6 +387,5 @@
"createGroupBtn": " Vytvoriť",
"defaultGroupName": "Úžasná Skupina",
"createGroupTitle": "Vytvoriť Skupinu",
"profileEnabled": "Povoliť",
"profileEnabledDescription": "Spustiť alebo zastaviť profil"
"profileEnabled": "Povoliť"
}

391
lib/l10n/intl_sv.arb Normal file
View File

@ -0,0 +1,391 @@
{
"@@locale": "sv",
"@@last_modified": "2023-05-29T14:05:23+02:00",
"localeUk": "Ukrainska \/ українською",
"profileEnabledDescription": "Aktivera eller inaktivera profilen",
"localeSw": "Swahili \/ Kiswahili",
"createGroupTitle": "Skapa grupp",
"serverLabel": "Server",
"defaultGroupName": "Fantastisk grupp",
"createGroupBtn": "Skapa",
"profileOnionLabel": "Skicka den här adressen till personer du vill ansluta till",
"addPeerTab": "Lägg till en kontakt",
"createGroupTab": "Skapa en grupp",
"joinGroupTab": "Gå med i en grupp",
"peerAddress": "Adress",
"peerName": "Namn",
"server": "Server",
"invitation": "Inbjudan",
"groupAddr": "Adress",
"addPeer": "Lägg till kontakt",
"createGroup": "Skapa grupp",
"joinGroup": "Gå med i grupp",
"newBulletinLabel": "Ny rapport",
"postNewBulletinLabel": "Lägg upp ny rapport",
"titlePlaceholder": "titel...",
"pasteAddressToAddContact": "Klistra in en cwtch-adress, inbjudan eller nyckelpaket här för att lägga till en ny konversation",
"blocked": "Blockerad",
"search": "Sök...",
"invitationLabel": "Inbjudan",
"serverInfo": "Server info",
"serverConnectivityConnected": "Server ansluten",
"serverConnectivityDisconnected": "Server frånkopplad",
"serverSynced": "Synkroniserad",
"serverNotSynced": "Synkroniserar nya meddelanden (det kan ta lite tid)...",
"viewServerInfo": "Server info",
"groupNameLabel": "Gruppens namn",
"saveBtn": "Spara",
"inviteToGroupLabel": "Bjud in till grupp",
"inviteBtn": "Bjud in",
"deleteBtn": "Ta bort",
"update": "Uppdatera",
"searchList": "Söklista",
"peerNotOnline": "Kontakten är offline. Program kan inte användas just nu.",
"addListItemBtn": "Lägg till",
"membershipDescription": "Nedan finns en lista över användare som har skickat meddelanden till gruppen. Den kanske inte innehåller alla användare som har åtkomst till gruppen dock.",
"dmTooltip": "Klicka för DM",
"couldNotSendMsgError": "Det gick inte att skicka detta meddelande",
"acknowledgedLabel": "Bekräftad",
"pendingLabel": "Väntar",
"peerBlockedMessage": "Kontakten är blockerad",
"peerOfflineMessage": "Kontakten är offline, meddelanden kan inte levereras just nu",
"copyBtn": "Kopiera",
"newGroupBtn": "Skapa ny grupp",
"acceptGroupInviteLabel": "Vill du acceptera inbjudan till",
"acceptGroupBtn": "Acceptera",
"rejectGroupBtn": "Avvisa",
"chatBtn": "Chatt",
"bulletinsBtn": "Rapporter",
"listsBtn": "Listor",
"puzzleGameBtn": "Pussel",
"addressLabel": "Adress",
"copiedToClipboardNotification": "Kopierat till urklipp",
"displayNameLabel": "Visningsnamn",
"blockBtn": "Blockera kontakt",
"savePeerHistory": "Spara historik",
"savePeerHistoryDescription": "Avgör om historik som är kopplad till kontakten ska tas bort.",
"dontSavePeerHistory": "Rensa historik",
"unblockBtn": "Avblockera kontakt",
"editProfileTitle": "Redigera profil",
"addProfileTitle": "Lägg till en ny profil",
"profileName": "Visningsnamn",
"defaultProfileName": "Alice",
"newProfile": "Ny profil",
"editProfile": "Redigera profil",
"radioUsePassword": "Lösenord",
"radioNoPassword": "Okrypterad (inget lösenord)",
"noPasswordWarning": "Att inte använda ett lösenord på detta konto innebär att all data som lagras lokalt är okrypterat",
"yourDisplayName": "Ditt visningsnamn",
"currentPasswordLabel": "Nuvarande lösenord",
"password1Label": "Lösenord",
"password2Label": "Ange lösenordet på nytt",
"passwordErrorEmpty": "Lösenordet kan inte vara tomt",
"createProfileBtn": "Skapa profil",
"saveProfileBtn": "Spara profil",
"passwordErrorMatch": "Lösenorden matchar inte",
"passwordChangeError": "Fel vid ändring av lösenord: Det angivna lösenordet avvisades",
"deleteProfileBtn": "Ta bort profil",
"deleteConfirmLabel": "Skriv DELETE för att bekräfta",
"deleteProfileConfirmBtn": "Ta bort profilen",
"deleteConfirmText": "TA BORT",
"addNewProfileBtn": "Lägg till en ny profil",
"enterProfilePassword": "Ange ett lösenord för att se dina profiler",
"password": "Lösenord",
"error0ProfilesLoadedForPassword": "0 profiler laddade med det lösenordet",
"yourProfiles": "Dina profiler",
"yourServers": "Dina servrar",
"unlock": "Lås upp",
"cwtchSettingsTitle": "Cwtch-inställningar",
"versionBuilddate": "Version: %1 Byggd: %2",
"zoomLabel": "Gränssnittszoom (påverkar främst storleken på text och knappar)",
"blockUnknownLabel": "Blockera okända kontakter",
"settingLanguage": "Språk",
"localeEn": "Engelska \/ English",
"localeFr": "Franska \/ Français",
"localePt": "Portugisiska \/ Portuguesa",
"localeDe": "Tyska \/ Deutsch",
"settingInterfaceZoom": "Zoomnivå",
"largeTextLabel": "Stor",
"settingTheme": "Använd ljusa teman",
"themeLight": "Ljust",
"themeDark": "Mörkt",
"experimentsEnabled": "Aktivera experimentella funktioner",
"versionTor": "Version %1 med tor %2",
"version": "Version %1",
"builddate": "Byggt: %2",
"defaultScalingText": "Teckensnittsskalning",
"smallTextLabel": "Liten",
"loadingTor": "Laddar tor...",
"viewGroupMembershipTooltip": "Visa gruppmedlemskap",
"networkStatusDisconnected": "Frånkopplad från internet, kontrollera din anslutning",
"networkStatusAttemptingTor": "Försöker ansluta till Tor-nätverket",
"networkStatusConnecting": "Ansluter till nätverk och kontakter...",
"networkStatusOnline": "Uppkopplad",
"newConnectionPaneTitle": "Ny anslutning",
"addListItem": "Lägg till ett nytt listobjekt",
"addNewItem": "Lägg till ett nytt objekt i listan",
"todoPlaceholder": "Att göra...",
"localeEs": "Spanska \/ Español",
"localeIt": "Italienska \/ Italiano",
"enableGroups": "Aktivera gruppchatt",
"enterCurrentPasswordForDelete": "Ange aktuellt lösenord för att ta bort den här profilen.",
"conversationSettings": "Konversationsinställningar",
"invalidImportString": "Ogiltig importsträng",
"contactAlreadyExists": "Kontakten finns redan",
"tooltipOpenSettings": "Öppna inställningsfönstret",
"tooltipAddContact": "Lägg till en ny kontakt eller konversation",
"titleManageContacts": "Konversationer",
"tooltipUnlockProfiles": "Lås upp krypterade profiler genom att ange deras lösenord.",
"titleManageProfiles": "Hantera Cwtch-profiler",
"descriptionExperiments": "Cwtch experimentella funktioner är frivilliga. De utökar funktionaliteten av Cwtch med t.ex. gruppchatt eller integration av botar vilket försämrar säkerhet och integritet jämfört med traditionell 1:1 metadataresistent chatt.",
"descriptionExperimentsGroups": "Grupper tillåter Cwtch att ansluta till opålitlig serverinfrastruktur för att möjliggöra kommunikation med mer än en kontakt.",
"descriptionBlockUnknownConnections": "Om det här alternativet är aktiverat stängs automatiskt anslutningar från Cwtch-användare som inte finns i din kontaktlista.",
"successfullAddedContact": "Har lagts till ",
"titleManageServers": "Hantera servrar",
"inviteToGroup": "Du har blivit inbjuden att gå med i en grupp:",
"leaveConversation": "Lämna denna konversation",
"reallyLeaveThisGroupPrompt": "Är du säker på att du vill lämna den här konversationen? Alla meddelanden och attribut kommer att raderas.",
"yesLeave": "Ja, lämna denna konversation",
"newPassword": "Nytt lösenord",
"chatHistoryDefault": "Den här konversationen kommer att raderas när Cwtch stängs! Meddelandehistorik kan aktiveras per konversation via menyn Inställningar uppe till höger.",
"accepted": "Accepterad!",
"rejected": "Avvisad!",
"contactSuggestion": "Detta är ett kontaktförslag för:",
"sendAnInvitation": "Du skickade en inbjudan till:",
"torStatus": "Tor-status",
"torVersion": "Tor-version",
"resetTor": "Återställ",
"cancel": "Avbryt",
"sendMessage": "Skicka meddelande",
"sendInvite": "Skicka en kontakt- eller gruppinbjudan",
"deleteProfileSuccess": "Profilen har tagits bort",
"addServerFirst": "Du måste lägga till en server innan du kan skapa en grupp",
"nickChangeSuccess": "Profilens smeknamn har ändrats",
"createProfileToBegin": "Skapa eller lås upp en profil för att börja",
"addContactFirst": "Lägg till eller välj en kontakt för att börja chatta.",
"torNetworkStatus": "Tor nätverksstatus",
"debugLog": "Aktivera debug-logg",
"profileDeleteSuccess": "Profilen har tagits bort",
"malformedMessage": "Felaktigt meddelande",
"shutdownCwtchTooltip": "Stäng ner Cwtch",
"shutdownCwtchDialog": "Är du säker på att du vill stänga ner Cwtch? Detta kommer att stänga alla anslutningar och avsluta programmet.",
"shutdownCwtchAction": "Stäng ner Cwtch",
"shutdownCwtchDialogTitle": "Stänga ner Cwtch?",
"groupInviteSettingsWarning": "Du har blivit inbjuden att gå med i en grupp! Aktivera gruppchatt i Inställningar för att se denna inbjudan.",
"tooltipShowPassword": "Visa lösenord",
"tooltipHidePassword": "Dölj lösenordet",
"notificationNewMessageFromPeer": "Nytt meddelande från en kontakt!",
"notificationNewMessageFromGroup": "Nytt meddelande i en grupp!",
"tooltipAcceptContactRequest": "Acceptera kontaktförfrågan.",
"tooltipReplyToThisMessage": "Svara på meddelande",
"tooltipRejectContactRequest": "Neka kontaktförfrågan",
"tooltipRemoveThisQuotedMessage": "Ta bort citerat meddelande.",
"localePl": "Polska \/ Polski",
"settingUIColumnPortrait": "UI-kolumner i stående läge",
"settingUIColumnOptionSame": "Samma som stående läge",
"settingUIColumnLandscape": "UI-kolumner i liggande läge",
"settingUIColumnSingle": "Enkel",
"settingUIColumnDouble12Ratio": "Dubbel (1:2)",
"settingUIColumnDouble14Ratio": "Dubbel (1:4)",
"contactGoto": "Gå till konversation med %1",
"addContact": "Lägg till kontakt",
"addContactConfirm": "Lägg till kontakt %1",
"encryptedProfileDescription": "Genom att kryptera en profil med ett lösenord skyddas den från andra personer som också kan använda den här enheten. Krypterade profiler kan inte dekrypteras, visas eller nås förrän rätt lösenord har angetts för att låsa upp dem.",
"plainProfileDescription": "Vi rekommenderar att du skyddar dina Cwtch-profiler med ett lösenord. Om du inte anger ett lösenord för den här profilen kan alla som har åtkomst till den här enheten komma åt information om den här profilen, inklusive kontakter, meddelanden och känsliga kryptografiska nycklar.",
"placeholderEnterMessage": "Skriv ett meddelande...",
"blockedMessageMessage": "Det här meddelandet kommer från en profil som du har blockerat.",
"showMessageButton": "Visa meddelande",
"blockUnknownConnectionsEnabledDescription": "Anslutningar från okända kontakter blockeras. Du kan ändra detta i Inställningar",
"archiveConversation": "Arkivera denna konversation",
"streamerModeLabel": "Streaming\/presentationsläge",
"descriptionStreamerMode": "Aktivera för att dölja privat information (exempelvis profil och kontaktadresser) vilket kan vara lämpligt vid streaming eller presentation.",
"retrievingManifestMessage": "Hämtar filinformation...",
"openFolderButton": "Öppna mapp",
"downloadFileButton": "Ladda ner",
"labelFilename": "Filnamn",
"labelFilesize": "Storlek",
"messageEnableFileSharing": "Aktivera fildelning för att kunna se meddelandet.",
"messageFileSent": "Du skickade en fil",
"messageFileOffered": "Kontakten försöker skicka en fil till dig",
"tooltipSendFile": "Skicka fil",
"settingFileSharing": "Fildelning",
"descriptionFileSharing": "Fildelning gör att du kan skicka och ta emot filer från Cwtch-kontakter och grupper. Observera att om du delar en fil med en grupp kommer medlemmarna i den gruppen behöva ansluta direkt till dig med Cwtch för att kunna ladda ner filen.",
"titleManageProfilesShort": "Profiler",
"addServerTitle": "Lägg till server",
"editServerTitle": "Redigera server",
"serverAddress": "Serveradress",
"serverDescriptionLabel": "Serverbeskrivning",
"serverDescriptionDescription": "Din beskrivning av servern. Endast synligt för dig, kommer aldrig att delas",
"serverEnabled": "Server startad",
"serverEnabledDescription": "Starta eller stoppa servern",
"serverAutostartLabel": "Autostart",
"serverAutostartDescription": "Styr om programmet automatiskt startar servern vid start",
"saveServerButton": "Spara server",
"serversManagerTitleLong": "Servrar du är värd för",
"serversManagerTitleShort": "Servrar",
"addServerTooltip": "Lägg till server",
"unlockServerTip": "Skapa eller lås upp en server för att börja!",
"unlockProfileTip": "Skapa eller lås upp en profil för att börja!",
"enterServerPassword": "Ange lösenord för att låsa upp servern",
"settingServers": "Server-värd",
"settingServersDescription": "Server-värd gör det möjligt att vara värd för och hantera Cwtch-servrar",
"copyAddress": "Kopiera adress",
"enterCurrentPasswordForDeleteServer": "Ange lösenord för att radera den här servern",
"deleteServerSuccess": "Servern har tagits bort",
"deleteServerConfirmBtn": "Bekräfta borttagning av servern",
"plainServerDescription": "Vi rekommenderar att du skyddar dina Cwtch-servrar med ett lösenord. Om du inte anger ett lösenord på den här servern kan alla som har åtkomst till den här enheten komma åt information om den här servern, inklusive känsliga kryptografiska nycklar.",
"encryptedServerDescription": "Genom att kryptera en server med ett lösenord skyddas den från andra personer som också kan använda den här enheten. Krypterade servrar kan inte dekrypteras, visas eller nås förrän rätt lösenord har angetts för att låsa upp dem.",
"fileSavedTo": "Sparad till",
"fileInterrupted": "Avbruten",
"fileCheckingStatus": "Kontrollera status för nedladdning",
"verfiyResumeButton": "Verifiera\/återuppta",
"copyServerKeys": "Kopiera nycklar",
"localeRU": "Ryska \/ Русский",
"newMessagesLabel": "Nya meddelanden",
"importLocalServerLabel": "Importera en lokal server",
"importLocalServerSelectText": "Välj lokal server",
"importLocalServerButton": "Importera %1",
"groupsOnThisServerLabel": "Grupper jag är med i på den här servern",
"fieldDescriptionLabel": "Beskrivning",
"manageKnownServersButton": "Hantera kända servrar",
"displayNameTooltip": "Ange ett visningsnamn",
"manageKnownServersLong": "Hantera kända servrar",
"manageKnownServersShort": "Servrar",
"serverMetricsLabel": "Serverinfo",
"serverTotalMessagesLabel": "Antal meddelanden",
"serverConnectionsLabel": "Anslutningar",
"enableExperimentClickableLinks": "Aktivera klickbara länkar",
"experimentClickableLinksDescription": "Med klickbara länkar aktiverat kan du klicka på webbadresser som delas i meddelanden",
"settingImagePreviews": "Förhandsgranskningar av bilder och profilbilder",
"settingImagePreviewsDescription": "Bilder och profilbilder kommer att laddas ner och förhandsgranskas automatiskt. Vi rekommenderar att du inte aktiverar detta om du använder Cwtch med opålitliga kontakter.",
"settingDownloadFolder": "Hämtade filer",
"themeNameCwtch": "Cwtch",
"themeNameWitch": "Häxa",
"themeNameVampire": "Vampyr",
"themeNameGhost": "Spöke",
"themeNamePumpkin": "Pumpa",
"themeNameMermaid": "Sjöjungfru",
"themeNameMidnight": "Midnatt",
"themeNameNeon1": "Neon1",
"themeNameNeon2": "Neon2",
"themeColorLabel": "Färgtema",
"loadingCwtch": "Laddar Cwtch...",
"storageMigrationModalMessage": "Migrerar profiler till nytt lagringsformat. Detta kan ta några minuter...",
"msgFileTooBig": "Filstorleken får inte överstiga 10 GB",
"msgConfirmSend": "Är du säker på att du vill skicka",
"btnSendFile": "Skicka fil",
"msgAddToAccept": "Lägg till det här kontot i dina kontakter för att acceptera den här filen.",
"torSettingsEnabledAdvanced": "Aktivera avancerad Tor-konfiguration",
"torSettingsEnabledAdvancedDescription": "Använd en befintlig Tor-tjänst på ditt system, eller ändra parametrarna för Cwtch Tor-tjänst",
"torSettingsCustomSocksPort": "Anpassad SOCKS-port",
"torSettingsCustomSocksPortDescription": "Använd en anpassad port för dataanslutningar till Tor-proxyn",
"torSettingsCustomControlPort": "Anpassad kontrollport",
"torSettingsCustomControlPortDescription": "Använd en anpassad port för kontrollanslutningar till Tor-proxyn",
"torSettingsUseCustomTorServiceConfiguration": "Använd en anpassad konfiguration av Tor (torrc)",
"torSettingsUseCustomTorServiceConfigurastionDescription": "Åsidosätt standard-konfigurationen för Tor. Varning: Detta kan vara farligt. Använd bara om du vet vad du gör.",
"torSettingsErrorSettingPort": "Portnumret måste vara mellan 1 och 65535",
"fileSharingSettingsDownloadFolderDescription": "När filer laddas ned automatiskt (t.ex. bildfiler, när förhandsgranskning är aktiverat) behövs en standardplats att ladda ner filerna till.",
"fileSharingSettingsDownloadFolderTooltip": "Bläddra för att välja en annan standardmapp för nedladdade filer.",
"descriptionACNCircuitInfo": "Detaljerad information om den väg som det anonyma kommunikationsnätverket använder för att ansluta till den här konversationen.",
"labelACNCircuitInfo": "Info om ACN-vägen",
"labelTorNetwork": "Tor-nätverket",
"torSettingsEnableCache": "Lagra konsensus i cache",
"torSettingsEnabledCacheDescription": "Lagra nedladdad Tor-konsensus i cache för att återanvända nästa gång Cwtch öppnas. Detta gör att Tor kan starta snabbare. Om detta är inaktiverat kommer Cwtch rensa cache vid uppstart.",
"tooltipSelectACustomProfileImage": "Välj en anpassad profilbild",
"notificationPolicyOptIn": "Välj",
"notificationPolicyMute": "Tysta",
"conversationNotificationPolicyOptIn": "Välj",
"notificationPolicyDefaultAll": "Återställ standard",
"conversationNotificationPolicyDefault": "Standard",
"conversationNotificationPolicyNever": "Aldrig",
"notificationPolicySettingLabel": "Aviseringspolicy",
"notificationContentSettingLabel": "Aviseringsinnehåll",
"notificationPolicySettingDescription": "Styr programmets standardaviseringsbeteende",
"notificationContentSettingDescription": "Styr innehållet i konversationsaviseringar",
"settingGroupBehaviour": "Beteende",
"settingsGroupAppearance": "Utseende",
"settingsGroupExperiments": "Experiment",
"conversationNotificationPolicySettingLabel": "Policy för konversationsaviseringar",
"conversationNotificationPolicySettingDescription": "Ändra aviseringar för den här konversationen",
"notificationContentSimpleEvent": "Enkel händelse",
"notificationContentContactInfo": "Info om konversation",
"newMessageNotificationSimple": "Nytt meddelande",
"newMessageNotificationConversationInfo": "Nytt meddelande från %1",
"localeRo": "Rumänska \/ Română",
"localeLb": "Luxemburgiska \/ Lëtzebuergesch",
"localeNo": "Norska \/ Norsk",
"localeEl": "Grekiska \/ Ελληνικά",
"localeCy": "Walesiska \/ Cymraeg",
"localeDa": "Danska \/ Dansk",
"exportProfile": "Exportera profil",
"exportProfileTooltip": "Säkerhetskopiera den här profilen till en krypterad fil. Den krypterade filen kan importeras till en annan Cwtch-app.",
"importProfileTooltip": "Använd en krypterad Cwtch-säkerhetskopia för att importera en profil skapad i en annan instans av Cwtch.",
"importProfile": "Importera profil",
"failedToImportProfile": "Fel vid import av profil",
"successfullyImportedProfile": "Profilen har importerats: %profile",
"shuttingDownApp": "Stänger ner...",
"clickableLinksWarning": "Om du öppnar den här webbadressen startar en applikation utanför Cwtch som kan avslöja metadata eller på annat sätt äventyra säkerheten för Cwtch. Öppna bara webbadresser från personer du litar på. Är du säker på att du vill fortsätta?",
"clickableLinkOpen": "Öppna URL",
"clickableLinksCopy": "Kopiera URL",
"clickableLinkError": "Fel uppstod vid försök att öppna URL",
"formattingExperiment": "Meddelandeformatering",
"messageFormattingDescription": "Aktivera RTF-formatering i visade meddelanden, t.ex. **fet** och *kursiv*",
"thisFeatureRequiresGroupExpermientsToBeEnabled": "Den här funktionen kräver att Grupper är aktiverat i Inställningar.",
"settingAndroidPowerExemption": "Undanta Android batterioptimering",
"settingAndroidPowerExemptionDescription": "Valfritt: Begär att Android ska undanta Cwtch från optimerad energihantering. Detta kommer att leda till bättre stabilitet till priset av större batterianvändning.",
"settingsAndroidPowerReenablePopup": "Det går inte att aktivera batterioptimering från Cwtch. Gå till Android \/ Inställningar \/ Appar \/ Cwtch \/ Batteri och välj \"Optimerad\"",
"okButton": "OK",
"tooltipBoldText": "Fet",
"tooltipBackToMessageEditing": "Tillbaka till meddelanderedigering",
"tooltipItalicize": "Kursiv",
"tooltipSuperscript": "Upphöjd",
"tooltipSubscript": "Nedsänkt",
"tooltipStrikethrough": "Överstruket",
"tooltipCode": "Kod \/ Monospace",
"tooltipPreviewFormatting": "Förhandsgranska meddelandeformatering",
"manageSharedFiles": "Hantera delade filer",
"stopSharingFile": "Sluta dela fil",
"restartFileShare": "Dela fil",
"viewReplies": "Visa svar på detta meddelande",
"headingReplies": "Svar",
"messageNoReplies": "Det finns inga svar på detta meddelande.",
"fileDownloadUnavailable": "Den här filen verkar inte vara tillgänglig för nedladdning. Avsändaren kan ha inaktiverat nedladdningar för den här filen.",
"replyingTo": "Svarar %1",
"tooltipPinConversation": "Fäst konversationen högst upp i \"Konversationer\".",
"tooltipUnpinConversation": "Ta bort konversationen från toppen av \"Konversationer\"",
"localeTr": "Turkiska \/ Türk",
"errorDownloadDirectoryDoesNotExist": "Fildelning kan inte aktiveras eftersom nedladdningsmappen inte har ställts in eller är inställd på en mapp som inte finns.",
"acquiringTicketsFromServer": "Utför Antispam-test",
"acquiredTicketsFromServer": "Antispam-testet slutfört",
"shareProfileMenuTooltop": "Dela profil via...",
"shareMenuQRCode": "Visa QR-kod",
"enableExperimentQRCode": "QR-koder",
"experimentQRCodeDescription": "QR-kodstöd tillåter delning av data (som profilidentitet) med QR-koder",
"localeNl": "Nederländska \/ Dutch",
"localePtBr": "Brasiliansk portugisiska \/ Português do Brasil",
"profileAutostartLabel": "Starta automatiskt",
"profileEnabled": "Aktivera",
"profileAutostartDescription": "Styr om profilen ska startas automatiskt vid programstart",
"localeSk": "Slovakiska \/ Slovák",
"localeKo": "Koreanska \/ 한국어",
"blodeuweddExperimentEnable": "Blodeuwedd-assistenten",
"blodeuweddDescription": "Blodeuwedd-assistenten lägger till nya funktioner till Cwtch, såsom sammanfattning av koversationer och meddelandeöversättning. Allt via en språkmodell som körs i datorn.",
"blodeuweddNotSupported": "Denna version av Cwtch har kompilerats utan stöd för Blodeuwedd-assistenten.",
"blodeuweddPath": "Katalogen där Blodeuwedd finns på din dator.",
"blodeuweddSummarize": "Sammanfatta konversation",
"blodeuweddTranslate": "Översätt meddelande",
"blodeuweddWarning": "Blodeuwedd använder en lokal språkmodell och en uppsättning små hjälpmodeller för att driva dess funktionalitet. Dessa tekniker är ofta mycket effektiva, de är inte felfria.\n\nÄven om vi har vidtagit åtgärder för att minimera risken, finns det fortfarande en möjlighet att data från Blodeuwedd kan vara felaktigt, missvisande och\/eller stötande.\n\nPå grund av det kräver Blodeuwedd nedladdning av två ytterligare komponenter separat från Cwtch, Blodeuwedd Model (eller annan kompatibel modell) och Blodeuwedd Runner.\n\nLäs på https:\/\/docs.cwtch.im\/docs\/settings\/experiments\/blodeuwedd för mer information om hur du skaffar dessa komponenter och konfigurerar dem.",
"blodeuweddProcessing": "Blodeuwedd arbetar...",
"availabilityStatusAvailable": "Tillgänglig",
"availabilityStatusAway": "Borta",
"availabilityStatusBusy": "Upptagen",
"availabilityStatusTooltip": "Ange tillgänglighetsstatus",
"profileInfoHint": "Lägg till lite offentlig information om dig själv här, t.ex. blogg, webbplatser, kortfattad biografi.",
"profileInfoHint2": "Du kan lägga till upp till 3 fält.",
"profileInfoHint3": "Kontakter kommer att kunna se denna information under konversationsinställningar",
"retryConnection": "Försök igen",
"retryConnectionTooltip": "Cwtch försöker ansluta till noder regelbundet, men du kan be Cwtch att försöka tidigare genom att trycka på den här knappen.",
"localeSv": "Svenska \/ Svenska",
"localeJa": "Japanska \/ 日本語",
"fontScalingDescription": "Justera den relativa skalningsfaktorn för teckensnitt som tillämpas på text och widgets."
}

391
lib/l10n/intl_sw.arb Normal file
View File

@ -0,0 +1,391 @@
{
"@@locale": "sw",
"@@last_modified": "2023-05-29T14:05:23+02:00",
"torSettingsUseCustomTorServiceConfigurastionDescription": "Batilisha usanidi chaguo-msingi wa tor. Onyo: Hii inaweza kuwa hatari. Washa hii ikiwa tu unajua unachofanya.",
"torSettingsErrorSettingPort": "Nambari ya Mlango lazima iwe kati ya 1 na 65535",
"fileSharingSettingsDownloadFolderDescription": "Faili zinapopakuliwa kiotomatiki (km faili za picha, mapitio ya picha yanapowezeshwa) eneo chaguomsingi la kupakua faili linahitajika.",
"fileSharingSettingsDownloadFolderTooltip": "Vinjari ili kuchagua folda chaguo-msingi tofauti kwa faili zilizopakuliwa.",
"labelACNCircuitInfo": "Maelezo ya Mzunguko wa ACN",
"descriptionACNCircuitInfo": "Maelezo ya kina kuhusu njia ambayo mtandao wa mawasiliano usiojulikana unatumia kuunganisha kwenye mazungumzo haya.",
"labelTorNetwork": "Mtandao wa Tor",
"torSettingsEnableCache": "Makubaliano ya Cache Tor",
"tooltipSelectACustomProfileImage": "Chagua Picha Maalum ya Wasifu",
"notificationPolicyMute": "Nyamazisha",
"notificationPolicyOptIn": "Chagua Katika",
"notificationPolicyDefaultAll": "Chaguomsingi Zote",
"availabilityStatusBusy": "Shughuli",
"conversationNotificationPolicyDefault": "Chaguomsingi",
"conversationNotificationPolicyOptIn": "Chagua kujijumuisha ",
"conversationNotificationPolicyNever": "Kamwe",
"notificationPolicySettingLabel": "Sera ya Arifa",
"notificationContentSettingLabel": "Maudhui ya Arifa",
"notificationPolicySettingDescription": "Hudhibiti tabia ya arifa ya programu chaguomsingi",
"notificationContentSettingDescription": "Hudhibiti maudhui ya arifa za mazungumzo",
"settingGroupBehaviour": "Tabia",
"settingsGroupAppearance": "Muonekano",
"settingsGroupExperiments": "Majaribio",
"conversationNotificationPolicySettingLabel": "Sera ya Arifa ya Mazungumzo",
"conversationNotificationPolicySettingDescription": "Dhibiti tabia ya arifa kwa mazungumzo haya",
"notificationContentSimpleEvent": "Tukio la wazi",
"notificationContentContactInfo": "Taarifa za Mazungumzo",
"newMessageNotificationSimple": "Ujumbe Mpya",
"newMessageNotificationConversationInfo": "Ujumbe Mpya Kutoka %1",
"localeRo": "Kiromania \/ Kirumi",
"localeLb": "Luxembourgish \/ Lëtzebuergesch",
"localeNo": "Kinorwe \/ Norsk",
"localeEl": "Kigiriki \/ Ελληνικά",
"localeCy": "Welsh \/ Cymraeg",
"localeDa": "Kidenishi \/ Dansk",
"exportProfile": "Hamisha Wasifu",
"exportProfileTooltip": "Hifadhi nakala ya wasifu huu kwa faili iliyosimbwa. Faili iliyosimbwa kwa njia fiche inaweza kuingizwa kwenye programu nyingine ya Cwtch.",
"importProfile": "Ingiza Wasifu",
"importProfileTooltip": "Tumia chelezo iliyosimbwa kwa njia fiche ya Cwtch kuleta wasifu ulioundwa katika mfano mwingine wa Cwtch.",
"failedToImportProfile": "Hitilafu katika Kuingiza Wasifu",
"successfullyImportedProfile": "Imefaulu Kuingiza Wasifu: %wasifu",
"shuttingDownApp": "Inazima...",
"clickableLinksWarning": "Kufungua URL hii itafungua programu nje ya Cwtch na kunaweza kufichua metadata au vinginevyo kuhatarisha usalama wa Cwtch. Fungua URL kutoka kwa watu unaowaamini pekee. Je, una uhakika ungependa kuendelea?",
"clickableLinkOpen": "Fungua URL",
"clickableLinksCopy": "Nakili URL",
"clickableLinkError": "Hitilafu ilitokea wakati wa kujaribu kufungua URL",
"formattingExperiment": "Uumbizaji wa Ujumbe",
"messageFormattingDescription": "Washa uumbizaji wa maandishi umbizo katika ujumbe unaoonyeshwa kwa mfano **bold** na *italic*",
"thisFeatureRequiresGroupExpermientsToBeEnabled": "Kipengele hiki kinahitaji Majaribio ya Vikundi kuwashwa katika Mipangilio",
"settingAndroidPowerExemption": "Android Puuza Uboreshaji wa Betri",
"settingAndroidPowerExemptionDescription": "Hiari: Omba Android kuondoa Cwtch kutoka kwa usimamizi bora wa nishati. Hii itasababisha uthabiti bora kwa gharama ya matumizi makubwa ya betri.",
"settingsAndroidPowerReenablePopup": "Haiwezi kuwezesha upya Uboreshaji wa Betri kutoka ndani ya Cwtch. Tafadhali nenda kwa Android \/ Mipangilio \/ Programu \/ Cwtch \/ Betri na uweke Matumizi kwa 'Imeboreshwa'",
"okButton": "sawa",
"tooltipBoldText": "Kolevu",
"tooltipBackToMessageEditing": "Rudi kwa Kuhariri Ujumbe",
"tooltipItalicize": "Italiki",
"tooltipSubscript": "Usajili",
"tooltipStrikethrough": "Strikethrough",
"tooltipCode": "Nambari \/ Nafasi moja",
"tooltipPreviewFormatting": "Hakiki Uumbizaji wa Ujumbe",
"manageSharedFiles": "Dhibiti Faili Zilizoshirikiwa",
"stopSharingFile": "Acha Kushiriki Faili",
"restartFileShare": "Anza Kushiriki Faili",
"viewReplies": "Tazama majibu kwa ujumbe huu",
"headingReplies": "Majibu",
"messageNoReplies": "Hakuna majibu kwa ujumbe huu.",
"fileDownloadUnavailable": "Faili hii inaonekana haipatikani kwa kupakuliwa. Mtumaji anaweza kuwa amezima upakuaji wa faili hii.",
"replyingTo": "Kujibu %1",
"tooltipPinConversation": "Bandika mazungumzo juu ya \"Mazungumzo\"",
"tooltipUnpinConversation": "Bandua mazungumzo kutoka sehemu ya juu ya \"Mazungumzo\"",
"localeTr": "Kituruki \/ Kituruki",
"acquiringTicketsFromServer": "Kutekeleza Changamoto ya Antispam",
"acquiredTicketsFromServer": "Changamoto ya Antispam Imekamilika",
"shareProfileMenuTooltop": "Shiriki wasifu kupitia...",
"shareMenuQRCode": "Onyesha Msimbo wa QR",
"enableExperimentQRCode": "Misimbo ya QR",
"experimentQRCodeDescription": "Usaidizi wa Msimbo wa QR huruhusu kushiriki data (kama vile utambulisho wa wasifu) kwa Misimbo ya QR",
"localeNl": "Kiholanzi \/ Kiholanzi",
"localePtBr": "Kireno cha Kibrazili \/ Português do Brasil",
"profileAutostartLabel": "Anzisha kiotomatiki",
"profileEnabled": "Wezesha",
"profileAutostartDescription": "Hudhibiti ikiwa wasifu utazinduliwa kiotomatiki inapowashwa",
"profileEnabledDescription": "Washa au Lemaza wasifu.",
"localeSk": "Kislovakia \/ Kislovakia",
"localeKo": "Kikorea \/ 한국어",
"blodeuweddExperimentEnable": "Msaidizi wa Blodeuwedd",
"blodeuweddNotSupported": "Toleo hili la Cwtch limeundwa bila usaidizi kwa Msaidizi wa Blodeuwedd.",
"retryConnectionTooltip": "Cwtch retries wenzao mara kwa mara, lakini unaweza kuwaambia Cwtch kujaribu mapema kwa kubofya hiki kitufe",
"blodeuweddPath": "The directory where the Blodeuwedd is located on your computer.",
"blodeuweddSummarize": "Fupisha Mazungumzo",
"blodeuweddTranslate": "Tafsiri Ujumbe",
"blodeuweddProcessing": "Blodeuwedd inachakata...",
"availabilityStatusAvailable": "Inapatikana",
"availabilityStatusAway": "Sipo karibu",
"availabilityStatusTooltip": "Weka hali ya upatikanaji wako",
"profileInfoHint": "Ongeza taarifa za umma kukuhusu hapa kwa mfano blogu, tovuti, wasifu mfupi.",
"profileInfoHint2": "Unaweza kuongeza hadi sehemu 3.",
"profileInfoHint3": "Anwani zitaweza kuona maelezo haya katika Mipangilio ya Mazungumzo",
"retryConnection": "Jaribu tena",
"fontScalingDescription": "Adjust the relative font scaling factor applied to text and widgets.",
"localeUk": "Kiukreni \/ українською",
"localeSv": "Kiswidi \/ Svenska",
"localeJa": "Kijapani \/ 日本語",
"localeSw": "Kiswahili \/ Kiswahili",
"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.",
"blodeuweddDescription": "The Blodeuwedd assistant adds new features to Cwtch such as chat transcript summarization and message translation via a locally hosted language model.",
"errorDownloadDirectoryDoesNotExist": "Filesharing cannot be enabled because the Download Folder has not been set, or is set to a folder that does not exist.",
"tooltipSuperscript": "Superscript",
"torSettingsEnabledCacheDescription": "Cache the current downloaded Tor consensus to reuse next time Cwtch is opened. This will allow Tor to start faster. When disabled, Cwtch will purge cached data on start up.",
"torSettingsUseCustomTorServiceConfiguration": "Use a Custom Tor Service Configuration (torrc)",
"torSettingsCustomControlPortDescription": "Use a custom port for control connections to the Tor proxy",
"torSettingsCustomControlPort": "Custom Control Port",
"torSettingsCustomSocksPortDescription": "Use a custom port for data connections to the Tor proxy",
"torSettingsCustomSocksPort": "Custom SOCKS Port",
"torSettingsEnabledAdvancedDescription": "Use an existing Tor service on your system, or change the parameters of the Cwtch Tor Service",
"torSettingsEnabledAdvanced": "Enable Advanced Tor Configuration",
"msgAddToAccept": "Add this account to your contacts in order to accept this file.",
"btnSendFile": "Send File",
"msgConfirmSend": "Are you sure you want to send",
"msgFileTooBig": "File size cannot exceed 10 GB",
"storageMigrationModalMessage": "Migrating profiles to new storage format. This could take a few minutes...",
"loadingCwtch": "Loading Cwtch...",
"themeColorLabel": "Color Theme",
"themeNameNeon2": "Neon2",
"themeNameNeon1": "Neon1",
"themeNameMidnight": "Midnight",
"themeNameMermaid": "Mermaid",
"themeNamePumpkin": "Pumpkin",
"themeNameGhost": "Ghost",
"themeNameVampire": "Vampire",
"themeNameWitch": "Witch",
"themeNameCwtch": "Cwtch",
"settingDownloadFolder": "Download Folder",
"settingImagePreviewsDescription": "Images and Profile Pictures will be downloaded and previewed automatically. We recommend that you do not enable this Experiment if you use Cwtch with untrusted contacts.",
"settingImagePreviews": "Image Previews and Profile Pictures",
"experimentClickableLinksDescription": "The clickable links experiment allows you to click on URLs shared in messages",
"enableExperimentClickableLinks": "Enable Clickable Links",
"serverConnectionsLabel": "Connection",
"serverTotalMessagesLabel": "Total Messages",
"serverMetricsLabel": "Server Metrics",
"manageKnownServersShort": "Servers",
"manageKnownServersLong": "Manage Known Servers",
"displayNameTooltip": "Please enter a display name",
"manageKnownServersButton": "Manage Known Servers",
"fieldDescriptionLabel": "Description",
"groupsOnThisServerLabel": "Groups I am in hosted on this server",
"importLocalServerButton": "Import %1",
"importLocalServerSelectText": "Select Local Server",
"importLocalServerLabel": "Import a locally hosted server",
"newMessagesLabel": "New Messages",
"localeRU": "Russian \/ Русский",
"copyServerKeys": "Copy keys",
"verfiyResumeButton": "Verify\/resume",
"fileCheckingStatus": "Checking download status",
"fileInterrupted": "Interrupted",
"fileSavedTo": "Saved to",
"encryptedServerDescription": "Encrypting a server with a password protects it from other people who may also use this device. Encrypted servers cannot be decrypted, displayed or accessed until the correct password is entered to unlock them.",
"plainServerDescription": "We recommend that you protect your Cwtch servers with a password. If you do not set a password on this server then anyone who has access to this device may be able to access information about this server, including sensitive cryptographic keys.",
"deleteServerConfirmBtn": "Really delete server",
"deleteServerSuccess": "Successfully deleted server",
"enterCurrentPasswordForDeleteServer": "Please enter current password to delete this server",
"copyAddress": "Copy Address",
"settingServersDescription": "The hosting servers experiment enables hosting and managing Cwtch servers",
"settingServers": "Hosting Servers",
"enterServerPassword": "Enter password to unlock server",
"unlockProfileTip": "Please create or unlock a profile to begin!",
"unlockServerTip": "Please create or unlock a server to begin!",
"addServerTooltip": "Add new server",
"serversManagerTitleShort": "Servers",
"serversManagerTitleLong": "Servers You Host",
"saveServerButton": "Save Server",
"serverAutostartDescription": "Controls if the application will automatically launch the server on start",
"serverAutostartLabel": "Autostart",
"serverEnabledDescription": "Start or stop the server",
"serverEnabled": "Server Enabled",
"serverDescriptionDescription": "Your description of the server for personal management use only, will never be shared",
"serverDescriptionLabel": "Server Description",
"serverAddress": "Server Address",
"editServerTitle": "Edit Server",
"addServerTitle": "Add Server",
"titleManageProfilesShort": "Profiles",
"descriptionFileSharing": "The file sharing experiment allows you to send and receive files from Cwtch contacts and groups. Note that sharing a file with a group will result in members of that group connecting with you directly over Cwtch to download it.",
"settingFileSharing": "File Sharing",
"tooltipSendFile": "Send File",
"messageFileOffered": "Contact is offering to send you a file",
"messageFileSent": "You sent a file",
"messageEnableFileSharing": "Enable the file sharing experiment to view this message.",
"labelFilesize": "Size",
"labelFilename": "Filename",
"downloadFileButton": "Download",
"openFolderButton": "Open Folder",
"retrievingManifestMessage": "Retrieving file information...",
"descriptionStreamerMode": "If turned on, this option makes the app more visually private for streaming or presenting with, for example, hiding profile and contact addresses",
"streamerModeLabel": "Streamer\/Presentation Mode",
"archiveConversation": "Archive this Conversation",
"blockUnknownConnectionsEnabledDescription": "Connections from unknown contacts are blocked. You can change this in Settings",
"showMessageButton": "Show Message",
"blockedMessageMessage": "This message is from a profile you have blocked.",
"placeholderEnterMessage": "Type a message...",
"plainProfileDescription": "We recommend that you protect your Cwtch profiles with a password. If you do not set a password on this profile then anyone who has access to this device may be able to access information about this profile, including contacts, messages and sensitive cryptographic keys.",
"encryptedProfileDescription": "Encrypting a profile with a password protects it from other people who may also use this device. Encrypted profiles cannot be decrypted, displayed or accessed until the correct password is entered to unlock them.",
"addContactConfirm": "Add contact %1",
"addContact": "Add contact",
"contactGoto": "Go to conversation with %1",
"settingUIColumnOptionSame": "Same as portrait mode setting",
"settingUIColumnDouble14Ratio": "Double (1:4)",
"settingUIColumnDouble12Ratio": "Double (1:2)",
"settingUIColumnSingle": "Single",
"settingUIColumnLandscape": "UI Columns in Landscape Mode",
"settingUIColumnPortrait": "UI Columns in Portrait Mode",
"localePl": "Polish \/ Polski",
"tooltipRemoveThisQuotedMessage": "Remove quoted message.",
"tooltipReplyToThisMessage": "Reply to this message",
"tooltipRejectContactRequest": "Reject this contact request",
"tooltipAcceptContactRequest": "Accept this contact request.",
"notificationNewMessageFromGroup": "New message in a group!",
"notificationNewMessageFromPeer": "New message from a contact!",
"tooltipHidePassword": "Hide Password",
"tooltipShowPassword": "Show Password",
"groupInviteSettingsWarning": "You have been invited to join a group! Please enable the Group Chat Experiment in Settings to view this Invitation.",
"shutdownCwtchAction": "Shutdown Cwtch",
"shutdownCwtchDialog": "Are you sure you want to shutdown Cwtch? This will close all connections, and exit the application.",
"shutdownCwtchDialogTitle": "Shutdown Cwtch?",
"shutdownCwtchTooltip": "Shutdown Cwtch",
"malformedMessage": "Malformed message",
"profileDeleteSuccess": "Successfully deleted profile",
"debugLog": "Turn on console debug logging",
"torNetworkStatus": "Tor network status",
"addContactFirst": "Add or pick a contact to begin chatting.",
"createProfileToBegin": "Please create or unlock a profile to begin",
"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",
"sendMessage": "Send Message",
"cancel": "Cancel",
"resetTor": "Reset",
"torStatus": "Tor Status",
"torVersion": "Tor Version",
"sendAnInvitation": "You sent an invitation for: ",
"contactSuggestion": "This is a contact suggestion for: ",
"rejected": "Rejected!",
"accepted": "Accepted!",
"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.",
"newPassword": "New Password",
"yesLeave": "Yes, Leave This Conversation",
"reallyLeaveThisGroupPrompt": "Are you sure you want to leave this conversation? All messages and attributes will be deleted.",
"leaveConversation": "Leave This Conversation",
"inviteToGroup": "You have been invited to join a group:",
"titleManageServers": "Manage Servers",
"successfullAddedContact": "Successfully added ",
"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.",
"titleManageProfiles": "Manage Cwtch Profiles",
"tooltipUnlockProfiles": "Unlock encrypted profiles by entering their password.",
"titleManageContacts": "Conversations",
"tooltipAddContact": "Add a new contact or conversation",
"tooltipOpenSettings": "Open the settings pane",
"contactAlreadyExists": "Contact Already Exists",
"invalidImportString": "Invalid import string",
"conversationSettings": "Conversation Settings",
"enterCurrentPasswordForDelete": "Please enter current password to delete this profile.",
"enableGroups": "Enable Group Chat",
"localeIt": "Italian \/ Italiano",
"localeEs": "Spanish \/ Español",
"todoPlaceholder": "Todo...",
"addNewItem": "Add a new item to the list",
"addListItem": "Add a New List Item",
"newConnectionPaneTitle": "New Connection",
"networkStatusOnline": "Online",
"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...",
"smallTextLabel": "Small",
"defaultScalingText": "Font Scaling",
"builddate": "Built on: %2",
"version": "Version %1",
"versionTor": "Version %1 with tor %2",
"experimentsEnabled": "Enable Experiments",
"themeDark": "Dark",
"themeLight": "Light",
"settingTheme": "Use Light Themes",
"largeTextLabel": "Large",
"settingInterfaceZoom": "Zoom level",
"localeDe": "German \/ Deutsch",
"localePt": "Portuguese \/ Portuguesa",
"localeFr": "French \/ Français",
"localeEn": "English \/ English",
"settingLanguage": "Language",
"blockUnknownLabel": "Block Unknown Contacts",
"zoomLabel": "Interface zoom (mostly affects text and button sizes)",
"versionBuilddate": "Version: %1 Built on: %2",
"cwtchSettingsTitle": "Cwtch Settings",
"unlock": "Unlock",
"yourServers": "Your Servers",
"yourProfiles": "Your Profiles",
"error0ProfilesLoadedForPassword": "0 profiles loaded with that password",
"password": "Password",
"enterProfilePassword": "Enter a password to view your profiles",
"addNewProfileBtn": "Add new profile",
"deleteConfirmText": "DELETE",
"deleteProfileConfirmBtn": "Really Delete Profile",
"deleteConfirmLabel": "Type DELETE to confirm",
"deleteProfileBtn": "Delete Profile",
"passwordChangeError": "Error changing password: Supplied password rejected",
"passwordErrorMatch": "Passwords do not match",
"saveProfileBtn": "Save Profile",
"createProfileBtn": "Create Profile",
"passwordErrorEmpty": "Password cannot be empty",
"password2Label": "Reenter password",
"password1Label": "Password",
"currentPasswordLabel": "Current Password",
"yourDisplayName": "Your Display Name",
"profileOnionLabel": "Send this address to contacts you want to connect with",
"noPasswordWarning": "Not using a password on this account means that all data stored locally will not be encrypted",
"radioNoPassword": "Unencrypted (No password)",
"radioUsePassword": "Password",
"editProfile": "Edit Profile",
"newProfile": "New Profile",
"defaultProfileName": "Alice",
"profileName": "Display name",
"editProfileTitle": "Edit Profile",
"addProfileTitle": "Add new profile",
"deleteBtn": "Delete",
"unblockBtn": "Unblock Contact",
"dontSavePeerHistory": "Delete History",
"savePeerHistoryDescription": "Determines whether to delete any history associated with the contact.",
"savePeerHistory": "Save History",
"blockBtn": "Block Contact",
"saveBtn": "Save",
"displayNameLabel": "Display Name",
"copiedToClipboardNotification": "Copied to Clipboard",
"addressLabel": "Address",
"puzzleGameBtn": "Puzzle Game",
"bulletinsBtn": "Bulletins",
"listsBtn": "Lists",
"chatBtn": "Chat",
"rejectGroupBtn": "Reject",
"acceptGroupBtn": "Accept",
"acceptGroupInviteLabel": "Do you want to accept the invitation to",
"newGroupBtn": "Create new group",
"copyBtn": "Copy",
"peerOfflineMessage": "Contact is offline, messages can't be delivered right now",
"peerBlockedMessage": "Contact is blocked",
"pendingLabel": "Pending",
"acknowledgedLabel": "Acknowledged",
"couldNotSendMsgError": "Could not send this message",
"dmTooltip": "Click to DM",
"membershipDescription": "Below is a list of users who have sent messages to the group. This list may not reflect all users who have access to the group.",
"addListItemBtn": "Add Item",
"peerNotOnline": "Contact is offline. Applications cannot be used right now.",
"searchList": "Search List",
"update": "Update",
"inviteBtn": "Invite",
"inviteToGroupLabel": "Invite to group",
"groupNameLabel": "Group Name",
"viewServerInfo": "Server Info",
"serverNotSynced": "Syncing New Messages (This can take some time)...",
"serverSynced": "Synced",
"serverConnectivityDisconnected": "Server Disconnected",
"serverConnectivityConnected": "Server Connected",
"serverInfo": "Server Information",
"invitationLabel": "Invitation",
"serverLabel": "Server",
"search": "Search...",
"blocked": "Blocked",
"pasteAddressToAddContact": "Paste a cwtch address, invitation or key bundle here to add a new conversation",
"titlePlaceholder": "title...",
"postNewBulletinLabel": "Post new bulletin",
"newBulletinLabel": "New Bulletin",
"joinGroup": "Join group",
"createGroup": "Create group",
"addPeer": "Add Contact",
"groupAddr": "Address",
"invitation": "Invitation",
"server": "Server",
"peerName": "Name",
"peerAddress": "Address",
"joinGroupTab": "Join a group",
"createGroupTab": "Create a group",
"addPeerTab": "Add a contact",
"createGroupBtn": "Create",
"defaultGroupName": "Awesome Group",
"createGroupTitle": "Create Group"
}

View File

@ -1,6 +1,10 @@
{
"@@locale": "tr",
"@@last_modified": "2023-05-15T21:16:36+02:00",
"@@last_modified": "2023-05-29T14:05:23+02:00",
"localeUk": "Ukrainian \/ українською",
"profileEnabledDescription": "Profili başlat veya durdur",
"localeSw": "Swahili \/ Kiswahili",
"localeSv": "Swedish \/ Svenska",
"fontScalingDescription": "Adjust the relative font scaling factor applied to text and widgets.",
"defaultScalingText": "Varsayılan metin boyutu (ölçek faktörü: ",
"localeJa": "Japanese \/ 日本語",
@ -23,7 +27,6 @@
"blodeuweddExperimentEnable": "Blodeuwedd Assistant",
"localeKo": "Korean \/ 한국어",
"localeSk": "Slovak \/ Slovák",
"profileEnabledDescription": "Profili başlat veya durdur",
"profileAutostartLabel": "Otomatik başlatma",
"profileAutostartDescription": "Profilin başlangıçta otomatik olarak başlatılıp başlatılmayacağını kontrol eder",
"profileEnabled": "Etkinleştir",

391
lib/l10n/intl_uk.arb Normal file
View File

@ -0,0 +1,391 @@
{
"@@locale": "uk",
"@@last_modified": "2023-05-29T14:05:23+02:00",
"localeUk": "Ukrainian \/ українською",
"localeSw": "Swahili \/ Kiswahili",
"localeSv": "Swedish \/ Svenska",
"fontScalingDescription": "Adjust the relative font scaling factor applied to text and widgets.",
"localeJa": "Japanese \/ 日本語",
"retryConnectionTooltip": "Cwtch retries peers regularly, but you can tell Cwtch to try sooner by pushing this button.",
"retryConnection": "Retry",
"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.",
"availabilityStatusTooltip": "Set your availability status",
"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",
"profileEnabledDescription": "Activate or Deactivate the profile.",
"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...",
"acquiredTicketsFromServer": "Antispam Challenge Complete",
"acquiringTicketsFromServer": "Performing Antispam Challenge",
"errorDownloadDirectoryDoesNotExist": "Filesharing cannot be enabled because the Download Folder has not been set, or is set to a folder that does not exist.",
"localeTr": "Turkish \/ Türk",
"tooltipUnpinConversation": "Unpin conversation from the top of \"Conversations\"",
"tooltipPinConversation": "Pin conversation to the top of \"Conversations\"",
"replyingTo": "Replying to %1",
"fileDownloadUnavailable": "This file appears unavailable for download. The sender may have disabled downloads for this file.",
"messageNoReplies": "There are no replies to this message.",
"headingReplies": "Replies",
"viewReplies": "View replies to this message",
"restartFileShare": "Start Sharing File",
"stopSharingFile": "Stop Sharing File",
"manageSharedFiles": "Manage Shared Files",
"tooltipPreviewFormatting": "Preview Message Formatting",
"tooltipCode": "Code \/ Monospace",
"tooltipStrikethrough": "Strikethrough",
"tooltipSubscript": "Subscript",
"tooltipSuperscript": "Superscript",
"tooltipItalicize": "Italic",
"tooltipBackToMessageEditing": "Back to Message Editing",
"tooltipBoldText": "Bold",
"okButton": "OK",
"settingsAndroidPowerReenablePopup": "Cannot re-enable Battery Optimization from within Cwtch. Please go to Android \/ Settings \/ Apps \/ Cwtch \/ Battery and set Usage to 'Optimized'",
"settingAndroidPowerExemptionDescription": "Optional: Request Android to exempt Cwtch from optimized power management. This will result in better stability at the cost of greater battery use.",
"settingAndroidPowerExemption": "Android Ignore Battery Optimizations",
"thisFeatureRequiresGroupExpermientsToBeEnabled": "This feature requires the Groups Experiment to be enabled in Settings",
"messageFormattingDescription": "Enable rich text formatting in displayed messages e.g. **bold** and *italic*",
"formattingExperiment": "Message Formatting",
"clickableLinkError": "Error encountered while attempting to open URL",
"clickableLinksCopy": "Copy URL",
"clickableLinkOpen": "Open URL",
"clickableLinksWarning": "Opening this URL will launch an application outside of Cwtch and may reveal metadata or otherwise compromise the security of Cwtch. Only open URLs from people you trust. Are you sure you want to continue?",
"shuttingDownApp": "Shutting down...",
"successfullyImportedProfile": "Successfully Imported Profile: %profile",
"failedToImportProfile": "Error Importing Profile",
"importProfileTooltip": "Use an encrypted Cwtch backup to bring in a profile created in another instance of Cwtch.",
"importProfile": "Import Profile",
"exportProfileTooltip": "Backup this profile to an encrypted file. The encrypted file can be imported into another Cwtch app.",
"exportProfile": "Export Profile",
"localeDa": "Danish \/ Dansk",
"localeCy": "Welsh \/ Cymraeg",
"localeEl": "Greek \/ Ελληνικά",
"localeNo": "Norwegian \/ Norsk",
"localeLb": "Luxembourgish \/ Lëtzebuergesch",
"localeRo": "Romanian \/ Română",
"newMessageNotificationConversationInfo": "New Message From %1",
"newMessageNotificationSimple": "New Message",
"notificationContentContactInfo": "Conversation Information",
"notificationContentSimpleEvent": "Plain Event",
"conversationNotificationPolicySettingDescription": "Control notification behaviour for this conversation",
"conversationNotificationPolicySettingLabel": "Conversation Notification Policy",
"settingsGroupExperiments": "Experiments",
"settingsGroupAppearance": "Appearance",
"settingGroupBehaviour": "Behaviour",
"notificationContentSettingDescription": "Controls the contents of conversation notifications",
"notificationPolicySettingDescription": "Controls the default application notification behaviour",
"notificationContentSettingLabel": "Notification Content",
"notificationPolicySettingLabel": "Notification Policy",
"conversationNotificationPolicyNever": "Never",
"conversationNotificationPolicyOptIn": "Opt In",
"conversationNotificationPolicyDefault": "Default",
"notificationPolicyDefaultAll": "Default All",
"notificationPolicyOptIn": "Opt In",
"notificationPolicyMute": "Mute",
"tooltipSelectACustomProfileImage": "Select a Custom Profile Image",
"torSettingsEnabledCacheDescription": "Cache the current downloaded Tor consensus to reuse next time Cwtch is opened. This will allow Tor to start faster. When disabled, Cwtch will purge cached data on start up.",
"torSettingsEnableCache": "Cache Tor Consensus",
"labelTorNetwork": "Tor Network",
"descriptionACNCircuitInfo": "In depth information about the path that the anonymous communication network is using to connect to this conversation.",
"labelACNCircuitInfo": "ACN Circuit Info",
"fileSharingSettingsDownloadFolderTooltip": "Browse to select a different default folder for downloaded files.",
"fileSharingSettingsDownloadFolderDescription": "When files are downloaded automatically (e.g. image files, when image previews are enabled) a default location to download the files to is needed.",
"torSettingsErrorSettingPort": "Port Number must be between 1 and 65535",
"torSettingsUseCustomTorServiceConfigurastionDescription": "Override the default tor configuration. Warning: This could be dangerous. Only turn this on if you know what you are doing.",
"torSettingsUseCustomTorServiceConfiguration": "Use a Custom Tor Service Configuration (torrc)",
"torSettingsCustomControlPortDescription": "Use a custom port for control connections to the Tor proxy",
"torSettingsCustomControlPort": "Custom Control Port",
"torSettingsCustomSocksPortDescription": "Use a custom port for data connections to the Tor proxy",
"torSettingsCustomSocksPort": "Custom SOCKS Port",
"torSettingsEnabledAdvancedDescription": "Use an existing Tor service on your system, or change the parameters of the Cwtch Tor Service",
"torSettingsEnabledAdvanced": "Enable Advanced Tor Configuration",
"msgAddToAccept": "Add this account to your contacts in order to accept this file.",
"btnSendFile": "Send File",
"msgConfirmSend": "Are you sure you want to send",
"msgFileTooBig": "File size cannot exceed 10 GB",
"storageMigrationModalMessage": "Migrating profiles to new storage format. This could take a few minutes...",
"loadingCwtch": "Loading Cwtch...",
"themeColorLabel": "Color Theme",
"themeNameNeon2": "Neon2",
"themeNameNeon1": "Neon1",
"themeNameMidnight": "Midnight",
"themeNameMermaid": "Mermaid",
"themeNamePumpkin": "Pumpkin",
"themeNameGhost": "Ghost",
"themeNameVampire": "Vampire",
"themeNameWitch": "Witch",
"themeNameCwtch": "Cwtch",
"settingDownloadFolder": "Download Folder",
"settingImagePreviewsDescription": "Images and Profile Pictures will be downloaded and previewed automatically. We recommend that you do not enable this Experiment if you use Cwtch with untrusted contacts.",
"settingImagePreviews": "Image Previews and Profile Pictures",
"experimentClickableLinksDescription": "The clickable links experiment allows you to click on URLs shared in messages",
"enableExperimentClickableLinks": "Enable Clickable Links",
"serverConnectionsLabel": "Connection",
"serverTotalMessagesLabel": "Total Messages",
"serverMetricsLabel": "Server Metrics",
"manageKnownServersShort": "Servers",
"manageKnownServersLong": "Manage Known Servers",
"displayNameTooltip": "Please enter a display name",
"manageKnownServersButton": "Manage Known Servers",
"fieldDescriptionLabel": "Description",
"groupsOnThisServerLabel": "Groups I am in hosted on this server",
"importLocalServerButton": "Import %1",
"importLocalServerSelectText": "Select Local Server",
"importLocalServerLabel": "Import a locally hosted server",
"newMessagesLabel": "New Messages",
"localeRU": "Russian \/ Русский",
"copyServerKeys": "Copy keys",
"verfiyResumeButton": "Verify\/resume",
"fileCheckingStatus": "Checking download status",
"fileInterrupted": "Interrupted",
"fileSavedTo": "Saved to",
"encryptedServerDescription": "Encrypting a server with a password protects it from other people who may also use this device. Encrypted servers cannot be decrypted, displayed or accessed until the correct password is entered to unlock them.",
"plainServerDescription": "We recommend that you protect your Cwtch servers with a password. If you do not set a password on this server then anyone who has access to this device may be able to access information about this server, including sensitive cryptographic keys.",
"deleteServerConfirmBtn": "Really delete server",
"deleteServerSuccess": "Successfully deleted server",
"enterCurrentPasswordForDeleteServer": "Please enter current password to delete this server",
"copyAddress": "Copy Address",
"settingServersDescription": "The hosting servers experiment enables hosting and managing Cwtch servers",
"settingServers": "Hosting Servers",
"enterServerPassword": "Enter password to unlock server",
"unlockProfileTip": "Please create or unlock a profile to begin!",
"unlockServerTip": "Please create or unlock a server to begin!",
"addServerTooltip": "Add new server",
"serversManagerTitleShort": "Servers",
"serversManagerTitleLong": "Servers You Host",
"saveServerButton": "Save Server",
"serverAutostartDescription": "Controls if the application will automatically launch the server on start",
"serverAutostartLabel": "Autostart",
"serverEnabledDescription": "Start or stop the server",
"serverEnabled": "Server Enabled",
"serverDescriptionDescription": "Your description of the server for personal management use only, will never be shared",
"serverDescriptionLabel": "Server Description",
"serverAddress": "Server Address",
"editServerTitle": "Edit Server",
"addServerTitle": "Add Server",
"titleManageProfilesShort": "Profiles",
"descriptionFileSharing": "The file sharing experiment allows you to send and receive files from Cwtch contacts and groups. Note that sharing a file with a group will result in members of that group connecting with you directly over Cwtch to download it.",
"settingFileSharing": "File Sharing",
"tooltipSendFile": "Send File",
"messageFileOffered": "Contact is offering to send you a file",
"messageFileSent": "You sent a file",
"messageEnableFileSharing": "Enable the file sharing experiment to view this message.",
"labelFilesize": "Size",
"labelFilename": "Filename",
"downloadFileButton": "Download",
"openFolderButton": "Open Folder",
"retrievingManifestMessage": "Retrieving file information...",
"descriptionStreamerMode": "If turned on, this option makes the app more visually private for streaming or presenting with, for example, hiding profile and contact addresses",
"streamerModeLabel": "Streamer\/Presentation Mode",
"archiveConversation": "Archive this Conversation",
"blockUnknownConnectionsEnabledDescription": "Connections from unknown contacts are blocked. You can change this in Settings",
"showMessageButton": "Show Message",
"blockedMessageMessage": "This message is from a profile you have blocked.",
"placeholderEnterMessage": "Type a message...",
"plainProfileDescription": "We recommend that you protect your Cwtch profiles with a password. If you do not set a password on this profile then anyone who has access to this device may be able to access information about this profile, including contacts, messages and sensitive cryptographic keys.",
"encryptedProfileDescription": "Encrypting a profile with a password protects it from other people who may also use this device. Encrypted profiles cannot be decrypted, displayed or accessed until the correct password is entered to unlock them.",
"addContactConfirm": "Add contact %1",
"addContact": "Add contact",
"contactGoto": "Go to conversation with %1",
"settingUIColumnOptionSame": "Same as portrait mode setting",
"settingUIColumnDouble14Ratio": "Double (1:4)",
"settingUIColumnDouble12Ratio": "Double (1:2)",
"settingUIColumnSingle": "Single",
"settingUIColumnLandscape": "UI Columns in Landscape Mode",
"settingUIColumnPortrait": "UI Columns in Portrait Mode",
"localePl": "Polish \/ Polski",
"tooltipRemoveThisQuotedMessage": "Remove quoted message.",
"tooltipReplyToThisMessage": "Reply to this message",
"tooltipRejectContactRequest": "Reject this contact request",
"tooltipAcceptContactRequest": "Accept this contact request.",
"notificationNewMessageFromGroup": "New message in a group!",
"notificationNewMessageFromPeer": "New message from a contact!",
"tooltipHidePassword": "Hide Password",
"tooltipShowPassword": "Show Password",
"groupInviteSettingsWarning": "You have been invited to join a group! Please enable the Group Chat Experiment in Settings to view this Invitation.",
"shutdownCwtchAction": "Shutdown Cwtch",
"shutdownCwtchDialog": "Are you sure you want to shutdown Cwtch? This will close all connections, and exit the application.",
"shutdownCwtchDialogTitle": "Shutdown Cwtch?",
"shutdownCwtchTooltip": "Shutdown Cwtch",
"malformedMessage": "Malformed message",
"profileDeleteSuccess": "Successfully deleted profile",
"debugLog": "Turn on console debug logging",
"torNetworkStatus": "Tor network status",
"addContactFirst": "Add or pick a contact to begin chatting.",
"createProfileToBegin": "Please create or unlock a profile to begin",
"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",
"sendMessage": "Send Message",
"cancel": "Cancel",
"resetTor": "Reset",
"torStatus": "Tor Status",
"torVersion": "Tor Version",
"sendAnInvitation": "You sent an invitation for: ",
"contactSuggestion": "This is a contact suggestion for: ",
"rejected": "Rejected!",
"accepted": "Accepted!",
"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.",
"newPassword": "New Password",
"yesLeave": "Yes, Leave This Conversation",
"reallyLeaveThisGroupPrompt": "Are you sure you want to leave this conversation? All messages and attributes will be deleted.",
"leaveConversation": "Leave This Conversation",
"inviteToGroup": "You have been invited to join a group:",
"titleManageServers": "Manage Servers",
"successfullAddedContact": "Successfully added ",
"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.",
"titleManageProfiles": "Manage Cwtch Profiles",
"tooltipUnlockProfiles": "Unlock encrypted profiles by entering their password.",
"titleManageContacts": "Conversations",
"tooltipAddContact": "Add a new contact or conversation",
"tooltipOpenSettings": "Open the settings pane",
"contactAlreadyExists": "Contact Already Exists",
"invalidImportString": "Invalid import string",
"conversationSettings": "Conversation Settings",
"enterCurrentPasswordForDelete": "Please enter current password to delete this profile.",
"enableGroups": "Enable Group Chat",
"localeIt": "Italian \/ Italiano",
"localeEs": "Spanish \/ Español",
"todoPlaceholder": "Todo...",
"addNewItem": "Add a new item to the list",
"addListItem": "Add a New List Item",
"newConnectionPaneTitle": "New Connection",
"networkStatusOnline": "Online",
"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...",
"smallTextLabel": "Small",
"defaultScalingText": "Font Scaling",
"builddate": "Built on: %2",
"version": "Version %1",
"versionTor": "Version %1 with tor %2",
"experimentsEnabled": "Enable Experiments",
"themeDark": "Dark",
"themeLight": "Light",
"settingTheme": "Use Light Themes",
"largeTextLabel": "Large",
"settingInterfaceZoom": "Zoom level",
"localeDe": "German \/ Deutsch",
"localePt": "Portuguese \/ Portuguesa",
"localeFr": "French \/ Français",
"localeEn": "English \/ English",
"settingLanguage": "Language",
"blockUnknownLabel": "Block Unknown Contacts",
"zoomLabel": "Interface zoom (mostly affects text and button sizes)",
"versionBuilddate": "Version: %1 Built on: %2",
"cwtchSettingsTitle": "Cwtch Settings",
"unlock": "Unlock",
"yourServers": "Your Servers",
"yourProfiles": "Your Profiles",
"error0ProfilesLoadedForPassword": "0 profiles loaded with that password",
"password": "Password",
"enterProfilePassword": "Enter a password to view your profiles",
"addNewProfileBtn": "Add new profile",
"deleteConfirmText": "DELETE",
"deleteProfileConfirmBtn": "Really Delete Profile",
"deleteConfirmLabel": "Type DELETE to confirm",
"deleteProfileBtn": "Delete Profile",
"passwordChangeError": "Error changing password: Supplied password rejected",
"passwordErrorMatch": "Passwords do not match",
"saveProfileBtn": "Save Profile",
"createProfileBtn": "Create Profile",
"passwordErrorEmpty": "Password cannot be empty",
"password2Label": "Reenter password",
"password1Label": "Password",
"currentPasswordLabel": "Current Password",
"yourDisplayName": "Your Display Name",
"profileOnionLabel": "Send this address to contacts you want to connect with",
"noPasswordWarning": "Not using a password on this account means that all data stored locally will not be encrypted",
"radioNoPassword": "Unencrypted (No password)",
"radioUsePassword": "Password",
"editProfile": "Edit Profile",
"newProfile": "New Profile",
"defaultProfileName": "Alice",
"profileName": "Display name",
"editProfileTitle": "Edit Profile",
"addProfileTitle": "Add new profile",
"deleteBtn": "Delete",
"unblockBtn": "Unblock Contact",
"dontSavePeerHistory": "Delete History",
"savePeerHistoryDescription": "Determines whether to delete any history associated with the contact.",
"savePeerHistory": "Save History",
"blockBtn": "Block Contact",
"saveBtn": "Save",
"displayNameLabel": "Display Name",
"copiedToClipboardNotification": "Copied to Clipboard",
"addressLabel": "Address",
"puzzleGameBtn": "Puzzle Game",
"bulletinsBtn": "Bulletins",
"listsBtn": "Lists",
"chatBtn": "Chat",
"rejectGroupBtn": "Reject",
"acceptGroupBtn": "Accept",
"acceptGroupInviteLabel": "Do you want to accept the invitation to",
"newGroupBtn": "Create new group",
"copyBtn": "Copy",
"peerOfflineMessage": "Contact is offline, messages can't be delivered right now",
"peerBlockedMessage": "Contact is blocked",
"pendingLabel": "Pending",
"acknowledgedLabel": "Acknowledged",
"couldNotSendMsgError": "Could not send this message",
"dmTooltip": "Click to DM",
"membershipDescription": "Below is a list of users who have sent messages to the group. This list may not reflect all users who have access to the group.",
"addListItemBtn": "Add Item",
"peerNotOnline": "Contact is offline. Applications cannot be used right now.",
"searchList": "Search List",
"update": "Update",
"inviteBtn": "Invite",
"inviteToGroupLabel": "Invite to group",
"groupNameLabel": "Group Name",
"viewServerInfo": "Server Info",
"serverNotSynced": "Syncing New Messages (This can take some time)...",
"serverSynced": "Synced",
"serverConnectivityDisconnected": "Server Disconnected",
"serverConnectivityConnected": "Server Connected",
"serverInfo": "Server Information",
"invitationLabel": "Invitation",
"serverLabel": "Server",
"search": "Search...",
"blocked": "Blocked",
"pasteAddressToAddContact": "Paste a cwtch address, invitation or key bundle here to add a new conversation",
"titlePlaceholder": "title...",
"postNewBulletinLabel": "Post new bulletin",
"newBulletinLabel": "New Bulletin",
"joinGroup": "Join group",
"createGroup": "Create group",
"addPeer": "Add Contact",
"groupAddr": "Address",
"invitation": "Invitation",
"server": "Server",
"peerName": "Name",
"peerAddress": "Address",
"joinGroupTab": "Join a group",
"createGroupTab": "Create a group",
"addPeerTab": "Add a contact",
"createGroupBtn": "Create",
"defaultGroupName": "Awesome Group",
"createGroupTitle": "Create Group"
}

View File

@ -44,6 +44,8 @@ Future<void> main() async {
print("Cwtch version: ${EnvironmentConfig.BUILD_VER} built on: ${EnvironmentConfig.BUILD_DATE}");
LicenseRegistry.addLicense(() => licenses());
WidgetsFlutterBinding.ensureInitialized();
// window_manager requires (await recommended but probably not required if not using immediately)
windowManager.ensureInitialized();
print("runApp()");
return runApp(Flwtch());
}
@ -84,7 +86,6 @@ class FlwtchState extends State<Flwtch> with WindowListener {
print("initState: running...");
windowManager.addListener(this);
super.initState();
print("initState: registering notification, shutdown handlers...");
profs = ProfileListState();
@ -104,10 +105,12 @@ class FlwtchState extends State<Flwtch> with WindowListener {
new CwtchNotifier(profs, globalSettings, globalErrorHandler, globalTorStatus, newDesktopNotificationsManager(_notificationSelectConvo), globalAppState, globalServersList, this);
cwtch = CwtchFfi(cwtchNotifier);
}
startConnectivityListener();
print("initState: invoking cwtch.Start()");
cwtch.Start();
print("initState: starting connectivityListener");
startConnectivityListener();
print("initState: done!");
super.initState();
}
// connectivity listening is an optional enhancement feature that tries to listen for OS events about the network
@ -287,7 +290,8 @@ class FlwtchState extends State<Flwtch> with WindowListener {
);
// On Gnome follows up a clicked notification with a "Cwtch is ready" notification that takes you to the app. AFAICT just because Gnome is bad
// https://askubuntu.com/questions/1286206/how-to-skip-the-is-ready-notification-and-directly-open-apps-in-ubuntu-20-4
windowManager.focus();
await windowManager.show();
await windowManager.focus();
}
// using windowManager flutter plugin until proper lifecycle management lands in desktop
@ -302,6 +306,8 @@ class FlwtchState extends State<Flwtch> with WindowListener {
globalAppState.focus = false;
}
void onWindowClose() {}
@override
void dispose() {
globalAppState.SetModalState(ModalState.shutdown);

View File

@ -1,5 +1,6 @@
import 'dart:async';
import 'package:cwtch/config.dart';
import 'package:flutter/widgets.dart';
enum ModalState { none, storageMigration, shutdown }
@ -30,11 +31,13 @@ class AppState extends ChangeNotifier {
void SetAppError(String error) {
appError = error;
EnvironmentConfig.debugLog("App Error: ${appError}");
notifyListeners();
}
void SetModalState(ModalState newState) {
modalState = newState;
EnvironmentConfig.debugLog("Modal State: ${newState}");
notifyListeners();
}

View File

@ -264,6 +264,15 @@ class ContactInfoState extends ChangeNotifier {
}
}
bool canSend() {
if (this.isGroup == true) {
// We now have an out of sync warning so we will mark these as online...
return this.status == "Synced" && this.antispamTickets > 0;
} else {
return this.isOnline();
}
}
ConversationNotificationPolicy get notificationsPolicy => _notificationPolicy;
set notificationsPolicy(ConversationNotificationPolicy newVal) {

View File

@ -1,24 +1,26 @@
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.
/// Only one draft is stored per conversation.
class MessageDraft extends ChangeNotifier {
String? _messageText;
QuotedReference? _quotedReference;
TextEditingController ctrlCompose = TextEditingController();
static MessageDraft empty() {
return MessageDraft();
}
bool isEmpty() {
return (this._messageText == null && this._quotedReference == null) || (this._messageText != null && this._messageText!.isEmpty);
return (this._quotedReference == null) || (this.messageText.isEmpty);
}
String? get messageText => _messageText;
String get messageText => ctrlCompose.text;
set messageText(String? text) {
this._messageText = text;
set messageText(String text) {
this.ctrlCompose.text = text;
notifyListeners();
}
@ -35,6 +37,18 @@ class MessageDraft extends ChangeNotifier {
this._quotedReference = null;
notifyListeners();
}
void clearDraft() {
this._quotedReference = null;
this.ctrlCompose.clear();
notifyListeners();
}
@override
void dispose() {
ctrlCompose.dispose();
super.dispose();
}
}
/// A QuotedReference encapsulates the state of replied-to message.

View File

@ -4,6 +4,7 @@ import 'package:cwtch/config.dart';
import 'package:cwtch/models/message.dart';
import 'package:cwtch/models/messages/malformedmessage.dart';
import 'package:cwtch/widgets/malformedbubble.dart';
import 'package:cwtch/widgets/messageBubbleWidgetHelpers.dart';
import 'package:cwtch/widgets/messagerow.dart';
import 'package:cwtch/widgets/quotedmessage.dart';
import 'package:flutter/widgets.dart';
@ -39,15 +40,7 @@ class QuotedMessage extends Message {
);
var content = message["body"];
var formatMessages = Provider.of<Settings>(bcontext).isExperimentEnabled(FormattingExperiment);
return SelectableLinkify(
text: content + '\u202F',
options: LinkifyOptions(messageFormatting: formatMessages, parseLinks: false, looseUrl: true, defaultToHttps: true),
linkifiers: [UrlLinkifier()],
onOpen: null,
textAlign: TextAlign.left,
style: TextStyle(fontSize: 12.0 * Provider.of<Settings>(context).fontScaling, fontWeight: FontWeight.normal, fontFamily: "Inter", overflow: TextOverflow.ellipsis),
codeStyle: TextStyle(fontSize: 12.0 * Provider.of<Settings>(context).fontScaling, fontWeight: FontWeight.normal, fontFamily: "Inter", overflow: TextOverflow.ellipsis),
textWidthBasis: TextWidthBasis.longestLine);
return compileMessageContentWidget(context, false, content, FocusNode(), formatMessages, false);
} catch (e) {
return MalformedBubble();
}

View File

@ -12,6 +12,7 @@ import 'package:provider/provider.dart';
import '../../settings.dart';
import '../../third_party/linkify/flutter_linkify.dart';
import '../../widgets/messageBubbleWidgetHelpers.dart';
class TextMessage extends Message {
final MessageMetadata metadata;
@ -25,20 +26,8 @@ class TextMessage extends Message {
value: this.metadata,
builder: (bcontext, child) {
var formatMessages = Provider.of<Settings>(bcontext).isExperimentEnabled(FormattingExperiment);
return SelectableLinkify(
text: content + '\u202F',
options: LinkifyOptions(messageFormatting: formatMessages, parseLinks: false, looseUrl: true, defaultToHttps: true),
linkifiers: [UrlLinkifier()],
onOpen: null,
textAlign: TextAlign.left,
style: TextStyle(overflow: TextOverflow.fade, fontFamily: "Inter", fontSize: 12.0 * Provider.of<Settings>(context).fontScaling),
linkStyle: TextStyle(overflow: TextOverflow.fade, fontFamily: "Inter", fontSize: 12.0 * Provider.of<Settings>(context).fontScaling),
codeStyle: TextStyle(
overflow: TextOverflow.ellipsis,
fontFamily: "RobotoMono",
),
textWidthBasis: TextWidthBasis.parent,
);
return compileMessageContentWidget(context, false, content, FocusNode(), formatMessages, false);
;
});
}

View File

@ -6,7 +6,6 @@ import 'package:cwtch/main.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
import 'package:win_toast/win_toast.dart';
import 'package:desktop_notifications/desktop_notifications.dart' as linux_notifications;
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:flutter_local_notifications_linux/flutter_local_notifications_linux.dart';
import 'package:flutter_local_notifications_linux/src/model/hint.dart';
@ -32,10 +31,33 @@ class NullNotificationsManager implements NotificationsManager {
class WindowsNotificationManager implements NotificationsManager {
bool active = false;
bool initialized = false;
late Future<void> Function(String, int) notificationSelectConvo;
WindowsNotificationManager() {
WindowsNotificationManager(Future<void> Function(String, int) notificationSelectConvo) {
this.notificationSelectConvo = notificationSelectConvo;
scheduleMicrotask(() async {
initialized = await WinToast.instance().initialize(appName: 'cwtch', productName: 'Cwtch', companyName: 'Open Privacy Research Society');
/*
* WinToast 0.3.0 code for when we can compile it
*
var init = await WinToast.instance().initialize(
aumId: 'OpenPrivacyResearchSociety.Cwtch',
displayName: 'Cwtch',
iconPath: '', // TODO NEED ICON
clsid: 'cwtch',
);
WinToast.instance().setActivatedCallback((event) {
if (event.argument != "close") {
try {
Map<String, dynamic> payloadMap = jsonDecode(event.argument);
var payload = NotificationPayload.fromJson(payloadMap);
notificationSelectConvo(payload.profileOnion, payload.convoId);
} catch (e) {
/* it failed, is ok, may have been 'close'? */
}
}
});*/
initialized = true;
});
}
@ -44,7 +66,8 @@ class WindowsNotificationManager implements NotificationsManager {
if (!active) {
active = true;
WinToast.instance().clear();
final toast = await WinToast.instance().showToast(type: ToastType.text01, title: message);
final toast = await WinToast.instance().showToast(
type: ToastType.text01, title: message);
toast?.eventStream.listen((event) {
if (event is ActivatedEvent) {
WinToast.instance().bringWindowToFront();
@ -52,6 +75,34 @@ class WindowsNotificationManager implements NotificationsManager {
active = false;
});
}
/*
* WinToast 0.3.0 code for when we can compile it
*
WinToast.instance().clear();
await WinToast.instance().showToast(
toast: Toast(duration: ToastDuration.short, children: [
ToastChildAudio(source: ToastAudioSource.im),
ToastChildVisual(
binding: ToastVisualBinding(children: [
ToastVisualBindingChildText(
text: message,
id: 1,
),
])),
ToastChildActions(children: [
ToastAction(
content: "Open",
arguments: jsonEncode(NotificationPayload(profile, conversationId)),
),
ToastAction(
content: "Close",
arguments: "close",
),
]),
]));
active = false;
}*/
}
}
}
@ -113,12 +164,12 @@ class NixNotificationManager implements NotificationsManager {
linuxAssetsPath = "";
}
final MacOSInitializationSettings initializationSettingsMacOS = MacOSInitializationSettings(defaultPresentSound: false);
var linuxIcon = FilePathLinuxIcon(path.join(linuxAssetsPath, 'assets/knott.png'));
final LinuxInitializationSettings initializationSettingsLinux = LinuxInitializationSettings(defaultActionName: 'Open notification', defaultIcon: linuxIcon, defaultSuppressSound: true);
final InitializationSettings initializationSettings = InitializationSettings(android: null, iOS: null, macOS: initializationSettingsMacOS, linux: initializationSettingsLinux);
final InitializationSettings initializationSettings =
InitializationSettings(android: null, iOS: null, macOS: DarwinInitializationSettings(defaultPresentSound: false), linux: initializationSettingsLinux);
flutterLocalNotificationsPlugin.resolvePlatformSpecificImplementation<MacOSFlutterLocalNotificationsPlugin>()?.requestPermissions(
alert: true,
@ -126,7 +177,9 @@ class NixNotificationManager implements NotificationsManager {
sound: false,
);
await flutterLocalNotificationsPlugin.initialize(initializationSettings, onSelectNotification: selectNotification);
await flutterLocalNotificationsPlugin.initialize(
initializationSettings,
);
});
}
@ -138,7 +191,7 @@ class NixNotificationManager implements NotificationsManager {
message,
'',
NotificationDetails(
linux: LinuxNotificationDetails(suppressSound: true, category: LinuxNotificationCategory.imReceived(), icon: FilePathLinuxIcon(path.join(linuxAssetsPath, 'assets/knott.png')))),
linux: LinuxNotificationDetails(suppressSound: true, category: LinuxNotificationCategory.imReceived, icon: FilePathLinuxIcon(path.join(linuxAssetsPath, 'assets/knott.png')))),
payload: jsonEncode(NotificationPayload(profile, conversationId)));
}
}
@ -173,7 +226,7 @@ NotificationsManager newDesktopNotificationsManager(Future<void> Function(String
}
} else if (Platform.isWindows) {
try {
return WindowsNotificationManager();
return WindowsNotificationManager(notificationSelectConvo);
} catch (e) {
EnvironmentConfig.debugLog("Failed to create Windows desktoasts notification manager");
}

View File

@ -192,6 +192,11 @@ class Settings extends ChangeNotifier {
double get fontScaling => _fontScaling;
// a convenience function to scale fonts dynamically...
TextStyle scaleFonts(TextStyle input) {
return input.copyWith(fontSize: (input.fontSize ?? 12) * this.fontScaling);
}
/// Switch the Locale of the App
switchLocale(Locale newLocale) {
locale = newLocale;

View File

@ -19,6 +19,13 @@ import 'neon2.dart';
const mode_light = "light";
const mode_dark = "dark";
final TextStyle defaultSmallTextStyle = TextStyle(fontFamily: "Inter", fontWeight: FontWeight.normal, fontSize: 10);
final TextStyle defaultMessageTextStyle = TextStyle(fontFamily: "Inter", fontWeight: FontWeight.normal, fontSize: 12);
final TextStyle defaultFormLabelTextStyle = TextStyle(fontFamily: "Inter", fontWeight: FontWeight.bold, fontSize: 20);
final TextStyle defaultTextStyle = TextStyle(fontFamily: "Inter", fontWeight: FontWeight.w500, fontSize: 12);
final TextStyle defaultTextButtonStyle = defaultTextStyle.copyWith(fontWeight: FontWeight.bold);
final TextStyle defaultDropDownMenuItemTextStyle = TextStyle(fontFamily: "Inter", fontWeight: FontWeight.bold, fontSize: 16);
final themes = {
cwtch_theme: {mode_light: CwtchLight(), mode_dark: CwtchDark()},
ghost_theme: {mode_light: GhostLight(), mode_dark: GhostDark()},
@ -177,6 +184,7 @@ ThemeData mkThemeData(Settings opaque) {
? opaque.current().defaultButtonDisabledColor
: null),
enableFeedback: true,
textStyle: MaterialStateProperty.all(opaque.scaleFonts(defaultTextButtonStyle)),
padding: MaterialStateProperty.all(EdgeInsets.all(20)),
shape: MaterialStateProperty.all(RoundedRectangleBorder(
borderRadius: BorderRadius.circular(6.0),
@ -186,9 +194,12 @@ ThemeData mkThemeData(Settings opaque) {
scrollbarTheme: ScrollbarThemeData(isAlwaysShown: false, thumbColor: MaterialStateProperty.all(opaque.current().scrollbarDefaultColor)),
tabBarTheme: TabBarTheme(
labelColor: opaque.current().mainTextColor,
unselectedLabelColor: opaque.current().mainTextColor,
indicator: UnderlineTabIndicator(borderSide: BorderSide(color: opaque.current().defaultButtonActiveColor))),
labelColor: opaque.current().mainTextColor,
unselectedLabelColor: opaque.current().mainTextColor,
indicator: UnderlineTabIndicator(borderSide: BorderSide(color: opaque.current().defaultButtonActiveColor)),
labelStyle: opaque.scaleFonts(defaultTextButtonStyle),
unselectedLabelStyle: opaque.scaleFonts(defaultTextStyle),
),
dialogTheme: DialogTheme(
backgroundColor: opaque.current().backgroundPaneColor,
titleTextStyle: TextStyle(fontFamily: "Inter", fontWeight: FontWeight.bold, color: opaque.current().mainTextColor),
@ -199,8 +210,8 @@ ThemeData mkThemeData(Settings opaque) {
textTheme: TextTheme(
// NOTE: The following font scales were arrived at after consulting the material text scale
// docs: https://m3.material.io/styles/typography/type-scale-tokens and some trial and error
displayMedium: TextStyle(fontFamily: "Inter", fontSize: opaque.fontScaling * 16.0, color: opaque.current().mainTextColor),
displaySmall: TextStyle(fontFamily: "Inter", fontSize: opaque.fontScaling * 14.0, color: opaque.current().mainTextColor),
displayMedium: TextStyle(fontFamily: "Inter", fontSize: opaque.fontScaling * 16.0, color: opaque.current().mainTextColor),
displayLarge: TextStyle(fontFamily: "Inter", fontSize: opaque.fontScaling * 18.0, color: opaque.current().mainTextColor),
titleSmall: TextStyle(fontFamily: "Inter", fontWeight: FontWeight.bold, fontSize: opaque.fontScaling * 16.0, color: opaque.current().mainTextColor),
titleLarge: TextStyle(fontFamily: "Inter", fontWeight: FontWeight.bold, fontSize: opaque.fontScaling * 18.0, color: opaque.current().mainTextColor),
@ -212,8 +223,8 @@ ThemeData mkThemeData(Settings opaque) {
headlineMedium: TextStyle(fontFamily: "Inter", fontWeight: FontWeight.bold, fontSize: opaque.fontScaling * 26.0, color: opaque.current().mainTextColor),
headlineLarge: TextStyle(fontFamily: "Inter", fontWeight: FontWeight.bold, fontSize: opaque.fontScaling * 28.0, color: opaque.current().mainTextColor),
labelSmall: TextStyle(fontFamily: "Inter", fontWeight: FontWeight.w100, fontSize: opaque.fontScaling * 14.0, color: opaque.current().mainTextColor),
labelLarge: TextStyle(fontFamily: "Inter", fontWeight: FontWeight.w200, fontSize: opaque.fontScaling * 16.0, color: opaque.current().mainTextColor),
labelMedium: TextStyle(fontFamily: "Inter", fontWeight: FontWeight.w300, fontSize: opaque.fontScaling * 18.0, color: opaque.current().mainTextColor),
labelMedium: TextStyle(fontFamily: "Inter", fontWeight: FontWeight.w300, fontSize: opaque.fontScaling * 16.0, color: opaque.current().mainTextColor),
labelLarge: TextStyle(fontFamily: "Inter", fontWeight: FontWeight.w200, fontSize: opaque.fontScaling * 18.0, color: opaque.current().mainTextColor),
),
switchTheme: SwitchThemeData(
overlayColor: MaterialStateProperty.all(opaque.current().defaultButtonActiveColor),

View File

@ -35,7 +35,7 @@ android {
}
defaultConfig {
minSdkVersion 16
minSdkVersion 19
targetSdkVersion 31
//testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

View File

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-all.zip
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME

View File

@ -6,7 +6,7 @@ repository: https://github.com/fluttercommunity/plus_plugins/tree/main/packages/
environment:
sdk: ">=2.12.0 <3.0.0"
flutter: ">=2.11.0"
flutter: ">=3.7.0"
dependencies:
flutter:

View File

@ -472,7 +472,7 @@ class _ContactsViewState extends State<ContactsView> {
builder: (BuildContext context) {
return Wrap(children: <Widget>[
Center(
child: QrImage(
child: QrImageView(
data: profile_code,
version: QrVersions.auto,
size: 400.0,

View File

@ -128,7 +128,12 @@ class _GlobalSettingsViewState extends State<GlobalSettingsView> {
items: AppLocalizations.supportedLocales.map<DropdownMenuItem<String>>((Locale value) {
return DropdownMenuItem<String>(
value: value.toString(),
child: Text(key: Key("dropdownLanguage" + value.languageCode), getLanguageFull(context, value.languageCode, value.countryCode)),
child: Text(
key: Key("dropdownLanguage" + value.languageCode),
getLanguageFull(context, value.languageCode, value.countryCode),
style: settings.scaleFonts(defaultDropDownMenuItemTextStyle),
overflow: TextOverflow.ellipsis,
),
);
}).toList()))),
SwitchListTile(
@ -165,7 +170,7 @@ class _GlobalSettingsViewState extends State<GlobalSettingsView> {
items: themes.keys.map<DropdownMenuItem<String>>((String themeId) {
return DropdownMenuItem<String>(
value: themeId,
child: Text(getThemeName(context, themeId)), //"ddi_$themeId", key: Key("ddi_$themeId")),
child: Text(getThemeName(context, themeId), style: settings.scaleFonts(defaultDropDownMenuItemTextStyle)), //"ddi_$themeId", key: Key("ddi_$themeId")),
);
}).toList())),
leading: Icon(Icons.palette, color: settings.current().mainTextColor),
@ -185,7 +190,7 @@ class _GlobalSettingsViewState extends State<GlobalSettingsView> {
items: Settings.uiColumnModeOptions(false).map<DropdownMenuItem<String>>((DualpaneMode value) {
return DropdownMenuItem<String>(
value: value.toString(),
child: Text(Settings.uiColumnModeToString(value, context)),
child: Text(Settings.uiColumnModeToString(value, context), style: settings.scaleFonts(defaultDropDownMenuItemTextStyle)),
);
}).toList()))),
ListTile(
@ -193,7 +198,6 @@ class _GlobalSettingsViewState extends State<GlobalSettingsView> {
AppLocalizations.of(context)!.settingUIColumnLandscape,
textWidthBasis: TextWidthBasis.longestLine,
softWrap: true,
style: TextStyle(color: settings.current().mainTextColor),
),
leading: Icon(Icons.stay_primary_landscape, color: settings.current().mainTextColor),
trailing: Container(
@ -210,10 +214,7 @@ class _GlobalSettingsViewState extends State<GlobalSettingsView> {
items: Settings.uiColumnModeOptions(true).map<DropdownMenuItem<String>>((DualpaneMode value) {
return DropdownMenuItem<String>(
value: value.toString(),
child: Text(
Settings.uiColumnModeToString(value, context),
overflow: TextOverflow.ellipsis,
),
child: Text(Settings.uiColumnModeToString(value, context), overflow: TextOverflow.ellipsis, style: settings.scaleFonts(defaultDropDownMenuItemTextStyle)),
);
}).toList())))),
ListTile(
@ -305,10 +306,7 @@ class _GlobalSettingsViewState extends State<GlobalSettingsView> {
items: NotificationPolicy.values.map<DropdownMenuItem<NotificationPolicy>>((NotificationPolicy value) {
return DropdownMenuItem<NotificationPolicy>(
value: value,
child: Text(
Settings.notificationPolicyToString(value, context),
overflow: TextOverflow.ellipsis,
),
child: Text(Settings.notificationPolicyToString(value, context), overflow: TextOverflow.ellipsis, style: settings.scaleFonts(defaultDropDownMenuItemTextStyle)),
);
}).toList())),
leading: Icon(CwtchIcons.chat_bubble_empty_24px, color: settings.current().mainTextColor),
@ -328,10 +326,7 @@ class _GlobalSettingsViewState extends State<GlobalSettingsView> {
items: NotificationContent.values.map<DropdownMenuItem<NotificationContent>>((NotificationContent value) {
return DropdownMenuItem<NotificationContent>(
value: value,
child: Text(
Settings.notificationContentToString(value, context),
overflow: TextOverflow.ellipsis,
),
child: Text(Settings.notificationContentToString(value, context), overflow: TextOverflow.ellipsis, style: settings.scaleFonts(defaultDropDownMenuItemTextStyle)),
);
}).toList())),
leading: Icon(CwtchIcons.chat_bubble_empty_24px, color: settings.current().mainTextColor),
@ -747,6 +742,15 @@ String getLanguageFull(context, String languageCode, String? countryCode) {
if (languageCode == "ja") {
return AppLocalizations.of(context)!.localeJa;
}
if (languageCode == "sv") {
return AppLocalizations.of(context)!.localeSv;
}
if (languageCode == "sw") {
return AppLocalizations.of(context)!.localeSw;
}
if (languageCode == "uk") {
return AppLocalizations.of(context)!.localeUk;
}
return languageCode;
}

View File

@ -2,6 +2,7 @@ import 'package:cwtch/cwtch_icons_icons.dart';
import 'package:cwtch/models/appstate.dart';
import 'package:cwtch/models/contact.dart';
import 'package:cwtch/models/profile.dart';
import 'package:cwtch/themes/opaque.dart';
import 'package:flutter/services.dart';
import 'package:cwtch/widgets/buttontextfield.dart';
import 'package:cwtch/widgets/cwtchlabel.dart';
@ -180,7 +181,7 @@ class _GroupSettingsViewState extends State<GroupSettingsView> {
icon: Icon(CwtchIcons.leave_group),
label: Text(
AppLocalizations.of(context)!.leaveConversation,
style: TextStyle(decoration: TextDecoration.underline),
style: settings.scaleFonts(defaultTextButtonStyle.copyWith(decoration: TextDecoration.underline)),
),
))
])

View File

@ -44,7 +44,6 @@ class MessageView extends StatefulWidget {
}
class _MessageViewState extends State<MessageView> {
final ctrlrCompose = TextEditingController();
final focusNode = FocusNode();
int selectedContact = -1;
ItemPositionsListener scrollListener = ItemPositionsListener.create();
@ -68,7 +67,6 @@ class _MessageViewState extends State<MessageView> {
showDown = false;
}
});
ctrlrCompose.text = Provider.of<ContactInfoState>(context, listen: false).messageDraft.messageText ?? "";
super.initState();
}
@ -88,7 +86,6 @@ class _MessageViewState extends State<MessageView> {
@override
void dispose() {
focusNode.dispose();
ctrlrCompose.dispose();
super.dispose();
}
@ -321,22 +318,21 @@ class _MessageViewState extends State<MessageView> {
void _sendMessage([String? ignoredParam]) {
// Do this after we trim to preserve enter-behaviour...
bool isOffline = Provider.of<ContactInfoState>(context, listen: false).isOnline() == false;
bool performingAntiSpam = Provider.of<ContactInfoState>(context, listen: false).antispamTickets == 0;
bool cannotSend = Provider.of<ContactInfoState>(context, listen: false).canSend() == false;
bool isGroup = Provider.of<ContactInfoState>(context, listen: false).isGroup;
if (isOffline || (isGroup && performingAntiSpam)) {
if (cannotSend) {
return;
}
// Trim message
final messageWithoutNewLine = ctrlrCompose.value.text.trimRight();
ctrlrCompose.value = TextEditingValue(text: messageWithoutNewLine, selection: TextSelection.fromPosition(TextPosition(offset: messageWithoutNewLine.length)));
var messageText = Provider.of<ContactInfoState>(context, listen: false).messageDraft.messageText ?? "";
final messageWithoutNewLine = messageText.trimRight();
// peers and groups currently have different length constraints (servers can store less)...
var actualMessageLength = ctrlrCompose.value.text.length;
var actualMessageLength = messageText.length;
var lengthOk = (isGroup && actualMessageLength < GroupMessageLengthMax) || actualMessageLength <= P2PMessageLengthMax;
if (ctrlrCompose.value.text.isNotEmpty && lengthOk) {
if (messageWithoutNewLine.isNotEmpty && lengthOk) {
if (Provider.of<AppState>(context, listen: false).selectedConversation != null && Provider.of<ContactInfoState>(context, listen: false).messageDraft.getQuotedMessage() != null) {
var conversationId = Provider.of<AppState>(context, listen: false).selectedConversation!;
MessageCache? cache = Provider.of<ProfileInfoState>(context, listen: false).contactList.getContact(conversationId)?.messageCache;
@ -347,7 +343,7 @@ class _MessageViewState extends State<MessageView> {
var bytes1 = utf8.encode(data!.metadata.senderHandle + data.wrapper);
var digest1 = sha256.convert(bytes1);
var contentHash = base64Encode(digest1.bytes);
var quotedMessage = jsonEncode(QuotedMessageStructure(contentHash, ctrlrCompose.value.text));
var quotedMessage = jsonEncode(QuotedMessageStructure(contentHash, messageWithoutNewLine));
ChatMessage cm = new ChatMessage(o: QuotedMessageOverlay, d: quotedMessage);
Provider.of<FlwtchState>(context, listen: false)
.cwtch
@ -359,7 +355,7 @@ class _MessageViewState extends State<MessageView> {
Provider.of<ContactInfoState>(context, listen: false).messageDraft.clearQuotedReference();
});
} else {
ChatMessage cm = new ChatMessage(o: TextMessageOverlay, d: ctrlrCompose.value.text);
ChatMessage cm = new ChatMessage(o: TextMessageOverlay, d: messageWithoutNewLine);
Provider.of<FlwtchState>(context, listen: false)
.cwtch
.SendMessage(Provider.of<ContactInfoState>(context, listen: false).profileOnion, Provider.of<ContactInfoState>(context, listen: false).identifier, jsonEncode(cm))
@ -391,8 +387,7 @@ class _MessageViewState extends State<MessageView> {
// At this point we have decided to send the text to the backend, failure is still possible
// but it will show as an error-ed message, as such the draft can be purged.
Provider.of<ContactInfoState>(context, listen: false).messageDraft = MessageDraft.empty();
ctrlrCompose.clear();
Provider.of<ContactInfoState>(context, listen: false).messageDraft.clearDraft();
var profileOnion = Provider.of<ContactInfoState>(context, listen: false).profileOnion;
var identifier = Provider.of<ContactInfoState>(context, listen: false).identifier;
@ -424,7 +419,7 @@ class _MessageViewState extends State<MessageView> {
var wdgMessage = Padding(
padding: EdgeInsets.all(8),
child: SelectableLinkify(
text: ctrlrCompose.text + '\n',
text: Provider.of<ContactInfoState>(context).messageDraft.messageText + '\n',
options: LinkifyOptions(messageFormatting: true, parseLinks: showClickableLinks, looseUrl: true, defaultToHttps: true),
linkifiers: [UrlLinkifier()],
onOpen: showClickableLinks ? null : null,
@ -468,7 +463,7 @@ class _MessageViewState extends State<MessageView> {
margin: EdgeInsets.all(2),
// 164 minimum height + 16px for every line of text so the entire message is displayed when previewed.
height: 164 + ((ctrlrCompose.text.split("\n").length - 1) * 16),
height: 164 + ((Provider.of<ContactInfoState>(context).messageDraft.messageText.split("\n").length - 1) * 16),
child: Column(
children: [
Row(mainAxisAlignment: MainAxisAlignment.start, mainAxisSize: MainAxisSize.max, children: [preview]),
@ -483,11 +478,11 @@ class _MessageViewState extends State<MessageView> {
}
Widget _buildComposeBox(BuildContext context) {
bool isOffline = Provider.of<ContactInfoState>(context).isOnline() == false;
bool cannotSend = Provider.of<ContactInfoState>(context).canSend() == false;
bool isGroup = Provider.of<ContactInfoState>(context).isGroup;
var showToolbar = Provider.of<Settings>(context).isExperimentEnabled(FormattingExperiment);
var charLength = ctrlrCompose.value.text.characters.length;
var expectedLength = ctrlrCompose.value.text.length;
var charLength = Provider.of<ContactInfoState>(context).messageDraft.messageText.characters.length;
var expectedLength = Provider.of<ContactInfoState>(context).messageDraft.messageText.length;
var numberOfBytesMoreThanChar = (expectedLength - charLength);
var bold = IconButton(
@ -495,12 +490,14 @@ class _MessageViewState extends State<MessageView> {
tooltip: AppLocalizations.of(context)!.tooltipBoldText,
onPressed: () {
setState(() {
var ctrlrCompose = Provider.of<ContactInfoState>(context, listen: false).messageDraft.ctrlCompose;
var selected = ctrlrCompose.selection.textInside(ctrlrCompose.text);
var selection = ctrlrCompose.selection;
var start = ctrlrCompose.selection.start;
var end = ctrlrCompose.selection.end;
ctrlrCompose.text = ctrlrCompose.text.replaceRange(start, end, "**" + selected + "**");
ctrlrCompose.selection = selection.copyWith(baseOffset: selection.start + 2, extentOffset: selection.start + 2);
Provider.of<ContactInfoState>(context, listen: false).messageDraft.ctrlCompose = ctrlrCompose;
});
});
@ -509,12 +506,14 @@ class _MessageViewState extends State<MessageView> {
tooltip: AppLocalizations.of(context)!.tooltipItalicize,
onPressed: () {
setState(() {
var ctrlrCompose = Provider.of<ContactInfoState>(context, listen: false).messageDraft.ctrlCompose;
var selected = ctrlrCompose.selection.textInside(ctrlrCompose.text);
var selection = ctrlrCompose.selection;
var start = ctrlrCompose.selection.start;
var end = ctrlrCompose.selection.end;
ctrlrCompose.text = ctrlrCompose.text.replaceRange(start, end, "*" + selected + "*");
ctrlrCompose.selection = selection.copyWith(baseOffset: selection.start + 1, extentOffset: selection.start + 1);
Provider.of<ContactInfoState>(context, listen: false).messageDraft.ctrlCompose = ctrlrCompose;
});
});
@ -523,12 +522,14 @@ class _MessageViewState extends State<MessageView> {
tooltip: AppLocalizations.of(context)!.tooltipCode,
onPressed: () {
setState(() {
var ctrlrCompose = Provider.of<ContactInfoState>(context, listen: false).messageDraft.ctrlCompose;
var selected = ctrlrCompose.selection.textInside(ctrlrCompose.text);
var selection = ctrlrCompose.selection;
var start = ctrlrCompose.selection.start;
var end = ctrlrCompose.selection.end;
ctrlrCompose.text = ctrlrCompose.text.replaceRange(start, end, "`" + selected + "`");
ctrlrCompose.selection = selection.copyWith(baseOffset: selection.start + 1, extentOffset: selection.start + 1);
Provider.of<ContactInfoState>(context, listen: false).messageDraft.ctrlCompose = ctrlrCompose;
});
});
@ -537,12 +538,14 @@ class _MessageViewState extends State<MessageView> {
tooltip: AppLocalizations.of(context)!.tooltipSuperscript,
onPressed: () {
setState(() {
var ctrlrCompose = Provider.of<ContactInfoState>(context, listen: false).messageDraft.ctrlCompose;
var selected = ctrlrCompose.selection.textInside(ctrlrCompose.text);
var selection = ctrlrCompose.selection;
var start = ctrlrCompose.selection.start;
var end = ctrlrCompose.selection.end;
ctrlrCompose.text = ctrlrCompose.text.replaceRange(start, end, "^" + selected + "^");
ctrlrCompose.selection = selection.copyWith(baseOffset: selection.start + 1, extentOffset: selection.start + 1);
Provider.of<ContactInfoState>(context, listen: false).messageDraft.ctrlCompose = ctrlrCompose;
});
});
@ -551,12 +554,14 @@ class _MessageViewState extends State<MessageView> {
tooltip: AppLocalizations.of(context)!.tooltipSubscript,
onPressed: () {
setState(() {
var ctrlrCompose = Provider.of<ContactInfoState>(context, listen: false).messageDraft.ctrlCompose;
var selected = ctrlrCompose.selection.textInside(ctrlrCompose.text);
var selection = ctrlrCompose.selection;
var start = ctrlrCompose.selection.start;
var end = ctrlrCompose.selection.end;
ctrlrCompose.text = ctrlrCompose.text.replaceRange(start, end, "_" + selected + "_");
ctrlrCompose.selection = selection.copyWith(baseOffset: selection.start + 1, extentOffset: selection.start + 1);
Provider.of<ContactInfoState>(context, listen: false).messageDraft.ctrlCompose = ctrlrCompose;
});
});
@ -565,12 +570,14 @@ class _MessageViewState extends State<MessageView> {
tooltip: AppLocalizations.of(context)!.tooltipStrikethrough,
onPressed: () {
setState(() {
var ctrlrCompose = Provider.of<ContactInfoState>(context, listen: false).messageDraft.ctrlCompose;
var selected = ctrlrCompose.selection.textInside(ctrlrCompose.text);
var selection = ctrlrCompose.selection;
var start = ctrlrCompose.selection.start;
var end = ctrlrCompose.selection.end;
ctrlrCompose.text = ctrlrCompose.text.replaceRange(start, end, "~~" + selected + "~~");
ctrlrCompose.selection = selection.copyWith(baseOffset: selection.start + 2, extentOffset: selection.start + 2);
Provider.of<ContactInfoState>(context, listen: false).messageDraft.ctrlCompose = ctrlrCompose;
});
});
@ -600,7 +607,7 @@ class _MessageViewState extends State<MessageView> {
padding: EdgeInsets.all(8),
child: TextFormField(
key: Key('txtCompose'),
controller: ctrlrCompose,
controller: Provider.of<ContactInfoState>(context).messageDraft.ctrlCompose,
focusNode: focusNode,
autofocus: !Platform.isAndroid,
textInputAction: TextInputAction.newline,
@ -615,18 +622,17 @@ class _MessageViewState extends State<MessageView> {
style: TextStyle(
fontFamily: "Inter",
fontSize: 12.0 * Provider.of<Settings>(context).fontScaling,
fontWeight: FontWeight.w500,
fontWeight: FontWeight.w300,
),
enabled: true, // always allow editing...
onChanged: (String x) {
Provider.of<ContactInfoState>(context, listen: false).messageDraft.messageText = x;
setState(() {
// we need to force a rerender here to update the max length count
});
},
decoration: InputDecoration(
hintText: isOffline ? "" : AppLocalizations.of(context)!.placeholderEnterMessage,
hintText: AppLocalizations.of(context)!.placeholderEnterMessage,
hintStyle: TextStyle(fontFamily: "Inter", fontSize: 10.0 * Provider.of<Settings>(context).fontScaling, color: Provider.of<Settings>(context).theme.sendHintTextColor),
enabledBorder: InputBorder.none,
focusedBorder: InputBorder.none,
@ -635,13 +641,13 @@ class _MessageViewState extends State<MessageView> {
key: Key("btnSend"),
style: ElevatedButton.styleFrom(padding: EdgeInsets.all(0.0), shape: new RoundedRectangleBorder(borderRadius: new BorderRadius.circular(45.0))),
child: Tooltip(
message: isOffline
message: cannotSend
? (isGroup ? AppLocalizations.of(context)!.serverNotSynced : AppLocalizations.of(context)!.peerOfflineMessage)
: (isGroup && Provider.of<ContactInfoState>(context, listen: false).antispamTickets == 0)
? AppLocalizations.of(context)!.acquiringTicketsFromServer
: AppLocalizations.of(context)!.sendMessage,
child: Icon(CwtchIcons.send_24px, size: 24, color: Provider.of<Settings>(context).theme.defaultButtonTextColor)),
onPressed: isOffline || (isGroup && Provider.of<ContactInfoState>(context, listen: false).antispamTickets == 0) ? null : _sendMessage,
onPressed: cannotSend || (isGroup && Provider.of<ContactInfoState>(context, listen: false).antispamTickets == 0) ? null : _sendMessage,
))),
)));
@ -727,7 +733,8 @@ class _MessageViewState extends State<MessageView> {
if (event is RawKeyUpEvent) {
if ((data.logicalKey == LogicalKeyboardKey.enter && !event.isShiftPressed) || data.logicalKey == LogicalKeyboardKey.numpadEnter && !event.isShiftPressed) {
// Don't send when inserting a new line that is not at the end of the message
if (ctrlrCompose.selection.baseOffset != ctrlrCompose.text.length) {
if (Provider.of<ContactInfoState>(context, listen: false).messageDraft.ctrlCompose.selection.baseOffset !=
Provider.of<ContactInfoState>(context, listen: false).messageDraft.ctrlCompose.text.length) {
return;
}
_sendMessage();
@ -735,8 +742,6 @@ class _MessageViewState extends State<MessageView> {
}
}
void placeHolder() => {};
// explicitly passing BuildContext ctx here is important, change at risk to own health
// otherwise some Providers will become inaccessible to subwidgets...?
// https://stackoverflow.com/a/63818697

View File

@ -1,4 +1,5 @@
import 'package:cwtch/models/appstate.dart';
import 'package:cwtch/themes/opaque.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
@ -52,7 +53,7 @@ class _SplashViewState extends State<SplashView> {
: appState.modalState == ModalState.storageMigration
? AppLocalizations.of(context)!.storageMigrationModalMessage
: AppLocalizations.of(context)!.shuttingDownApp, // Todo l10n AppLocalizations.of(context)!.storageMigrationModalMessage
style: TextStyle(
style: defaultTextButtonStyle.copyWith(
fontSize: 16.0, color: appState.appError == "" ? Provider.of<Settings>(context).theme.mainTextColor : Provider.of<Settings>(context).theme.textfieldErrorColor))),
Visibility(
visible: appState.modalState == ModalState.storageMigration || appState.modalState == ModalState.shutdown,

View File

@ -1,3 +1,4 @@
import 'package:cwtch/themes/opaque.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../settings.dart';
@ -18,7 +19,7 @@ class _CwtchLabelState extends State<CwtchLabel> {
return Consumer<Settings>(builder: (context, theme, child) {
return Text(
widget.label,
style: TextStyle(fontSize: 20, color: theme.current().mainTextColor),
style: Provider.of<Settings>(context).scaleFonts(defaultFormLabelTextStyle),
);
});
}

View File

@ -7,8 +7,10 @@ import 'package:cwtch/models/contact.dart';
import 'package:cwtch/models/filedownloadprogress.dart';
import 'package:cwtch/models/message.dart';
import 'package:cwtch/models/profile.dart';
import 'package:cwtch/themes/opaque.dart';
import 'package:cwtch/widgets/malformedbubble.dart';
import 'package:file_picker_desktop/file_picker_desktop.dart';
import 'package:cwtch/widgets/messageBubbleWidgetHelpers.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
@ -147,18 +149,10 @@ class FileBubbleState extends State<FileBubble> {
var wdgSender = Visibility(
visible: widget.interactive,
child: Container(
height: 14 * Provider.of<Settings>(context).fontScaling,
clipBehavior: Clip.hardEdge,
decoration: BoxDecoration(),
child: SelectableText(senderDisplayStr + '\u202F',
style: TextStyle(
fontSize: 9.0 * Provider.of<Settings>(context).fontScaling,
fontWeight: FontWeight.bold,
fontFamily: "Inter",
color: fromMe ? Provider.of<Settings>(context).theme.messageFromMeTextColor : Provider.of<Settings>(context).theme.messageFromOtherTextColor))));
height: 14 * Provider.of<Settings>(context).fontScaling, clipBehavior: Clip.hardEdge, decoration: BoxDecoration(), child: compileSenderWidget(context, fromMe, senderDisplayStr)));
var isPreview = false;
var wdgMessage = !showFileSharing
? Text(AppLocalizations.of(context)!.messageEnableFileSharing)
? Text(AppLocalizations.of(context)!.messageEnableFileSharing, style: Provider.of<Settings>(context).scaleFonts(defaultTextStyle))
: fromMe
? senderFileChrome(AppLocalizations.of(context)!.messageFileSent, widget.nameSuggestion, widget.rootHash, widget.fileSize)
: (fileChrome(AppLocalizations.of(context)!.messageFileOffered + ":", widget.nameSuggestion, widget.rootHash, widget.fileSize,
@ -182,11 +176,13 @@ class FileBubbleState extends State<FileBubble> {
},
)));
} else {
wdgDecorations = Visibility(visible: widget.interactive, child: Text(AppLocalizations.of(context)!.fileSavedTo + ': ' + path + '\u202F'));
wdgDecorations = Visibility(
visible: widget.interactive, child: Text(AppLocalizations.of(context)!.fileSavedTo + ': ' + path + '\u202F', style: Provider.of<Settings>(context).scaleFonts(defaultTextStyle)));
}
} else if (downloadActive) {
if (!downloadGotManifest) {
wdgDecorations = Visibility(visible: widget.interactive, child: Text(AppLocalizations.of(context)!.retrievingManifestMessage + '\u202F'));
wdgDecorations = Visibility(
visible: widget.interactive, child: Text(AppLocalizations.of(context)!.retrievingManifestMessage + '\u202F', style: Provider.of<Settings>(context).scaleFonts(defaultTextStyle)));
} else {
wdgDecorations = Visibility(
visible: widget.interactive,
@ -199,19 +195,19 @@ class FileBubbleState extends State<FileBubble> {
// in this case, the download was done in a previous application launch,
// so we probably have to request an info lookup
if (!downloadInterrupted) {
wdgDecorations = Text(AppLocalizations.of(context)!.fileCheckingStatus + '...' + '\u202F');
wdgDecorations = Text(AppLocalizations.of(context)!.fileCheckingStatus + '...' + '\u202F', style: Provider.of<Settings>(context).scaleFonts(defaultTextStyle));
// We should have already requested this...
} else {
var path = Provider.of<ProfileInfoState>(context).downloadFinalPath(widget.fileKey()) ?? "";
wdgDecorations = Visibility(
visible: widget.interactive,
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
Text(AppLocalizations.of(context)!.fileInterrupted + ': ' + path + '\u202F'),
ElevatedButton(onPressed: _btnResume, child: Text(AppLocalizations.of(context)!.verfiyResumeButton))
Text(AppLocalizations.of(context)!.fileInterrupted + ': ' + path + '\u202F', style: Provider.of<Settings>(context).scaleFonts(defaultTextStyle)),
ElevatedButton(onPressed: _btnResume, child: Text(AppLocalizations.of(context)!.verfiyResumeButton, style: Provider.of<Settings>(context).scaleFonts(defaultTextButtonStyle)))
]));
}
} else if (!senderIsContact) {
wdgDecorations = Text(AppLocalizations.of(context)!.msgAddToAccept);
wdgDecorations = Text(AppLocalizations.of(context)!.msgAddToAccept, style: Provider.of<Settings>(context).scaleFonts(defaultTextStyle));
} else if (!widget.isAuto || Provider.of<MessageMetadata>(context).attributes["file-missing"] == "false") {
//Note: we need this second case to account for scenarios where a user deletes the downloaded file, we won't automatically
// fetch it again, so we need to offer the user the ability to restart..
@ -220,7 +216,10 @@ class FileBubbleState extends State<FileBubble> {
child: Center(
widthFactor: 1,
child: Wrap(children: [
Padding(padding: EdgeInsets.all(5), child: ElevatedButton(child: Text(AppLocalizations.of(context)!.downloadFileButton + '\u202F'), onPressed: _btnAccept)),
Padding(
padding: EdgeInsets.all(5),
child: ElevatedButton(
child: Text(AppLocalizations.of(context)!.downloadFileButton + '\u202F', style: Provider.of<Settings>(context).scaleFonts(defaultTextButtonStyle)), onPressed: _btnAccept)),
])));
} else {
wdgDecorations = Container();
@ -278,8 +277,9 @@ class FileBubbleState extends State<FileBubble> {
}
} else {
try {
selectedFileName = await saveFile(
defaultFileName: widget.nameSuggestion,
selectedFileName = await FilePicker.platform.saveFile(
fileName: widget.nameSuggestion,
lockParentWindow: true,
);
if (selectedFileName != null) {
file = File(selectedFileName);
@ -307,52 +307,35 @@ class FileBubbleState extends State<FileBubble> {
// Construct an file chrome for the sender
Widget senderFileChrome(String chrome, String fileName, String rootHash, int fileSize) {
var settings = Provider.of<Settings>(context);
return ListTile(
visualDensity: VisualDensity.compact,
title: Wrap(direction: Axis.horizontal, alignment: WrapAlignment.start, children: [
SelectableText(
chrome + '\u202F',
style: TextStyle(
color: Provider.of<Settings>(context).theme.messageFromMeTextColor,
fontWeight: FontWeight.normal,
fontFamily: "Inter",
fontSize: 12 * Provider.of<Settings>(context).fontScaling,
),
style: settings.scaleFonts(defaultMessageTextStyle.copyWith(color: Provider.of<Settings>(context).theme.messageFromMeTextColor)),
textAlign: TextAlign.left,
maxLines: 2,
textWidthBasis: TextWidthBasis.longestLine,
),
SelectableText(
fileName + '\u202F',
style: TextStyle(
color: Provider.of<Settings>(context).theme.messageFromMeTextColor,
fontWeight: FontWeight.bold,
overflow: TextOverflow.ellipsis,
fontFamily: "Inter",
fontSize: 12 * Provider.of<Settings>(context).fontScaling,
),
style:
settings.scaleFonts(defaultMessageTextStyle.copyWith(overflow: TextOverflow.ellipsis, fontWeight: FontWeight.bold, color: Provider.of<Settings>(context).theme.messageFromMeTextColor)),
textAlign: TextAlign.left,
textWidthBasis: TextWidthBasis.parent,
maxLines: 2,
),
SelectableText(
prettyBytes(fileSize) + '\u202F' + '\n',
style: TextStyle(
color: Provider.of<Settings>(context).theme.messageFromMeTextColor,
fontSize: 10 * Provider.of<Settings>(context).fontScaling,
fontFamily: "Inter",
),
style: settings.scaleFonts(defaultSmallTextStyle.copyWith(color: Provider.of<Settings>(context).theme.messageFromMeTextColor)),
textAlign: TextAlign.left,
maxLines: 2,
)
]),
subtitle: SelectableText(
'sha512: ' + rootHash + '\u202F',
style: TextStyle(
color: Provider.of<Settings>(context).theme.messageFromMeTextColor,
fontSize: 10 * Provider.of<Settings>(context).fontScaling,
fontFamily: "RobotoMono",
),
style: settings.scaleFonts(defaultSmallTextStyle.copyWith(fontFamily: "RobotoMono", color: Provider.of<Settings>(context).theme.messageFromMeTextColor)),
textAlign: TextAlign.left,
maxLines: 4,
textWidthBasis: TextWidthBasis.parent,
@ -362,50 +345,35 @@ class FileBubbleState extends State<FileBubble> {
// Construct an file chrome
Widget fileChrome(String chrome, String fileName, String rootHash, int fileSize, String speed) {
var settings = Provider.of<Settings>(context);
return ListTile(
visualDensity: VisualDensity.compact,
title: Wrap(direction: Axis.horizontal, alignment: WrapAlignment.start, children: [
SelectableText(
chrome + '\u202F',
style: TextStyle(
color: Provider.of<Settings>(context).theme.messageFromOtherTextColor,
fontSize: 12 * Provider.of<Settings>(context).fontScaling,
fontFamily: "Inter",
),
style: settings.scaleFonts(defaultMessageTextStyle.copyWith(color: Provider.of<Settings>(context).theme.messageFromOtherTextColor)),
textAlign: TextAlign.left,
maxLines: 2,
textWidthBasis: TextWidthBasis.longestLine,
),
SelectableText(
fileName + '\u202F',
style: TextStyle(
color: Provider.of<Settings>(context).theme.messageFromOtherTextColor,
fontWeight: FontWeight.bold,
overflow: TextOverflow.ellipsis,
fontFamily: "Inter",
),
style: settings
.scaleFonts(defaultMessageTextStyle.copyWith(overflow: TextOverflow.ellipsis, fontWeight: FontWeight.bold, color: Provider.of<Settings>(context).theme.messageFromOtherTextColor)),
textAlign: TextAlign.left,
textWidthBasis: TextWidthBasis.parent,
maxLines: 2,
),
SelectableText(
AppLocalizations.of(context)!.labelFilesize + ': ' + prettyBytes(fileSize) + '\u202F' + '\n',
style: TextStyle(
color: Provider.of<Settings>(context).theme.messageFromOtherTextColor,
fontFamily: "Inter",
fontSize: 10 * Provider.of<Settings>(context).fontScaling,
),
style: settings.scaleFonts(defaultSmallTextStyle.copyWith(color: Provider.of<Settings>(context).theme.messageFromOtherTextColor)),
textAlign: TextAlign.left,
maxLines: 2,
)
]),
subtitle: SelectableText(
'sha512: ' + rootHash + '\u202F',
style: TextStyle(
color: Provider.of<Settings>(context).theme.messageFromMeTextColor,
fontSize: 10 * Provider.of<Settings>(context).fontScaling,
fontFamily: "RobotoMono",
),
style: settings.scaleFonts(defaultSmallTextStyle.copyWith(fontFamily: "RobotoMono", color: Provider.of<Settings>(context).theme.messageFromOtherTextColor)),
textAlign: TextAlign.left,
maxLines: 4,
textWidthBasis: TextWidthBasis.parent,
@ -415,11 +383,7 @@ class FileBubbleState extends State<FileBubble> {
visible: speed != "0 B/s",
child: SelectableText(
speed + '\u202F',
style: TextStyle(
color: Provider.of<Settings>(context).theme.messageFromMeTextColor,
fontFamily: "Inter",
fontSize: 10 * Provider.of<Settings>(context).fontScaling,
),
style: settings.scaleFonts(defaultSmallTextStyle.copyWith(color: Provider.of<Settings>(context).theme.messageFromOtherTextColor)),
textAlign: TextAlign.left,
maxLines: 1,
textWidthBasis: TextWidthBasis.longestLine,

View File

@ -1,12 +1,7 @@
import 'package:cwtch/config.dart';
import 'package:cwtch/controllers/filesharing.dart';
import 'package:cwtch/cwtch_icons_icons.dart';
import 'package:cwtch/models/appstate.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'dart:io';
import 'package:file_picker_desktop/file_picker_desktop.dart';
import 'package:provider/provider.dart';
import '../settings.dart';
import 'buttontextfield.dart';

View File

@ -5,6 +5,7 @@ import 'package:cwtch/cwtch_icons_icons.dart';
import 'package:cwtch/models/contact.dart';
import 'package:cwtch/models/message.dart';
import 'package:cwtch/models/profile.dart';
import 'package:cwtch/themes/opaque.dart';
import 'package:cwtch/widgets/malformedbubble.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
@ -13,6 +14,7 @@ import 'package:intl/intl.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import '../settings.dart';
import 'messageBubbleWidgetHelpers.dart';
import 'messagebubbledecorations.dart';
// Like MessageBubble but for displaying chat overlay 100/101 invitations
@ -54,15 +56,7 @@ class InvitationBubbleState extends State<InvitationBubble> {
}
}
var wdgSender = Center(
widthFactor: 1,
child: SelectableText(senderDisplayStr + '\u202F',
style: TextStyle(
fontSize: 9.0 * Provider.of<Settings>(context).fontScaling,
fontWeight: FontWeight.bold,
fontFamily: "Inter",
color: fromMe ? Provider.of<Settings>(context).theme.messageFromMeTextColor : Provider.of<Settings>(context).theme.messageFromOtherTextColor)));
var wdgSender = compileSenderWidget(context, fromMe, senderDisplayStr);
// If we receive an invite for ourselves, treat it as a bug. The UI no longer allows this so it could have only come from
// some kind of malfeasance.
var selfInvite = widget.inviteNick == Provider.of<ProfileInfoState>(context).onion;
@ -71,7 +65,7 @@ class InvitationBubbleState extends State<InvitationBubble> {
}
var wdgMessage = isGroup && !showGroupInvite
? Text(AppLocalizations.of(context)!.groupInviteSettingsWarning)
? Text(AppLocalizations.of(context)!.groupInviteSettingsWarning, style: Provider.of<Settings>(context).scaleFonts(defaultTextStyle))
: fromMe
? senderInviteChrome(
AppLocalizations.of(context)!.sendAnInvitation, isGroup ? Provider.of<ProfileInfoState>(context).contactList.findContact(widget.inviteTarget)!.nickname : widget.inviteTarget)
@ -83,15 +77,21 @@ class InvitationBubbleState extends State<InvitationBubble> {
} else if (fromMe) {
wdgDecorations = MessageBubbleDecoration(ackd: Provider.of<MessageMetadata>(context).ackd, errored: Provider.of<MessageMetadata>(context).error, fromMe: fromMe, messageDate: messageDate);
} else if (isAccepted) {
wdgDecorations = Text(AppLocalizations.of(context)!.accepted + '\u202F');
wdgDecorations = Text(AppLocalizations.of(context)!.accepted + '\u202F', style: Provider.of<Settings>(context).scaleFonts(defaultTextStyle));
} else if (this.rejected) {
wdgDecorations = Text(AppLocalizations.of(context)!.rejected + '\u202F');
wdgDecorations = Text(AppLocalizations.of(context)!.rejected + '\u202F', style: Provider.of<Settings>(context).scaleFonts(defaultTextStyle));
} else {
wdgDecorations = Center(
widthFactor: 1,
child: Wrap(children: [
Padding(padding: EdgeInsets.all(5), child: ElevatedButton(child: Text(AppLocalizations.of(context)!.rejectGroupBtn + '\u202F'), onPressed: _btnReject)),
Padding(padding: EdgeInsets.all(5), child: ElevatedButton(child: Text(AppLocalizations.of(context)!.acceptGroupBtn + '\u202F'), onPressed: _btnAccept)),
Padding(
padding: EdgeInsets.all(5),
child: ElevatedButton(
child: Text(AppLocalizations.of(context)!.rejectGroupBtn + '\u202F', style: Provider.of<Settings>(context).scaleFonts(defaultTextButtonStyle)), onPressed: _btnReject)),
Padding(
padding: EdgeInsets.all(5),
child: ElevatedButton(
child: Text(AppLocalizations.of(context)!.acceptGroupBtn + '\u202F', style: Provider.of<Settings>(context).scaleFonts(defaultTextButtonStyle)), onPressed: _btnAccept)),
]));
}
@ -149,21 +149,19 @@ class InvitationBubbleState extends State<InvitationBubble> {
// Construct an invite chrome for the sender
Widget senderInviteChrome(String chrome, String targetName) {
var settings = Provider.of<Settings>(context);
return Wrap(children: [
SelectableText(
chrome + '\u202F',
style: TextStyle(
color: Provider.of<Settings>(context).theme.messageFromMeTextColor,
),
style: settings.scaleFonts(defaultMessageTextStyle.copyWith(color: Provider.of<Settings>(context).theme.messageFromMeTextColor)),
textAlign: TextAlign.left,
maxLines: 2,
textWidthBasis: TextWidthBasis.longestLine,
),
SelectableText(
targetName + '\u202F',
style: TextStyle(
color: Provider.of<Settings>(context).theme.messageFromMeTextColor,
),
style: settings.scaleFonts(defaultMessageTextStyle.copyWith(color: Provider.of<Settings>(context).theme.messageFromMeTextColor)),
textAlign: TextAlign.left,
maxLines: 2,
textWidthBasis: TextWidthBasis.longestLine,
@ -173,19 +171,19 @@ class InvitationBubbleState extends State<InvitationBubble> {
// Construct an invite chrome
Widget inviteChrome(String chrome, String targetName, String targetId) {
var settings = Provider.of<Settings>(context);
return Wrap(children: [
SelectableText(
chrome + '\u202F',
style: TextStyle(
color: Provider.of<Settings>(context).theme.messageFromOtherTextColor,
),
style: settings.scaleFonts(defaultMessageTextStyle.copyWith(color: Provider.of<Settings>(context).theme.messageFromOtherTextColor)),
textAlign: TextAlign.left,
textWidthBasis: TextWidthBasis.longestLine,
maxLines: 2,
),
SelectableText(
targetName + '\u202F',
style: TextStyle(color: Provider.of<Settings>(context).theme.messageFromOtherTextColor),
style: settings.scaleFonts(defaultMessageTextStyle.copyWith(color: Provider.of<Settings>(context).theme.messageFromOtherTextColor)),
textAlign: TextAlign.left,
maxLines: 2,
textWidthBasis: TextWidthBasis.longestLine,

View File

@ -0,0 +1,48 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../controllers/open_link_modal.dart';
import '../settings.dart';
import '../themes/opaque.dart';
import '../third_party/linkify/flutter_linkify.dart';
Widget compileSenderWidget(BuildContext context, bool fromMe, String senderDisplayStr) {
return Container(
height: 14 * Provider.of<Settings>(context).fontScaling,
clipBehavior: Clip.hardEdge,
decoration: BoxDecoration(),
child: SelectableText(senderDisplayStr,
maxLines: 1,
style: TextStyle(
fontSize: 9.0 * Provider.of<Settings>(context).fontScaling,
fontWeight: FontWeight.bold,
fontFamily: "Inter",
overflow: TextOverflow.clip,
color: fromMe ? Provider.of<Settings>(context).theme.messageFromMeTextColor : Provider.of<Settings>(context).theme.messageFromOtherTextColor,
)));
}
Widget compileMessageContentWidget(BuildContext context, bool fromMe, String content, FocusNode focus, bool formatMessages, bool showClickableLinks) {
return SelectableLinkify(
text: content + '\u202F',
// TODO: onOpen breaks the "selectable" functionality. Maybe something to do with gesture handler?
options: LinkifyOptions(messageFormatting: formatMessages, parseLinks: showClickableLinks, looseUrl: true, defaultToHttps: true),
linkifiers: [UrlLinkifier()],
onOpen: showClickableLinks
? (link) {
modalOpenLink(context, link);
}
: null,
//key: Key(myKey),
focusNode: focus,
style: Provider.of<Settings>(context)
.scaleFonts(defaultMessageTextStyle.copyWith(color: fromMe ? Provider.of<Settings>(context).theme.messageFromMeTextColor : Provider.of<Settings>(context).theme.messageFromOtherTextColor)),
linkStyle: Provider.of<Settings>(context)
.scaleFonts(defaultMessageTextStyle.copyWith(color: fromMe ? Provider.of<Settings>(context).theme.messageFromMeTextColor : Provider.of<Settings>(context).theme.messageFromOtherTextColor)),
codeStyle: Provider.of<Settings>(context).scaleFonts(defaultMessageTextStyle.copyWith(
fontFamily: "RobotoMono",
color: fromMe ? Provider.of<Settings>(context).theme.messageFromOtherTextColor : Provider.of<Settings>(context).theme.messageFromMeTextColor,
backgroundColor: fromMe ? Provider.of<Settings>(context).theme.messageFromOtherBackgroundColor : Provider.of<Settings>(context).theme.messageFromMeBackgroundColor)),
textAlign: TextAlign.left,
textWidthBasis: TextWidthBasis.longestLine,
);
}

View File

@ -3,6 +3,7 @@ import 'dart:io';
import 'package:cwtch/controllers/open_link_modal.dart';
import 'package:cwtch/models/contact.dart';
import 'package:cwtch/models/message.dart';
import 'package:cwtch/themes/opaque.dart';
import 'package:cwtch/third_party/linkify/flutter_linkify.dart';
import 'package:cwtch/models/profile.dart';
import 'package:cwtch/widgets/malformedbubble.dart';
@ -10,6 +11,7 @@ import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../settings.dart';
import 'messageBubbleWidgetHelpers.dart';
import 'messagebubbledecorations.dart';
class MessageBubble extends StatefulWidget {
@ -42,56 +44,9 @@ class MessageBubbleState extends State<MessageBubble> {
senderDisplayStr = Provider.of<MessageMetadata>(context).senderHandle;
}
}
var wdgSender = Container(
height: 14 * Provider.of<Settings>(context).fontScaling,
clipBehavior: Clip.hardEdge,
decoration: BoxDecoration(),
child: SelectableText(senderDisplayStr,
maxLines: 1,
style: TextStyle(
fontSize: 9.0 * Provider.of<Settings>(context).fontScaling,
fontWeight: FontWeight.bold,
fontFamily: "Inter",
overflow: TextOverflow.clip,
color: fromMe ? Provider.of<Settings>(context).theme.messageFromMeTextColor : Provider.of<Settings>(context).theme.messageFromOtherTextColor,
)));
var wdgMessage = SelectableLinkify(
text: widget.content + '\u202F',
// TODO: onOpen breaks the "selectable" functionality. Maybe something to do with gesture handler?
options: LinkifyOptions(messageFormatting: formatMessages, parseLinks: showClickableLinks, looseUrl: true, defaultToHttps: true),
linkifiers: [UrlLinkifier()],
onOpen: showClickableLinks
? (link) {
modalOpenLink(context, link);
}
: null,
//key: Key(myKey),
focusNode: _focus,
style: TextStyle(
fontSize: 12.0 * Provider.of<Settings>(context).fontScaling,
fontWeight: FontWeight.normal,
fontFamily: "Inter",
color: fromMe ? Provider.of<Settings>(context).theme.messageFromMeTextColor : Provider.of<Settings>(context).theme.messageFromOtherTextColor,
),
linkStyle: TextStyle(
fontSize: 12.0 * Provider.of<Settings>(context).fontScaling,
fontWeight: FontWeight.normal,
fontFamily: "Inter",
color: fromMe ? Provider.of<Settings>(context).theme.messageFromMeTextColor : Provider.of<Settings>(context).theme.messageFromOtherTextColor),
codeStyle: TextStyle(
fontSize: 12.0 * Provider.of<Settings>(context).fontScaling,
fontWeight: FontWeight.normal,
fontFamily: "Inter",
// note: these colors are flipped
color: fromMe ? Provider.of<Settings>(context).theme.messageFromOtherTextColor : Provider.of<Settings>(context).theme.messageFromMeTextColor,
backgroundColor: fromMe ? Provider.of<Settings>(context).theme.messageFromOtherBackgroundColor : Provider.of<Settings>(context).theme.messageFromMeBackgroundColor),
textAlign: TextAlign.left,
textWidthBasis: TextWidthBasis.longestLine,
);
var wdgSender = compileSenderWidget(context, fromMe, senderDisplayStr);
var wdgMessage = compileMessageContentWidget(context, fromMe, widget.content, _focus, formatMessages, showClickableLinks);
var wdgDecorations = MessageBubbleDecoration(ackd: Provider.of<MessageMetadata>(context).ackd, errored: Provider.of<MessageMetadata>(context).error, fromMe: fromMe, messageDate: messageDate);
var error = Provider.of<MessageMetadata>(context).error;
return LayoutBuilder(builder: (context, constraints) {

View File

@ -7,6 +7,7 @@ import 'package:cwtch/models/appstate.dart';
import 'package:cwtch/models/contact.dart';
import 'package:cwtch/models/message.dart';
import 'package:cwtch/models/profile.dart';
import 'package:cwtch/themes/opaque.dart';
import 'package:cwtch/third_party/base32/base32.dart';
import 'package:cwtch/views/contactsview.dart';
import 'package:cwtch/widgets/staticmessagebubble.dart';
@ -149,8 +150,8 @@ class MessageRowState extends State<MessageRow> with SingleTickerProviderStateMi
if (fromMe) {
widgetRow = <Widget>[
wdgSpacer,
wdgSeeReplies,
wdgTranslateMessage,
wdgSeeReplies,
wdgReply,
actualMessage,
];
@ -307,7 +308,7 @@ class MessageRowState extends State<MessageRow> with SingleTickerProviderStateMi
bottomRight: Radius.circular(8),
),
),
child: Padding(padding: EdgeInsets.all(9.0), child: Text(AppLocalizations.of(context)!.newMessagesLabel)));
child: Padding(padding: EdgeInsets.all(9.0), child: Text(AppLocalizations.of(context)!.newMessagesLabel, style: Provider.of<Settings>(context).scaleFonts(defaultTextButtonStyle))));
}
void _runAnimation(Offset pixelsPerSecond, Size size) {

View File

@ -10,6 +10,7 @@ import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import '../settings.dart';
import 'messageBubbleWidgetHelpers.dart';
import 'messagebubbledecorations.dart';
class QuotedMessageBubble extends StatefulWidget {
@ -43,53 +44,11 @@ class QuotedMessageBubbleState extends State<QuotedMessageBubble> {
}
}
var wdgSender = Container(
height: 14 * Provider.of<Settings>(context).fontScaling,
clipBehavior: Clip.hardEdge,
decoration: BoxDecoration(),
child: SelectableText(senderDisplayStr,
style: TextStyle(
fontSize: 9.0 * Provider.of<Settings>(context).fontScaling,
fontWeight: FontWeight.bold,
fontFamily: "Inter",
color: fromMe ? Provider.of<Settings>(context).theme.messageFromMeTextColor : Provider.of<Settings>(context).theme.messageFromOtherTextColor)));
var wdgSender = compileSenderWidget(context, fromMe, senderDisplayStr);
var showClickableLinks = Provider.of<Settings>(context).isExperimentEnabled(ClickableLinksExperiment);
var formatMessages = Provider.of<Settings>(context).isExperimentEnabled(FormattingExperiment);
var wdgMessage = SelectableLinkify(
text: widget.body + '\u202F',
// TODO: onOpen breaks the "selectable" functionality. Maybe something to do with gesture handler?
options: LinkifyOptions(messageFormatting: formatMessages, parseLinks: showClickableLinks, looseUrl: true, defaultToHttps: true),
linkifiers: [UrlLinkifier()],
onOpen: showClickableLinks
? (link) {
modalOpenLink(context, link);
}
: null,
//key: Key(myKey),
focusNode: _focus,
style: TextStyle(
fontSize: 12.0 * Provider.of<Settings>(context).fontScaling,
fontWeight: FontWeight.normal,
fontFamily: "Inter",
color: fromMe ? Provider.of<Settings>(context).theme.messageFromMeTextColor : Provider.of<Settings>(context).theme.messageFromOtherTextColor,
),
linkStyle: TextStyle(
fontSize: 12.0 * Provider.of<Settings>(context).fontScaling,
fontWeight: FontWeight.normal,
fontFamily: "Inter",
color: fromMe ? Provider.of<Settings>(context).theme.messageFromMeTextColor : Provider.of<Settings>(context).theme.messageFromOtherTextColor),
codeStyle: TextStyle(
fontSize: 12.0 * Provider.of<Settings>(context).fontScaling,
fontWeight: FontWeight.normal,
fontFamily: "RobotoMono",
// note: these colors are flipped
color: fromMe ? Provider.of<Settings>(context).theme.messageFromOtherTextColor : Provider.of<Settings>(context).theme.messageFromMeTextColor,
backgroundColor: fromMe ? Provider.of<Settings>(context).theme.messageFromOtherBackgroundColor : Provider.of<Settings>(context).theme.messageFromMeBackgroundColor),
textAlign: TextAlign.left,
textWidthBasis: TextWidthBasis.longestLine,
);
var wdgMessage = compileMessageContentWidget(context, fromMe, widget.body, _focus, formatMessages, showClickableLinks);
var wdgQuote = FutureBuilder(
future: widget.quotedMessage,
@ -118,7 +77,7 @@ class QuotedMessageBubbleState extends State<QuotedMessageBubble> {
var wdgReplyingTo = SelectableText(
AppLocalizations.of(context)!.replyingTo.replaceAll("%1", qMessageSender),
style: TextStyle(fontSize: 10, color: qTextColor.withOpacity(0.8)),
style: Provider.of<Settings>(context).scaleFonts(TextStyle(fontSize: 10, color: qTextColor.withOpacity(0.8))),
);
// Swap the background color for quoted tweets..
return MouseRegion(

View File

@ -6,6 +6,7 @@ import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../settings.dart';
import 'messageBubbleWidgetHelpers.dart';
import 'messagebubbledecorations.dart';
class StaticMessageBubble extends StatefulWidget {
@ -40,12 +41,7 @@ class StaticMessageBubbleState extends State<StaticMessageBubble> {
senderDisplayStr = widget.profile.nickname;
}
var wdgSender = SelectableText(senderDisplayStr,
style: TextStyle(
fontSize: 9.0 * Provider.of<Settings>(context).fontScaling,
fontWeight: FontWeight.bold,
fontFamily: "Inter",
color: fromMe ? widget.settings.theme.messageFromMeTextColor : widget.settings.theme.messageFromOtherTextColor));
var wdgSender = compileSenderWidget(context, fromMe, senderDisplayStr);
var wdgDecorations = MessageBubbleDecoration(ackd: widget.metadata.ackd, errored: widget.metadata.error, fromMe: fromMe, messageDate: messageDate);

View File

@ -7,7 +7,7 @@ import Foundation
import connectivity_plus
import flutter_local_notifications
import package_info_plus_macos
import package_info_plus
import path_provider_foundation
import screen_retriever
import url_launcher_macos

View File

@ -1,4 +1,4 @@
platform :osx, '10.11'
platform :osx, '10.14'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'

View File

@ -1,11 +1,16 @@
PODS:
- connectivity_plus (0.0.1):
- FlutterMacOS
- ReachabilitySwift
- flutter_local_notifications (0.0.1):
- FlutterMacOS
- FlutterMacOS (1.0.0)
- package_info_plus_macos (0.0.1):
- package_info_plus (0.0.1):
- FlutterMacOS
- path_provider_macos (0.0.1):
- path_provider_foundation (0.0.1):
- Flutter
- FlutterMacOS
- ReachabilitySwift (5.0.0)
- screen_retriever (0.0.1):
- FlutterMacOS
- url_launcher_macos (0.0.1):
@ -14,23 +19,30 @@ PODS:
- FlutterMacOS
DEPENDENCIES:
- connectivity_plus (from `Flutter/ephemeral/.symlinks/plugins/connectivity_plus/macos`)
- flutter_local_notifications (from `Flutter/ephemeral/.symlinks/plugins/flutter_local_notifications/macos`)
- FlutterMacOS (from `Flutter/ephemeral`)
- package_info_plus_macos (from `Flutter/ephemeral/.symlinks/plugins/package_info_plus_macos/macos`)
- path_provider_macos (from `Flutter/ephemeral/.symlinks/plugins/path_provider_macos/macos`)
- package_info_plus (from `Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos`)
- path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`)
- screen_retriever (from `Flutter/ephemeral/.symlinks/plugins/screen_retriever/macos`)
- url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`)
- window_manager (from `Flutter/ephemeral/.symlinks/plugins/window_manager/macos`)
SPEC REPOS:
trunk:
- ReachabilitySwift
EXTERNAL SOURCES:
connectivity_plus:
:path: Flutter/ephemeral/.symlinks/plugins/connectivity_plus/macos
flutter_local_notifications:
:path: Flutter/ephemeral/.symlinks/plugins/flutter_local_notifications/macos
FlutterMacOS:
:path: Flutter/ephemeral
package_info_plus_macos:
:path: Flutter/ephemeral/.symlinks/plugins/package_info_plus_macos/macos
path_provider_macos:
:path: Flutter/ephemeral/.symlinks/plugins/path_provider_macos/macos
package_info_plus:
:path: Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos
path_provider_foundation:
:path: Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin
screen_retriever:
:path: Flutter/ephemeral/.symlinks/plugins/screen_retriever/macos
url_launcher_macos:
@ -39,14 +51,16 @@ EXTERNAL SOURCES:
:path: Flutter/ephemeral/.symlinks/plugins/window_manager/macos
SPEC CHECKSUMS:
connectivity_plus: 18d3c32514c886e046de60e9c13895109866c747
flutter_local_notifications: 3805ca215b2fb7f397d78b66db91f6a747af52e4
FlutterMacOS: 57701585bf7de1b3fc2bb61f6378d73bbdea8424
package_info_plus_macos: f010621b07802a241d96d01876d6705f15e77c1c
path_provider_macos: 3c0c3b4b0d4a76d2bf989a913c2de869c5641a19
FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24
package_info_plus: 02d7a575e80f194102bef286361c6c326e4c29ce
path_provider_foundation: eaf5b3e458fc0e5fbb9940fb09980e853fe058b8
ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825
screen_retriever: 59634572a57080243dd1bf715e55b6c54f241a38
url_launcher_macos: 597e05b8e514239626bcf4a850fcf9ef5c856ec3
url_launcher_macos: 5335912b679c073563f29d89d33d10d459f95451
window_manager: 3a1844359a6295ab1e47659b1a777e36773cd6e8
PODFILE CHECKSUM: 6eac6b3292e5142cfc23bdeb71848a40ec51c14c
PODFILE CHECKSUM: 353c8bcc5d5b0994e508d035b5431cfe18c1dea7
COCOAPODS: 1.11.2
COCOAPODS: 1.11.3

View File

@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
objectVersion = 51;
objectVersion = 54;
objects = {
/* Begin PBXAggregateTarget section */
@ -202,7 +202,7 @@
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0920;
LastUpgradeCheck = 0930;
LastUpgradeCheck = 1300;
ORGANIZATIONNAME = "";
TargetAttributes = {
33CC10EC2044A3C60003C045 = {
@ -255,6 +255,7 @@
/* Begin PBXShellScriptBuildPhase section */
3399D490228B24CF009A79C7 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
@ -403,7 +404,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.11;
MACOSX_DEPLOYMENT_TARGET = 10.14;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = macosx;
SWIFT_COMPILATION_MODE = wholemodule;
@ -483,7 +484,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.11;
MACOSX_DEPLOYMENT_TARGET = 10.14;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
@ -530,7 +531,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.11;
MACOSX_DEPLOYMENT_TARGET = 10.14;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = macosx;
SWIFT_COMPILATION_MODE = wholemodule;

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1000"
LastUpgradeVersion = "1300"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"

View File

@ -5,42 +5,42 @@ packages:
dependency: transitive
description:
name: _fe_analyzer_shared
sha256: "4897882604d919befd350648c7f91926a9d5de99e67b455bf0917cc2362f4bb8"
sha256: "405666cd3cf0ee0a48d21ec67e65406aad2c726d9fa58840d3375e7bdcd32a07"
url: "https://pub.dev"
source: hosted
version: "47.0.0"
version: "60.0.0"
analyzer:
dependency: transitive
description:
name: analyzer
sha256: "690e335554a8385bc9d787117d9eb52c0c03ee207a607e593de3c9d71b1cfe80"
sha256: "1952250bd005bacb895a01bf1b4dc00e3ba1c526cf47dca54dfe24979c65f5b3"
url: "https://pub.dev"
source: hosted
version: "4.7.0"
version: "5.12.0"
archive:
dependency: transitive
description:
name: archive
sha256: "80e5141fafcb3361653ce308776cfd7d45e6e9fbb429e14eec571382c0c5fecb"
sha256: "0c8368c9b3f0abbc193b9d6133649a614204b528982bebc7026372d61677ce3a"
url: "https://pub.dev"
source: hosted
version: "3.3.2"
version: "3.3.7"
args:
dependency: transitive
description:
name: args
sha256: "139d809800a412ebb26a3892da228b2d0ba36f0ef5d9a82166e5e52ec8d61611"
sha256: c372bb384f273f0c2a8aaaa226dad84dc27c8519a691b888725dec59518ad53a
url: "https://pub.dev"
source: hosted
version: "2.3.2"
version: "2.4.1"
async:
dependency: transitive
description:
name: async
sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0
sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
url: "https://pub.dev"
source: hosted
version: "2.10.0"
version: "2.11.0"
boolean_selector:
dependency: transitive
description:
@ -53,10 +53,10 @@ packages:
dependency: transitive
description:
name: build
sha256: "3fbda25365741f8251b39f3917fb3c8e286a96fd068a5a242e11c2012d495777"
sha256: "43865b79fbb78532e4bff7c33087aa43b1d488c4fdef014eaef568af6d8016dc"
url: "https://pub.dev"
source: hosted
version: "2.3.1"
version: "2.4.0"
build_config:
dependency: transitive
description:
@ -69,10 +69,10 @@ packages:
dependency: transitive
description:
name: build_daemon
sha256: "6bc5544ea6ce4428266e7ea680e945c68806c4aae2da0eb5e9ccf38df8d6acbf"
sha256: "5f02d73eb2ba16483e693f80bee4f088563a820e47d1027d4cdfe62b5bb43e65"
url: "https://pub.dev"
source: hosted
version: "3.1.0"
version: "4.0.0"
build_resolvers:
dependency: transitive
description:
@ -85,18 +85,18 @@ packages:
dependency: "direct dev"
description:
name: build_runner
sha256: "56942f8114731d1e79942cd981cfef29501937ff1bccf4dbdce0273f31f13640"
sha256: "220ae4553e50d7c21a17c051afc7b183d28a24a420502e842f303f8e4e6edced"
url: "https://pub.dev"
source: hosted
version: "2.2.0"
version: "2.4.4"
build_runner_core:
dependency: transitive
description:
name: build_runner_core
sha256: "14febe0f5bac5ae474117a36099b4de6f1dbc52df6c5e55534b3da9591bf4292"
sha256: "30859c90e9ddaccc484f56303931f477b1f1ba2bab74aa32ed5d6ce15870f8cf"
url: "https://pub.dev"
source: hosted
version: "7.2.7"
version: "7.2.8"
built_collection:
dependency: transitive
description:
@ -109,34 +109,34 @@ packages:
dependency: transitive
description:
name: built_value
sha256: "169565c8ad06adb760c3645bf71f00bff161b00002cace266cad42c5d22a7725"
sha256: "2f17434bd5d52a26762043d6b43bb53b3acd029b4d9071a329f46d67ef297e6d"
url: "https://pub.dev"
source: hosted
version: "8.4.3"
version: "8.5.0"
characters:
dependency: transitive
description:
name: characters
sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c
sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
url: "https://pub.dev"
source: hosted
version: "1.2.1"
version: "1.3.0"
checked_yaml:
dependency: transitive
description:
name: checked_yaml
sha256: "3d1505d91afa809d177efd4eed5bb0eb65805097a1463abdd2add076effae311"
sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff
url: "https://pub.dev"
source: hosted
version: "2.0.2"
version: "2.0.3"
cli_util:
dependency: transitive
description:
name: cli_util
sha256: "66f86e916d285c1a93d3b79587d94bd71984a66aac4ff74e524cfa7877f1395c"
sha256: b8db3080e59b2503ca9e7922c3df2072cf13992354d5e944074ffa836fba43b7
url: "https://pub.dev"
source: hosted
version: "0.3.5"
version: "0.4.0"
clock:
dependency: transitive
description:
@ -157,10 +157,10 @@ packages:
dependency: transitive
description:
name: collection
sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0
sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c"
url: "https://pub.dev"
source: hosted
version: "1.17.0"
version: "1.17.1"
connectivity_plus:
dependency: "direct main"
description:
@ -195,10 +195,10 @@ packages:
dependency: "direct main"
description:
name: crypto
sha256: aa274aa7774f8964e4f4f38cc994db7b6158dd36e9187aaceaddc994b35c6c67
sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab
url: "https://pub.dev"
source: hosted
version: "3.0.2"
version: "3.0.3"
cupertino_icons:
dependency: "direct main"
description:
@ -219,18 +219,10 @@ packages:
dependency: "direct main"
description:
name: dbus
sha256: "253bfaa3d340778d8bc755e89c3af38e85ef95e65fd5d5670aa3167f8d4f6577"
sha256: "6f07cba3f7b3448d42d015bfd3d53fe12e5b36da2423f23838efc1d5fb31a263"
url: "https://pub.dev"
source: hosted
version: "0.7.4"
desktop_notifications:
dependency: "direct main"
description:
name: desktop_notifications
sha256: "6d92694ad6e9297a862c5ff7dd6b8ff64c819972557754769f819d2209612927"
url: "https://pub.dev"
source: hosted
version: "0.6.3"
version: "0.7.8"
fake_async:
dependency: transitive
description:
@ -243,10 +235,10 @@ packages:
dependency: "direct main"
description:
name: ffi
sha256: "13a6ccf6a459a125b3fcdb6ec73bd5ff90822e071207c663bfd1f70062d51d18"
sha256: ed5337a5660c506388a9f012be0288fb38b49020ce2b45fe1f8b8323fe429f99
url: "https://pub.dev"
source: hosted
version: "1.2.1"
version: "2.0.2"
file:
dependency: transitive
description:
@ -259,18 +251,10 @@ packages:
dependency: "direct main"
description:
name: file_picker
sha256: "704259669b5e9cb24e15c11cfcf02caf5f20d30901b3916d60b6d1c2d647035f"
sha256: e6c7ad8e572379df86ea64ef0a5395889fba3954411d47ca021b888d79f8e798
url: "https://pub.dev"
source: hosted
version: "4.6.1"
file_picker_desktop:
dependency: "direct main"
description:
name: file_picker_desktop
sha256: bc802a0fff747071aed0ccdd9b3df827527e46643a18756b2c6bd4b4b4adce20
url: "https://pub.dev"
source: hosted
version: "1.1.1"
version: "5.2.11"
fixnum:
dependency: transitive
description:
@ -294,7 +278,7 @@ packages:
description:
path: "."
ref: main
resolved-ref: bc846ee4df720288a17b8455ec4cc1ccbe90ecdb
resolved-ref: "9e89cc0d89770242a3c2e86573f9618a0dd49194"
url: "https://git.openprivacy.ca/openprivacy/flutter_gherkin"
source: git
version: "3.0.0-rc.17"
@ -302,26 +286,26 @@ packages:
dependency: "direct main"
description:
name: flutter_local_notifications
sha256: "57d0012730780fe137260dd180e072c18a73fbeeb924cdc029c18aaa0f338d64"
sha256: ee6ee56855aa920899b68586b538474d086c149932220b47b92502cbfb5ba5e5
url: "https://pub.dev"
source: hosted
version: "9.9.1"
version: "14.0.0+2"
flutter_local_notifications_linux:
dependency: transitive
description:
name: flutter_local_notifications_linux
sha256: b472bfc173791b59ede323661eae20f7fff0b6908fea33dd720a6ef5d576bae8
sha256: "33f741ef47b5f63cc7f78fe75eeeac7e19f171ff3c3df054d84c1e38bedb6a03"
url: "https://pub.dev"
source: hosted
version: "0.5.1"
version: "4.0.0+1"
flutter_local_notifications_platform_interface:
dependency: transitive
description:
name: flutter_local_notifications_platform_interface
sha256: "21bceee103a66a53b30ea9daf677f990e5b9e89b62f222e60dd241cd08d63d3a"
sha256: "7cf643d6d5022f3baed0be777b0662cce5919c0a7b86e700299f22dc4ae660ef"
url: "https://pub.dev"
source: hosted
version: "5.0.0"
version: "7.0.0+1"
flutter_localizations:
dependency: "direct main"
description: flutter
@ -331,10 +315,10 @@ packages:
dependency: transitive
description:
name: flutter_plugin_android_lifecycle
sha256: "60fc7b78455b94e6de2333d2f95196d32cf5c22f4b0b0520a628804cb463503b"
sha256: "96af49aa6b57c10a312106ad6f71deed5a754029c24789bbf620ba784f0bd0b0"
url: "https://pub.dev"
source: hosted
version: "2.0.7"
version: "2.0.14"
flutter_test:
dependency: transitive
description: flutter
@ -349,10 +333,10 @@ packages:
dependency: transitive
description:
name: frontend_server_client
sha256: "4f4a162323c86ffc1245765cfe138872b8f069deb42f7dbb36115fa27f31469b"
sha256: "408e3ca148b31c20282ad6f37ebfa6f4bdc8fede5b74bc2f08d9d92b55db3612"
url: "https://pub.dev"
source: hosted
version: "2.1.3"
version: "3.2.0"
fuchsia_remote_debug_protocol:
dependency: transitive
description: flutter
@ -362,10 +346,10 @@ packages:
dependency: transitive
description:
name: get_it
sha256: "290fde3a86072e4b37dbb03c07bec6126f0ecc28dad403c12ffe2e5a2d751ab7"
sha256: "529de303c739fca98cd7ece5fca500d8ff89649f1bb4b4e94fb20954abcd7468"
url: "https://pub.dev"
source: hosted
version: "7.2.0"
version: "7.6.0"
gherkin:
dependency: transitive
description:
@ -386,18 +370,18 @@ packages:
dependency: transitive
description:
name: graphs
sha256: f9e130f3259f52d26f0cfc0e964513796dafed572fa52e45d2f8d6ca14db39b2
sha256: "772db3d53d23361d4ffcf5a9bb091cf3ee9b22f2be52cd107cd7a2683a89ba0e"
url: "https://pub.dev"
source: hosted
version: "2.2.0"
version: "2.3.0"
http:
dependency: transitive
description:
name: http
sha256: "6aa2946395183537c8b880962d935877325d6a09a2867c3970c05c0fed6ac482"
sha256: "5895291c13fa8a3bd82e76d5627f69e0d85ca6a30dcac95c4ea19a5d555879c2"
url: "https://pub.dev"
source: hosted
version: "0.13.5"
version: "0.13.6"
http_multi_server:
dependency: transitive
description:
@ -418,10 +402,10 @@ packages:
dependency: transitive
description:
name: image
sha256: "8e9d133755c3e84c73288363e6343157c383a0c6c56fc51afcc5d4d7180306d6"
sha256: a72242c9a0ffb65d03de1b7113bc4e189686fc07c7147b8b41811d0dd0e0d9bf
url: "https://pub.dev"
source: hosted
version: "3.3.0"
version: "4.0.17"
integration_test:
dependency: transitive
description: flutter
@ -431,10 +415,10 @@ packages:
dependency: transitive
description:
name: intl
sha256: "910f85bce16fb5c6f614e117efa303e85a1731bb0081edf3604a2ae6e9a3cc91"
sha256: a3715e3bc90294e971cb7dc063fbf3cd9ee0ebf8604ffeafabd9e6f16abbdbe6
url: "https://pub.dev"
source: hosted
version: "0.17.0"
version: "0.18.0"
io:
dependency: transitive
description:
@ -447,18 +431,18 @@ packages:
dependency: transitive
description:
name: js
sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7"
sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
url: "https://pub.dev"
source: hosted
version: "0.6.5"
version: "0.6.7"
json_annotation:
dependency: transitive
description:
name: json_annotation
sha256: c33da08e136c3df0190bd5bbe51ae1df4a7d96e7954d1d7249fea2968a72d317
sha256: b10a7b2ff83d83c777edba3c6a0f97045ddadd56c944e1a23a3fdf43a1bf4467
url: "https://pub.dev"
source: hosted
version: "4.8.0"
version: "4.8.1"
logging:
dependency: transitive
description:
@ -471,10 +455,10 @@ packages:
dependency: transitive
description:
name: matcher
sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72"
sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb"
url: "https://pub.dev"
source: hosted
version: "0.12.13"
version: "0.12.15"
material_color_utilities:
dependency: transitive
description:
@ -487,10 +471,10 @@ packages:
dependency: transitive
description:
name: meta
sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42"
sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3"
url: "https://pub.dev"
source: hosted
version: "1.8.0"
version: "1.9.1"
mime:
dependency: transitive
description:
@ -503,10 +487,10 @@ packages:
dependency: "direct dev"
description:
name: msix
sha256: e3de4d9f52543ad6e4b0f534991e1303cbd379d24be28dd241ac60bd9439a201
sha256: "88ee83949d87dc635ffd51d7c17ef222390e5067693cc248046661b12a353d13"
url: "https://pub.dev"
source: hosted
version: "3.7.0"
version: "3.12.2"
nested:
dependency: transitive
description:
@ -527,114 +511,82 @@ packages:
dependency: "direct main"
description:
name: package_info_plus
sha256: "7a6114becdf042be2b0777d77ace954d4a205644171a1cbd8712976b9bbb837c"
sha256: d39e8fbff4c5aef4592737e25ad6ac500df006ce7a7a8e1f838ce1256e167542
url: "https://pub.dev"
source: hosted
version: "1.4.2"
package_info_plus_linux:
dependency: transitive
description:
name: package_info_plus_linux
sha256: "04b575f44233d30edbb80a94e57cad9107aada334fc02aabb42b6becd13c43fc"
url: "https://pub.dev"
source: hosted
version: "1.0.5"
package_info_plus_macos:
dependency: transitive
description:
name: package_info_plus_macos
sha256: a2ad8b4acf4cd479d4a0afa5a74ea3f5b1c7563b77e52cc32b3ee6956d5482a6
url: "https://pub.dev"
source: hosted
version: "1.3.0"
version: "4.0.0"
package_info_plus_platform_interface:
dependency: transitive
description:
name: package_info_plus_platform_interface
sha256: f7a0c8f1e7e981bc65f8b64137a53fd3c195b18d429fba960babc59a5a1c7ae8
sha256: "9bc8ba46813a4cc42c66ab781470711781940780fd8beddd0c3da62506d3a6c6"
url: "https://pub.dev"
source: hosted
version: "1.0.2"
package_info_plus_web:
dependency: transitive
description:
name: package_info_plus_web
sha256: f0829327eb534789e0a16ccac8936a80beed4e2401c4d3a74f3f39094a822d3b
url: "https://pub.dev"
source: hosted
version: "1.0.6"
package_info_plus_windows:
dependency: transitive
description:
name: package_info_plus_windows
sha256: a6040b8695c82f8dd3c3d4dfab7ef96fbe9c67aac21b9bcf5db272589ef84441
url: "https://pub.dev"
source: hosted
version: "1.0.5"
version: "2.0.1"
path:
dependency: transitive
description:
name: path
sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b
sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
url: "https://pub.dev"
source: hosted
version: "1.8.2"
version: "1.8.3"
path_provider:
dependency: "direct main"
description:
name: path_provider
sha256: dcea5feb97d8abf90cab9e9030b497fb7c3cbf26b7a1fe9e3ef7dcb0a1ddec95
sha256: "3087813781ab814e4157b172f1a11c46be20179fcc9bea043e0fba36bc0acaa2"
url: "https://pub.dev"
source: hosted
version: "2.0.12"
version: "2.0.15"
path_provider_android:
dependency: transitive
description:
name: path_provider_android
sha256: a776c088d671b27f6e3aa8881d64b87b3e80201c64e8869b811325de7a76c15e
sha256: "2cec049d282c7f13c594b4a73976b0b4f2d7a1838a6dd5aaf7bd9719196bee86"
url: "https://pub.dev"
source: hosted
version: "2.0.22"
version: "2.0.27"
path_provider_foundation:
dependency: transitive
description:
name: path_provider_foundation
sha256: "62a68e7e1c6c459f9289859e2fae58290c981ce21d1697faf54910fe1faa4c74"
sha256: "1995d88ec2948dac43edf8fe58eb434d35d22a2940ecee1a9fefcd62beee6eb3"
url: "https://pub.dev"
source: hosted
version: "2.1.1"
version: "2.2.3"
path_provider_linux:
dependency: transitive
description:
name: path_provider_linux
sha256: ab0987bf95bc591da42dffb38c77398fc43309f0b9b894dcc5d6f40c4b26c379
sha256: "2ae08f2216225427e64ad224a24354221c2c7907e448e6e0e8b57b1eb9f10ad1"
url: "https://pub.dev"
source: hosted
version: "2.1.7"
version: "2.1.10"
path_provider_platform_interface:
dependency: transitive
description:
name: path_provider_platform_interface
sha256: f0abc8ebd7253741f05488b4813d936b4d07c6bae3e86148a09e342ee4b08e76
sha256: "57585299a729335f1298b43245842678cb9f43a6310351b18fb577d6e33165ec"
url: "https://pub.dev"
source: hosted
version: "2.0.5"
version: "2.0.6"
path_provider_windows:
dependency: transitive
description:
name: path_provider_windows
sha256: a34ecd7fb548f8e57321fd8e50d865d266941b54e6c3b7758cf8f37c24116905
sha256: d3f80b32e83ec208ac95253e0cd4d298e104fbc63cb29c5c69edaed43b0c69d6
url: "https://pub.dev"
source: hosted
version: "2.0.7"
version: "2.1.6"
petitparser:
dependency: transitive
description:
name: petitparser
sha256: "49392a45ced973e8d94a85fdb21293fbb40ba805fc49f2965101ae748a3683b4"
sha256: cb3798bef7fc021ac45b308f4b51208a152792445cce0448c9a4ba5879dd8750
url: "https://pub.dev"
source: hosted
version: "5.1.0"
version: "5.4.0"
platform:
dependency: transitive
description:
@ -647,10 +599,18 @@ packages:
dependency: transitive
description:
name: plugin_platform_interface
sha256: dbf0f707c78beedc9200146ad3cb0ab4d5da13c246336987be6940f026500d3a
sha256: "6a2128648c854906c53fa8e33986fc0247a1116122f9534dd20e3ab9e16a32bc"
url: "https://pub.dev"
source: hosted
version: "2.1.3"
version: "2.1.4"
pointycastle:
dependency: transitive
description:
name: pointycastle
sha256: "7c1e5f0d23c9016c5bbd8b1473d0d3fb3fc851b876046039509e18e0c7485f2c"
url: "https://pub.dev"
source: hosted
version: "3.7.3"
pool:
dependency: transitive
description:
@ -679,34 +639,34 @@ packages:
dependency: transitive
description:
name: pub_semver
sha256: "307de764d305289ff24ad257ad5c5793ce56d04947599ad68b3baa124105fc17"
sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c"
url: "https://pub.dev"
source: hosted
version: "2.1.3"
version: "2.1.4"
pubspec_parse:
dependency: transitive
description:
name: pubspec_parse
sha256: "75f6614d6dde2dc68948dffbaa4fe5dae32cd700eb9fb763fe11dfb45a3c4d0a"
sha256: c63b2876e58e194e4b0828fcb080ad0e06d051cb607a6be51a9e084f47cb9367
url: "https://pub.dev"
source: hosted
version: "1.2.1"
version: "1.2.3"
qr:
dependency: transitive
description:
name: qr
sha256: "5c4208b4dc0d55c3184d10d83ee0ded6212dc2b5e2ba17c5a0c0aab279128d21"
sha256: "64957a3930367bf97cc211a5af99551d630f2f4625e38af10edd6b19131b64b3"
url: "https://pub.dev"
source: hosted
version: "2.1.0"
version: "3.0.1"
qr_flutter:
dependency: "direct main"
description:
name: qr_flutter
sha256: c5c121c54cb6dd837b9b9d57eb7bc7ec6df4aee741032060c8833a678c80b87e
sha256: "5095f0fc6e3f71d08adef8feccc8cea4f12eec18a2e31c2e8d82cb6019f4b097"
url: "https://pub.dev"
source: hosted
version: "4.0.0"
version: "4.1.0"
screen_retriever:
dependency: transitive
description:
@ -719,26 +679,26 @@ packages:
dependency: "direct main"
description:
name: scrollable_positioned_list
sha256: ca7fcaa743db712d4f7b1580526f494d0093c77a721a65705ee51fbeac7a2bd3
sha256: "1b54d5f1329a1e263269abc9e2543d90806131aa14fe7c6062a8054d57249287"
url: "https://pub.dev"
source: hosted
version: "0.3.5"
version: "0.3.8"
shelf:
dependency: transitive
description:
name: shelf
sha256: c24a96135a2ccd62c64b69315a14adc5c3419df63b4d7c05832a346fdb73682c
sha256: ad29c505aee705f41a4d8963641f91ac4cee3c8fad5947e033390a7bd8180fa4
url: "https://pub.dev"
source: hosted
version: "1.4.0"
version: "1.4.1"
shelf_web_socket:
dependency: transitive
description:
name: shelf_web_socket
sha256: a988c0e8d8ffbdb8a28aa7ec8e449c260f3deb808781fe1284d22c5bba7156e8
sha256: "9ca081be41c60190ebcb4766b2486a7d50261db7bd0f5d9615f2d653637a84c1"
url: "https://pub.dev"
source: hosted
version: "1.0.3"
version: "1.0.4"
sky_engine:
dependency: transitive
description: flutter
@ -812,18 +772,18 @@ packages:
dependency: transitive
description:
name: test_api
sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206
sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb
url: "https://pub.dev"
source: hosted
version: "0.4.16"
version: "0.5.1"
timezone:
dependency: transitive
description:
name: timezone
sha256: "57b35f6e8ef731f18529695bffc62f92c6189fac2e52c12d478dec1931afb66e"
sha256: "1cfd8ddc2d1cfd836bc93e67b9be88c3adaeca6f40a00ca999104c30693cdca0"
url: "https://pub.dev"
source: hosted
version: "0.8.0"
version: "0.9.2"
timing:
dependency: transitive
description:
@ -836,74 +796,74 @@ packages:
dependency: transitive
description:
name: typed_data
sha256: "26f87ade979c47a150c9eaab93ccd2bebe70a27dc0b4b29517f2904f04eb11a5"
sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c
url: "https://pub.dev"
source: hosted
version: "1.3.1"
version: "1.3.2"
url_launcher:
dependency: "direct main"
description:
name: url_launcher
sha256: "698fa0b4392effdc73e9e184403b627362eb5fbf904483ac9defbb1c2191d809"
sha256: eb1e00ab44303d50dd487aab67ebc575456c146c6af44422f9c13889984c00f3
url: "https://pub.dev"
source: hosted
version: "6.1.8"
version: "6.1.11"
url_launcher_android:
dependency: transitive
description:
name: url_launcher_android
sha256: "3e2f6dfd2c7d9cd123296cab8ef66cfc2c1a13f5845f42c7a0f365690a8a7dd1"
sha256: "7aac14be5f4731b923cc697ae2d42043945076cd0dbb8806baecc92c1dc88891"
url: "https://pub.dev"
source: hosted
version: "6.0.23"
version: "6.0.33"
url_launcher_ios:
dependency: transitive
description:
name: url_launcher_ios
sha256: bb328b24d3bccc20bdf1024a0990ac4f869d57663660de9c936fb8c043edefe3
sha256: "9af7ea73259886b92199f9e42c116072f05ff9bea2dcb339ab935dfc957392c2"
url: "https://pub.dev"
source: hosted
version: "6.0.18"
version: "6.1.4"
url_launcher_linux:
dependency: transitive
description:
name: url_launcher_linux
sha256: "318c42cba924e18180c029be69caf0a1a710191b9ec49bb42b5998fdcccee3cc"
sha256: "207f4ddda99b95b4d4868320a352d374b0b7e05eefad95a4a26f57da413443f5"
url: "https://pub.dev"
source: hosted
version: "3.0.2"
version: "3.0.5"
url_launcher_macos:
dependency: transitive
description:
name: url_launcher_macos
sha256: "41988b55570df53b3dd2a7fc90c76756a963de6a8c5f8e113330cb35992e2094"
sha256: "91ee3e75ea9dadf38036200c5d3743518f4a5eb77a8d13fda1ee5764373f185e"
url: "https://pub.dev"
source: hosted
version: "3.0.2"
version: "3.0.5"
url_launcher_platform_interface:
dependency: transitive
description:
name: url_launcher_platform_interface
sha256: "4eae912628763eb48fc214522e58e942fd16ce195407dbf45638239523c759a6"
sha256: "6c9ca697a5ae218ce56cece69d46128169a58aa8653c1b01d26fcd4aad8c4370"
url: "https://pub.dev"
source: hosted
version: "2.1.1"
version: "2.1.2"
url_launcher_web:
dependency: transitive
description:
name: url_launcher_web
sha256: "44d79408ce9f07052095ef1f9a693c258d6373dc3944249374e30eff7219ccb0"
sha256: "81fe91b6c4f84f222d186a9d23c73157dc4c8e1c71489c4d08be1ad3b228f1aa"
url: "https://pub.dev"
source: hosted
version: "2.0.14"
version: "2.0.16"
url_launcher_windows:
dependency: transitive
description:
name: url_launcher_windows
sha256: b6217370f8eb1fd85c8890c539f5a639a01ab209a36db82c921ebeacefc7a615
sha256: "254708f17f7c20a9c8c471f67d86d76d4a3f9c1591aad1e15292008aceb82771"
url: "https://pub.dev"
source: hosted
version: "3.0.3"
version: "3.0.6"
uuid:
dependency: transitive
description:
@ -924,42 +884,42 @@ packages:
dependency: transitive
description:
name: vm_service
sha256: e7fb6c2282f7631712b69c19d1bff82f3767eea33a2321c14fa59ad67ea391c7
sha256: f6deed8ed625c52864792459709183da231ebf66ff0cf09e69b573227c377efe
url: "https://pub.dev"
source: hosted
version: "9.4.0"
version: "11.3.0"
watcher:
dependency: transitive
description:
name: watcher
sha256: "6a7f46926b01ce81bfc339da6a7f20afbe7733eff9846f6d6a5466aa4c6667c0"
sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8"
url: "https://pub.dev"
source: hosted
version: "1.0.2"
version: "1.1.0"
web_socket_channel:
dependency: transitive
description:
name: web_socket_channel
sha256: ca49c0bc209c687b887f30527fb6a9d80040b072cc2990f34b9bec3e7663101b
sha256: d88238e5eac9a42bb43ca4e721edba3c08c6354d4a53063afaa568516217621b
url: "https://pub.dev"
source: hosted
version: "2.3.0"
version: "2.4.0"
webdriver:
dependency: transitive
description:
name: webdriver
sha256: ef67178f0cc7e32c1494645b11639dd1335f1d18814aa8435113a92e9ef9d841
sha256: "3c923e918918feeb90c4c9fdf1fe39220fa4c0e8e2c0fffaded174498ef86c49"
url: "https://pub.dev"
source: hosted
version: "3.0.1"
version: "3.0.2"
win32:
dependency: transitive
description:
name: win32
sha256: c0e3a4f7be7dae51d8f152230b86627e3397c1ba8c3fa58e63d44a9f3edc9cef
sha256: "5a751eddf9db89b3e5f9d50c20ab8612296e4e8db69009788d6c8b060a84191c"
url: "https://pub.dev"
source: hosted
version: "2.6.1"
version: "4.1.4"
win_toast:
dependency: "direct main"
description:
@ -972,34 +932,34 @@ packages:
dependency: "direct main"
description:
name: window_manager
sha256: d812d3189d23465d2e94baa2505a4462b46dde4939012ff370711c6897d747ae
sha256: "2b2572442b2a5178642730442dc625ac088244f5827b1f0811371b1b7485eb62"
url: "https://pub.dev"
source: hosted
version: "0.2.9"
version: "0.3.2"
xdg_directories:
dependency: transitive
description:
name: xdg_directories
sha256: bd512f03919aac5f1313eb8249f223bacf4927031bf60b02601f81f687689e86
sha256: ee1505df1426458f7f60aac270645098d318a8b4766d85fde75f76f2e21807d1
url: "https://pub.dev"
source: hosted
version: "0.2.0+3"
version: "1.0.0"
xml:
dependency: transitive
description:
name: xml
sha256: "979ee37d622dec6365e2efa4d906c37470995871fe9ae080d967e192d88286b5"
sha256: "5bc72e1e45e941d825fd7468b9b4cc3b9327942649aeb6fc5cdbf135f0a86e84"
url: "https://pub.dev"
source: hosted
version: "6.2.2"
version: "6.3.0"
yaml:
dependency: transitive
description:
name: yaml
sha256: "23812a9b125b48d4007117254bca50abb6c712352927eece9e155207b1db2370"
sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5"
url: "https://pub.dev"
source: hosted
version: "3.1.1"
version: "3.1.2"
sdks:
dart: ">=2.19.0 <3.0.0"
flutter: ">=3.0.0"
dart: ">=3.0.0 <4.0.0"
flutter: ">=3.7.0"

View File

@ -18,13 +18,13 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
version: 1.11.0+37
environment:
sdk: ">=2.17.0 <3.0.0"
sdk: ">=2.17.0 <4.0.0"
dependencies:
flutter:
sdk: flutter
provider: ^6.0.3
package_info_plus: ^1.0.0
package_info_plus: ^4.0.0
#intl_translation: any
flutter_localizations:
sdk: flutter
@ -32,37 +32,38 @@ dependencies:
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.0
# Todo: upgrade to 2.x, allow other package upgrades (dbus)
ffi: ^1.2.1
ffi: ^2.0.2
path_provider: ^2.0.0
# Todo: upgrade to 3.0.3 when integration test is upgraded in flutter gherkin
# Note: This is a non-urgent upgrade as 3.0.3 is only a dart version bump
crypto: ^3.0.2
glob: any
scrollable_positioned_list: ^0.3.2
file_picker: ^4.3.2
file_picker_desktop: ^1.1.1
file_picker: 5.2.11
url_launcher: ^6.0.18
window_manager: ^0.2.8
window_manager: ^0.3.2
# notification plugins
## Somewhere between 0.0.2 and 0.3 they introduced a dependancy on a new Windows RT feature
## Which can only be linked to with a new VC 17 compiler and we're suspicious only work on
## Windows 2022 and newer... we can't seem to automate compiling on win server 2019 containers
## So pinning to 0.0.2 for the forseeable future or until we change plugins
win_toast: ^0.0.2
flutter_local_notifications: ^9.6.1
desktop_notifications: ^0.6.3
# network management plugins
# dbus >=0.7.5 depends on ffi ^2.0.0 and cwtch depends on ffi ^1.2.1, dbus >=0.7.5 is forbidden.
dbus: 0.7.4
flutter_local_notifications: ^14.0.0+2
dbus: ^0.7.8
connectivity_plus:
path: lib/third_party/connectivity_plus/connectivity_plus
# misc plugins
qr_flutter: ^4.0.0
dev_dependencies:
msix: ^3.6.2
msix: ^3.12.2
build_runner: any
flutter_gherkin:
#path: ./flutter_gherkin
git:
url: https://git.openprivacy.ca/openprivacy/flutter_gherkin
ref: main
url: https://git.openprivacy.ca/openprivacy/flutter_gherkin
ref: main
# Uncomment to update lokalise translations (see README for list of deps to comment out bc incompatibilities)
#dev_dependencies:

Binary file not shown.

Before

Width:  |  Height:  |  Size: 252 B

After

Width:  |  Height:  |  Size: 252 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

View File

@ -81,7 +81,7 @@ ShowInstDetails show
Section
# define the output path for this file
SetOutPath $INSTDIR
SetOutPath "$INSTDIR"
# define what to install and place it in the output path
# Filler for .sh to populate with contents of deploy/windows

View File

@ -69,14 +69,14 @@ IDI_APP_ICON_16 ICON "resources\\knot_16.ico"
// Version
//
#ifdef FLUTTER_BUILD_NUMBER
#define VERSION_AS_NUMBER FLUTTER_BUILD_NUMBER
#if defined(FLUTTER_VERSION_MAJOR) && defined(FLUTTER_VERSION_MINOR) && defined(FLUTTER_VERSION_PATCH) && defined(FLUTTER_VERSION_BUILD)
#define VERSION_AS_NUMBER FLUTTER_VERSION_MAJOR,FLUTTER_VERSION_MINOR,FLUTTER_VERSION_PATCH,FLUTTER_VERSION_BUILD
#else
#define VERSION_AS_NUMBER 1,0,0
#define VERSION_AS_NUMBER 1,0,0,0
#endif
#ifdef FLUTTER_BUILD_NAME
#define VERSION_AS_STRING #FLUTTER_BUILD_NAME
#if defined(FLUTTER_VERSION)
#define VERSION_AS_STRING FLUTTER_VERSION
#else
#define VERSION_AS_STRING "1.0.0"
#endif