forked from cwtch.im/cwtch-ui
Merge branch 'trunk' of git.openprivacy.ca:cwtch.im/cwtch-ui into filesharing
This commit is contained in:
commit
4eed72ded3
|
@ -20,7 +20,7 @@ steps:
|
|||
# force by pass of ssh host key check, less secure
|
||||
- ssh-keyscan -H git.openprivacy.ca >> ~/.ssh/known_hosts
|
||||
# use Drone ssh var instead of hardcode to allow forks to build (gogs@git.openprivacy.ca:cwtch.im/cwtch-ui.git)
|
||||
- git clone $DRONE_GIT_SSH_URL .
|
||||
- git clone gogs@git.openprivacy.ca:$DRONE_REPO.git .
|
||||
- git checkout $DRONE_COMMIT
|
||||
|
||||
- name: fetch
|
||||
|
@ -154,7 +154,7 @@ volumes:
|
|||
temp: {}
|
||||
|
||||
trigger:
|
||||
repo: cwtch.im/cwtch-ui
|
||||
#repo: cwtch.im/cwtch-ui # allow forks to build?
|
||||
branch: trunk
|
||||
event:
|
||||
- push
|
||||
|
@ -187,7 +187,7 @@ steps:
|
|||
- git init
|
||||
# -o UserKnownHostsFile=../known_hosts
|
||||
- git config core.sshCommand 'ssh -o StrictHostKeyChecking=no -i ../id_rsa'
|
||||
- git remote add origin $Env:DRONE_GIT_SSH_URL
|
||||
- git remote add origin gogs@git.openprivacy.ca:$Env:DRONE_REPO.git
|
||||
- git pull origin trunk
|
||||
- git fetch --tags
|
||||
- git checkout $Env:DRONE_COMMIT
|
||||
|
@ -271,7 +271,7 @@ steps:
|
|||
- scp -r -o StrictHostKeyChecking=no -i id_rsa deploy\\* buildfiles@build.openprivacy.ca:/home/buildfiles/buildfiles/
|
||||
|
||||
trigger:
|
||||
repo: cwtch.im/cwtch-ui
|
||||
# repo: cwtch.im/cwtch-ui # allow forks to build?
|
||||
branch: trunk
|
||||
event:
|
||||
- push
|
||||
|
|
|
@ -40,8 +40,10 @@ app.*.symbols
|
|||
# Obfuscation related
|
||||
app.*.map.json
|
||||
|
||||
libCwtch.so
|
||||
linux/tor
|
||||
linux/libCwtch.so
|
||||
android/cwtch/cwtch.aar
|
||||
android/app/src/main/jniLibs/*/libtor.so
|
||||
coverage
|
||||
test/failures
|
||||
.gradle
|
|
@ -1 +1 @@
|
|||
v1.2.1-2021-08-30-22-14
|
||||
v1.2.1-2-ga8e7bba-2021-09-14-21-04
|
||||
|
|
29
README.md
29
README.md
|
@ -12,7 +12,7 @@ This README covers build instructions, for information on Cwtch itself please go
|
|||
- `install.home.sh` installs the app into your home directory
|
||||
- `install.sys.sh` as root to install system wide
|
||||
- or run out of the unziped directory
|
||||
- MacOS: Cwtch.dmg coming soon...
|
||||
- MacOS: Available from [https://cwtch.im/download/](https://cwtch.im/download/) as a .dmg
|
||||
|
||||
## Running
|
||||
|
||||
|
@ -25,22 +25,33 @@ Cwtch processes the following environment variables:
|
|||
|
||||
### Getting Started
|
||||
|
||||
First you will need a valid [flutter sdk installation](https://flutter.dev/docs/get-started/install)
|
||||
and run `flutter pub get` to fetch dependencies.
|
||||
|
||||
First you will need a valid [flutter sdk installation](https://flutter.dev/docs/get-started/install).
|
||||
You will probably want to disable Analytics on the Flutter Tool: `flutter config --no-analytics`
|
||||
|
||||
This project uses the flutter `dev` channel, which you will need to switch to: `flutter channel dev; flutter upgrade`.
|
||||
|
||||
Once flutter is set up, run `flutter pub get` from this project folder to fetch dependencies.
|
||||
|
||||
By default a development version is built, which loads profiles from `$CWTCH_HOME/dev/`. This is so that you can build
|
||||
and test development builds with alternative profiles while running a release/stable version of Cwtch uninterrupted.
|
||||
To build a release version and load normal profiles, use `build-release.sh X` instead of `flutter build X`
|
||||
|
||||
### Building on Linux (for Linux)
|
||||
|
||||
- run `fetch-libcwtch-go.sh`libCwtch-go to fetch a prebuild version of `libCwtch-go.so` go to `./linux`. Include `./linux` in `LD_LIBRARY_PATH`
|
||||
- run `fetch-tor.sh` and/or ensure that `tor` is in `$PATH`
|
||||
- run `flutter run -d linux`
|
||||
- copy `libCwtch-go.so` to `linux/`, or run `fetch-libcwtch-go.sh` to download it
|
||||
- set `LD_LIBRARY_PATH="$PWD/linux"`
|
||||
- copy a `tor` binary to `linux/` or run `fetch-tor.sh` to download one
|
||||
- run `flutter config --enable-linux-desktop` if you've never done so before
|
||||
- optional: launch cwtch-ui directly by running `flutter run -d linux`
|
||||
- to build cwtch-ui, run `flutter build linux`
|
||||
- to package the build, run `linux/package-release.sh`
|
||||
|
||||
### Building on Windows (for Windows)
|
||||
|
||||
- run `fetch-libcwtch-go.ps1` to fetch a prebuild version of `libCwtch.dll`
|
||||
- copy `libCwtch.dll` to `windows/`, or run `fetch-libcwtch-go.ps1` to download it
|
||||
- run `fetch-tor-win.ps1` to fetch Tor for windows
|
||||
- run `flutter run -d windows`
|
||||
- optional: launch cwtch-ui directly by running `flutter run -d windows`
|
||||
- to build cwtch-ui, run `flutter build windows`
|
||||
|
||||
### Building on Linux/Windows (for Android)
|
||||
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
#!/bin/sh
|
||||
|
||||
if [ -z "$1" ]; then
|
||||
echo "build-release.sh [android|linux|macos|windows]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -f "VERSION" ]; then
|
||||
VERSION=`cat VERSION`
|
||||
else
|
||||
VERSION=`git describe --tags --abbrev=1`
|
||||
fi
|
||||
|
||||
if [ -f "BUILDDATE" ]; then
|
||||
BUILDDATE=`cat BUILDDATE`
|
||||
else
|
||||
BUILDDATE=`date +%G-%m-%d-%H-%M`
|
||||
fi
|
||||
|
||||
flutter build $1 --dart-define BUILD_VER=$VERSION --dart-define BUILD_DATE=$BUILDDATE
|
|
@ -307,6 +307,8 @@ class CwtchNotifier {
|
|||
if (profileCN.getProfile(data["ProfileOnion"])?.contactList.getContact(data["RemotePeer"]) != null) {
|
||||
profileCN.getProfile(data["ProfileOnion"])?.contactList.getContact(data["RemotePeer"])!.isArchived = data["Data"] == "true";
|
||||
}
|
||||
} else if (data["Key"] == "LastKnowSignature") {
|
||||
// group syncing information that isn't relevant to the UI...
|
||||
} else {
|
||||
EnvironmentConfig.debugLog("unhandled set peer attribute event: ${data['Key']}");
|
||||
}
|
||||
|
|
|
@ -101,7 +101,7 @@ class CwtchFfi implements Cwtch {
|
|||
Map<String, String> envVars = Platform.environment;
|
||||
String cwtchDir = "";
|
||||
if (Platform.isLinux) {
|
||||
cwtchDir = envVars['CWTCH_HOME'] ?? path.join(envVars['HOME']!, ".cwtch");
|
||||
cwtchDir = envVars['CWTCH_HOME'] ?? path.join(envVars['HOME']!, ".cwtch");
|
||||
if (await File("linux/tor").exists()) {
|
||||
bundledTor = "linux/tor";
|
||||
} else if (await File("lib/tor").exists()) {
|
||||
|
@ -120,8 +120,37 @@ class CwtchFfi implements Cwtch {
|
|||
cwtchDir = envVars['CWTCH_HOME'] ?? path.join(envVars['HOME']!, "Library/Application Support/Cwtch");
|
||||
if (await File("Cwtch.app/Contents/MacOS/Tor/tor.real").exists()) {
|
||||
bundledTor = "Cwtch.app/Contents/MacOS/Tor/tor.real";
|
||||
} else if (await File("/Applications/Cwtch.app/Contents/MacOS/Tor/tor.real").exists()) {
|
||||
bundledTor = "/Applications/Cwtch.app/Contents/MacOS/Tor/tor.real";
|
||||
} else if (await File("/Volumes/Cwtch/Cwtch.app/Contents/MacOS/Tor/tor.real").exists()) {
|
||||
bundledTor = "/Volumes/Cwtch/Cwtch.app/Contents/MacOS/Tor/tor.real";
|
||||
} else if (await File("/Applications/Tor Browser.app/Contents/MacOS/Tor/tor.real").exists()) {
|
||||
bundledTor = "/Applications/Tor Browser.app/Contents/MacOS/Tor/tor.real";
|
||||
print("We couldn't find Tor in the Cwtch app directory, however we can fall back to the Tor Browser binary");
|
||||
} else {
|
||||
var splitPath = path.split(dirname(Platform.script.path));
|
||||
if (splitPath[0] == "/" && splitPath[1] == "Applications") {
|
||||
var appName = splitPath[2];
|
||||
print("We're running in /Applications in a non standard app name: $appName");
|
||||
if (await File("/Applications/$appName/Contents/MacOS/Tor/tor.real").exists()) {
|
||||
bundledTor = "/Applications/$appName/Contents/MacOS/Tor/tor.real";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// the first Cwtch MacOS release (1.2) accidently was a dev build
|
||||
// we need to temporarily remedy this for a release or two then delete
|
||||
// if macOs and release build and no profile and is dev profile
|
||||
// copy dev profile to release profile
|
||||
if (Platform.isMacOS && EnvironmentConfig.BUILD_VER != dev_version) {
|
||||
var devProfileExists = await Directory(path.join(cwtchDir, "dev", "profiles")).exists();
|
||||
var releaseProfileExists = await Directory(path.join(cwtchDir, "profiles")).exists();
|
||||
if (devProfileExists && !releaseProfileExists) {
|
||||
print("MacOS one time dev -> release profile migration...");
|
||||
await Process.run("cp", ["-r", "-p", path.join(cwtchDir, "dev", "profiles"), cwtchDir]);
|
||||
await Process.run("cp", ["-r", "-p", path.join(cwtchDir, "dev", "SALT"), cwtchDir]);
|
||||
await Process.run("cp", ["-r", "-p", path.join(cwtchDir, "dev", "ui.globals"), cwtchDir]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -462,7 +491,6 @@ class CwtchFfi implements Cwtch {
|
|||
malloc.free(u2);
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
// ignore: non_constant_identifier_names
|
||||
void UpdateMessageFlags(String profile, String handle, int index, int flags) {
|
||||
|
|
|
@ -1,6 +1,19 @@
|
|||
{
|
||||
"@@locale": "de",
|
||||
"@@last_modified": "2021-08-29T18:35:41+02:00",
|
||||
"@@last_modified": "2021-09-21T23:09:19+02:00",
|
||||
"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 onions",
|
||||
"streamerModeLabel": "Streamer\/Presentation Mode",
|
||||
"archiveConversation": "Archive this Conversation",
|
||||
"profileOnionLabel": "Senden Sie diese Adresse an Peers, mit denen Sie sich verbinden möchten",
|
||||
"addPeerTab": "Einen anderen Nutzer hinzufügen",
|
||||
|
|
|
@ -1,6 +1,19 @@
|
|||
{
|
||||
"@@locale": "en",
|
||||
"@@last_modified": "2021-08-29T18:35:41+02:00",
|
||||
"@@last_modified": "2021-09-21T23:09:19+02:00",
|
||||
"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 onions",
|
||||
"streamerModeLabel": "Streamer\/Presentation Mode",
|
||||
"archiveConversation": "Archive this Conversation",
|
||||
"profileOnionLabel": "Send this address to people you want to connect with",
|
||||
"addPeerTab": "Add a contact",
|
||||
|
|
|
@ -1,6 +1,19 @@
|
|||
{
|
||||
"@@locale": "es",
|
||||
"@@last_modified": "2021-08-29T18:35:41+02:00",
|
||||
"@@last_modified": "2021-09-21T23:09:19+02:00",
|
||||
"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 onions",
|
||||
"streamerModeLabel": "Streamer\/Presentation Mode",
|
||||
"archiveConversation": "Archive this Conversation",
|
||||
"profileOnionLabel": "Envía esta dirección a los contactos con los que quieras conectarte",
|
||||
"addPeerTab": "Agregar Contacto",
|
||||
|
|
|
@ -1,6 +1,19 @@
|
|||
{
|
||||
"@@locale": "fr",
|
||||
"@@last_modified": "2021-08-29T18:35:41+02:00",
|
||||
"@@last_modified": "2021-09-21T23:09:19+02:00",
|
||||
"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": "Si elle est activée, cette option donne un rendu visuel plus privé à l'application pour la diffusion ou la présentation, par exemple en masquant les profils et les contacts.",
|
||||
"streamerModeLabel": "Mode Streamer\/Présentation",
|
||||
"archiveConversation": "Archiver cette conversation",
|
||||
"profileOnionLabel": "Envoyez cette adresse aux personnes avec lesquelles vous souhaitez entrer en contact.",
|
||||
"addPeerTab": "Ajouter un contact",
|
||||
|
|
|
@ -1,6 +1,19 @@
|
|||
{
|
||||
"@@locale": "it",
|
||||
"@@last_modified": "2021-08-29T18:35:41+02:00",
|
||||
"@@last_modified": "2021-09-21T23:09:19+02:00",
|
||||
"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 onions",
|
||||
"streamerModeLabel": "Streamer\/Presentation Mode",
|
||||
"archiveConversation": "Archive this Conversation",
|
||||
"profileOnionLabel": "Inviare questo indirizzo ai peer con cui si desidera connettersi",
|
||||
"addPeerTab": "Aggiungi un peer",
|
||||
|
|
|
@ -1,6 +1,19 @@
|
|||
{
|
||||
"@@locale": "pl",
|
||||
"@@last_modified": "2021-08-29T18:35:41+02:00",
|
||||
"@@last_modified": "2021-09-21T23:09:19+02:00",
|
||||
"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 onions",
|
||||
"streamerModeLabel": "Streamer\/Presentation Mode",
|
||||
"archiveConversation": "Archive this Conversation",
|
||||
"profileOnionLabel": "Send this address to contacts you want to connect with",
|
||||
"addPeerTab": "Add a contact",
|
||||
|
|
|
@ -1,6 +1,19 @@
|
|||
{
|
||||
"@@locale": "pt",
|
||||
"@@last_modified": "2021-08-29T18:35:41+02:00",
|
||||
"@@last_modified": "2021-09-21T23:09:19+02:00",
|
||||
"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 onions",
|
||||
"streamerModeLabel": "Streamer\/Presentation Mode",
|
||||
"archiveConversation": "Archive this Conversation",
|
||||
"profileOnionLabel": "Send this address to contacts you want to connect with",
|
||||
"addPeerTab": "Add a contact",
|
||||
|
|
|
@ -156,7 +156,7 @@ class FlwtchState extends State<Flwtch> {
|
|||
Future.delayed(Duration(seconds: 2)).then((value) {
|
||||
if (Platform.isAndroid) {
|
||||
SystemNavigator.pop();
|
||||
} else if (Platform.isLinux || Platform.isWindows) {
|
||||
} else if (Platform.isLinux || Platform.isWindows || Platform.isMacOS) {
|
||||
print("Exiting...");
|
||||
exit(0);
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ class AppState extends ChangeNotifier {
|
|||
String? _selectedProfile;
|
||||
String? _selectedConversation;
|
||||
int _initialScrollIndex = 0;
|
||||
int _hoveredIndex = -1;
|
||||
int? _selectedIndex;
|
||||
bool _unreadMessagesBelow = false;
|
||||
|
||||
|
@ -63,6 +64,14 @@ class AppState extends ChangeNotifier {
|
|||
notifyListeners();
|
||||
}
|
||||
|
||||
// Never use this for message lookup - can be a non-indexed value
|
||||
// e.g. -1
|
||||
int get hoveredIndex => _hoveredIndex;
|
||||
set hoveredIndex(int newVal) {
|
||||
this._hoveredIndex = newVal;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
bool get unreadMessagesBelow => _unreadMessagesBelow;
|
||||
set unreadMessagesBelow(bool newVal) {
|
||||
this._unreadMessagesBelow = newVal;
|
||||
|
@ -442,21 +451,18 @@ class ContactInfoState extends ChangeNotifier {
|
|||
String? _server;
|
||||
late bool _archived;
|
||||
|
||||
ContactInfoState(
|
||||
this.profileOnion,
|
||||
this.onion, {
|
||||
nickname = "",
|
||||
isGroup = false,
|
||||
authorization = ContactAuthorization.unknown,
|
||||
status = "",
|
||||
imagePath = "",
|
||||
savePeerHistory = "DeleteHistoryConfirmed",
|
||||
numMessages = 0,
|
||||
numUnread = 0,
|
||||
lastMessageTime,
|
||||
server,
|
||||
archived = false
|
||||
}) {
|
||||
ContactInfoState(this.profileOnion, this.onion,
|
||||
{nickname = "",
|
||||
isGroup = false,
|
||||
authorization = ContactAuthorization.unknown,
|
||||
status = "",
|
||||
imagePath = "",
|
||||
savePeerHistory = "DeleteHistoryConfirmed",
|
||||
numMessages = 0,
|
||||
numUnread = 0,
|
||||
lastMessageTime,
|
||||
server,
|
||||
archived = false}) {
|
||||
this._nickname = nickname;
|
||||
this._isGroup = isGroup;
|
||||
this._authorization = authorization;
|
||||
|
@ -482,8 +488,8 @@ class ContactInfoState extends ChangeNotifier {
|
|||
this._archived = archived;
|
||||
notifyListeners();
|
||||
}
|
||||
bool get isArchived => this._archived;
|
||||
|
||||
bool get isArchived => this._archived;
|
||||
|
||||
set savePeerHistory(String newVal) {
|
||||
this._savePeerHistory = newVal;
|
||||
|
|
|
@ -630,7 +630,7 @@ class OpaqueLight extends OpaqueThemeType {
|
|||
static final Color whitePurple = Color(0xFFFFFDFF);
|
||||
static final Color softPurple = Color(0xFFFDF3FC);
|
||||
static final Color purple = Color(0xFFDFB9DE);
|
||||
static final Color brightPurple = Color(0xFF760388);
|
||||
static final Color brightPurple = Color(0xFFD1B0E0);
|
||||
static final Color darkPurple = Color(0xFF350052);
|
||||
static final Color greyPurple = Color(0xFF775F84);
|
||||
static final Color pink = Color(0xFFE85DA1);
|
||||
|
@ -900,11 +900,11 @@ class OpaqueLight extends OpaqueThemeType {
|
|||
}
|
||||
|
||||
Color messageFromMeBackgroundColor() {
|
||||
return darkPurple;
|
||||
return brightPurple;
|
||||
}
|
||||
|
||||
Color messageFromMeTextColor() {
|
||||
return whitePurple;
|
||||
return mainTextColor();
|
||||
}
|
||||
|
||||
Color messageFromOtherBackgroundColor() {
|
||||
|
@ -948,11 +948,14 @@ ThemeData mkThemeData(Settings opaque) {
|
|||
backgroundColor: opaque.current().backgroundMainColor(),
|
||||
highlightColor: opaque.current().hilightElementTextColor(),
|
||||
iconTheme: IconThemeData(
|
||||
color: opaque.current().mainTextColor(),
|
||||
color: opaque.current().toolbarIconColor(),
|
||||
),
|
||||
cardColor: opaque.current().backgroundMainColor(),
|
||||
appBarTheme: AppBarTheme(
|
||||
backgroundColor: opaque.current().backgroundPaneColor(),
|
||||
iconTheme: IconThemeData(
|
||||
color: opaque.current().mainTextColor(),
|
||||
),
|
||||
titleTextStyle: TextStyle(
|
||||
color: opaque.current().mainTextColor(),
|
||||
),
|
||||
|
|
|
@ -32,6 +32,7 @@ class Settings extends ChangeNotifier {
|
|||
DualpaneMode _uiColumnModeLandscape = DualpaneMode.CopyPortrait;
|
||||
|
||||
bool blockUnknownConnections = false;
|
||||
bool streamerMode = false;
|
||||
|
||||
/// Set the dark theme.
|
||||
void setDark() {
|
||||
|
@ -75,11 +76,11 @@ class Settings extends ChangeNotifier {
|
|||
// Set Locale and notify listeners
|
||||
switchLocale(Locale(settings["Locale"]));
|
||||
|
||||
// Decide whether to enable Experiments
|
||||
blockUnknownConnections = settings["BlockUnknownConnections"];
|
||||
blockUnknownConnections = settings["BlockUnknownConnections"] ?? false;
|
||||
streamerMode = settings["StreamerMode"] ?? false;
|
||||
|
||||
// Decide whether to enable Experiments
|
||||
experimentsEnabled = settings["ExperimentsEnabled"];
|
||||
experimentsEnabled = settings["ExperimentsEnabled"] ?? false;
|
||||
|
||||
// Set the internal experiments map. Casting from the Map<dynamic, dynamic> that we get from JSON
|
||||
experiments = new HashMap<String, bool>.from(settings["Experiments"]);
|
||||
|
@ -106,6 +107,11 @@ class Settings extends ChangeNotifier {
|
|||
notifyListeners();
|
||||
}
|
||||
|
||||
setStreamerMode(bool newSteamerMode) {
|
||||
streamerMode = newSteamerMode;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
/// Block Unknown Connections will autoblock connections if they authenticate with public key not in our contacts list.
|
||||
/// This is one of the best tools we have to combat abuse, while it isn't ideal it does allow a user to curate their contacts
|
||||
/// list without being bothered by spurious requests (either permanently, or as a short term measure).
|
||||
|
@ -228,6 +234,7 @@ class Settings extends ChangeNotifier {
|
|||
"Theme": themeString,
|
||||
"PreviousPid": -1,
|
||||
"BlockUnknownConnections": blockUnknownConnections,
|
||||
"StreamerMode": streamerMode,
|
||||
"ExperimentsEnabled": this.experimentsEnabled,
|
||||
"Experiments": experiments,
|
||||
"StateRootPane": 0,
|
||||
|
|
|
@ -30,6 +30,7 @@ void selectConversation(BuildContext context, String handle) {
|
|||
Provider.of<AppState>(context, listen: false).initialScrollIndex = initialIndex;
|
||||
Provider.of<AppState>(context, listen: false).selectedConversation = handle;
|
||||
Provider.of<AppState>(context, listen: false).selectedIndex = null;
|
||||
Provider.of<AppState>(context, listen: false).hoveredIndex = -1;
|
||||
// if in singlepane mode, push to the stack
|
||||
var isLandscape = Provider.of<AppState>(context, listen: false).isLandscape(context);
|
||||
if (Provider.of<Settings>(context, listen: false).uiColumns(isLandscape).length == 1) _pushMessageView(context, handle);
|
||||
|
|
|
@ -137,6 +137,19 @@ class _GlobalSettingsViewState extends State<GlobalSettingsView> {
|
|||
inactiveTrackColor: settings.theme.defaultButtonDisabledColor(),
|
||||
secondary: Icon(CwtchIcons.block_unknown, color: settings.current().mainTextColor()),
|
||||
),
|
||||
SwitchListTile(
|
||||
title: Text(AppLocalizations.of(context)!.streamerModeLabel, style: TextStyle(color: settings.current().mainTextColor())),
|
||||
subtitle: Text(AppLocalizations.of(context)!.descriptionStreamerMode),
|
||||
value: settings.streamerMode,
|
||||
onChanged: (bool value) {
|
||||
settings.setStreamerMode(value);
|
||||
// Save Settings...
|
||||
saveSettings(context);
|
||||
},
|
||||
activeTrackColor: settings.theme.defaultButtonActiveColor(),
|
||||
inactiveTrackColor: settings.theme.defaultButtonDisabledColor(),
|
||||
secondary: Icon(CwtchIcons.block_unknown, color: settings.current().mainTextColor()),
|
||||
),
|
||||
SwitchListTile(
|
||||
title: Text(AppLocalizations.of(context)!.experimentsEnabled, style: TextStyle(color: settings.current().mainTextColor())),
|
||||
subtitle: Text(AppLocalizations.of(context)!.descriptionExperiments),
|
||||
|
|
|
@ -162,11 +162,12 @@ class _GroupSettingsViewState extends State<GroupSettingsView> {
|
|||
onPressed: () {
|
||||
showAlertDialog(context);
|
||||
},
|
||||
style: ButtonStyle (
|
||||
backgroundColor: MaterialStateProperty.all(Colors.transparent)
|
||||
),
|
||||
style: ButtonStyle(backgroundColor: MaterialStateProperty.all(Colors.transparent)),
|
||||
icon: Icon(CwtchIcons.leave_group),
|
||||
label: Text(AppLocalizations.of(context)!.leaveGroup, style: TextStyle(decoration: TextDecoration.underline),),
|
||||
label: Text(
|
||||
AppLocalizations.of(context)!.leaveGroup,
|
||||
style: TextStyle(decoration: TextDecoration.underline),
|
||||
),
|
||||
))
|
||||
])
|
||||
])
|
||||
|
|
|
@ -253,7 +253,7 @@ class _MessageViewState extends State<MessageView> {
|
|||
focusedBorder: InputBorder.none,
|
||||
enabled: true,
|
||||
suffixIcon: ElevatedButton(
|
||||
child: Icon(CwtchIcons.send_24px, size: 24, color: Provider.of<Settings>(context).theme.mainTextColor()),
|
||||
child: Icon(CwtchIcons.send_24px, size: 24, color: Provider.of<Settings>(context).theme.defaultButtonTextColor()),
|
||||
onPressed: isOffline ? null : _sendMessage,
|
||||
))),
|
||||
)))),
|
||||
|
@ -274,18 +274,27 @@ class _MessageViewState extends State<MessageView> {
|
|||
color: message.getMetadata().senderHandle != Provider.of<AppState>(context).selectedProfile
|
||||
? Provider.of<Settings>(context).theme.messageFromOtherBackgroundColor()
|
||||
: Provider.of<Settings>(context).theme.messageFromMeBackgroundColor(),
|
||||
child: Wrap(runAlignment: WrapAlignment.spaceEvenly, alignment: WrapAlignment.spaceEvenly, runSpacing: 1.0, crossAxisAlignment: WrapCrossAlignment.center, children: [
|
||||
Center(widthFactor: 1, child: Padding(padding: EdgeInsets.all(10.0), child: Icon(Icons.reply, size: 32))),
|
||||
Center(widthFactor: 1.0, child: message.getPreviewWidget(context)),
|
||||
Center(
|
||||
widthFactor: 1.0,
|
||||
child: IconButton(
|
||||
icon: Icon(Icons.highlight_remove),
|
||||
tooltip: AppLocalizations.of(context)!.tooltipRemoveThisQuotedMessage,
|
||||
onPressed: () {
|
||||
Provider.of<AppState>(context, listen: false).selectedIndex = null;
|
||||
},
|
||||
))
|
||||
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
|
||||
Stack(children: [
|
||||
Align(
|
||||
alignment: Alignment.topRight,
|
||||
child: IconButton(
|
||||
icon: Icon(Icons.highlight_remove),
|
||||
tooltip: AppLocalizations.of(context)!.tooltipRemoveThisQuotedMessage,
|
||||
onPressed: () {
|
||||
Provider.of<AppState>(context, listen: false).selectedIndex = null;
|
||||
},
|
||||
)),
|
||||
Align(
|
||||
alignment: Alignment.topLeft,
|
||||
child: Padding(padding: EdgeInsets.all(2.0), child: Icon(Icons.reply)),
|
||||
)
|
||||
]),
|
||||
Wrap(
|
||||
runAlignment: WrapAlignment.spaceEvenly,
|
||||
alignment: WrapAlignment.center,
|
||||
runSpacing: 1.0,
|
||||
children: [Center(widthFactor: 1.0, child: Padding(padding: EdgeInsets.all(10.0), child: message.getPreviewWidget(context)))]),
|
||||
]));
|
||||
} else {
|
||||
return MessageLoadingBubble();
|
||||
|
|
|
@ -51,6 +51,7 @@ class _ProfileMgrViewState extends State<ProfileMgrView> {
|
|||
Icon(
|
||||
CwtchIcons.cwtch_knott,
|
||||
size: 36,
|
||||
color: settings.theme.mainTextColor(),
|
||||
),
|
||||
SizedBox(
|
||||
width: 10,
|
||||
|
|
|
@ -65,8 +65,11 @@ class _ContactRowState extends State<ContactRow> {
|
|||
child: LinearProgressIndicator(
|
||||
color: Provider.of<Settings>(context).theme.defaultButtonActiveColor(),
|
||||
)),
|
||||
Text(contact.onion,
|
||||
style: TextStyle(color: contact.isBlocked ? Provider.of<Settings>(context).theme.portraitBlockedTextColor() : Provider.of<Settings>(context).theme.mainTextColor())),
|
||||
Visibility(
|
||||
visible: !Provider.of<Settings>(context).streamerMode,
|
||||
child: Text(contact.onion,
|
||||
style: TextStyle(color: contact.isBlocked ? Provider.of<Settings>(context).theme.portraitBlockedTextColor() : Provider.of<Settings>(context).theme.mainTextColor())),
|
||||
)
|
||||
],
|
||||
))),
|
||||
Padding(
|
||||
|
|
|
@ -56,44 +56,44 @@ class _MessageListState extends State<MessageList> {
|
|||
Text("")),
|
||||
))),
|
||||
Expanded(
|
||||
child: Container(
|
||||
// Only show broken heart is the contact is offline...
|
||||
decoration: BoxDecoration(
|
||||
image: Provider.of<ContactInfoState>(outerContext).isOnline()
|
||||
? null
|
||||
: DecorationImage(
|
||||
fit: BoxFit.scaleDown,
|
||||
alignment: Alignment.center,
|
||||
image: AssetImage("assets/core/negative_heart_512px.png"),
|
||||
colorFilter: ColorFilter.mode(Provider.of<Settings>(context).theme.hilightElementTextColor(), BlendMode.srcIn))),
|
||||
// Don't load messages for syncing server...
|
||||
child: loadMessages
|
||||
? ScrollablePositionedList.builder(
|
||||
itemPositionsListener: widget.scrollListener,
|
||||
itemScrollController: widget.scrollController,
|
||||
initialScrollIndex: Provider.of<AppState>(outerContext, listen: false).initialScrollIndex,
|
||||
itemCount: Provider.of<ContactInfoState>(outerContext).totalMessages,
|
||||
reverse: true, // NOTE: There seems to be a bug in flutter that corrects the mouse wheel scroll, but not the drag direction...
|
||||
itemBuilder: (itemBuilderContext, index) {
|
||||
var profileOnion = Provider.of<ProfileInfoState>(outerContext, listen: false).onion;
|
||||
var contactHandle = Provider.of<ContactInfoState>(outerContext, listen: false).onion;
|
||||
var messageIndex = Provider.of<ContactInfoState>(outerContext).totalMessages - index - 1;
|
||||
child: Container(
|
||||
// Only show broken heart is the contact is offline...
|
||||
decoration: BoxDecoration(
|
||||
image: Provider.of<ContactInfoState>(outerContext).isOnline()
|
||||
? null
|
||||
: DecorationImage(
|
||||
fit: BoxFit.scaleDown,
|
||||
alignment: Alignment.center,
|
||||
image: AssetImage("assets/core/negative_heart_512px.png"),
|
||||
colorFilter: ColorFilter.mode(Provider.of<Settings>(context).theme.hilightElementTextColor(), BlendMode.srcIn))),
|
||||
// Don't load messages for syncing server...
|
||||
child: loadMessages
|
||||
? ScrollablePositionedList.builder(
|
||||
itemPositionsListener: widget.scrollListener,
|
||||
itemScrollController: widget.scrollController,
|
||||
initialScrollIndex: Provider.of<AppState>(outerContext, listen: false).initialScrollIndex,
|
||||
itemCount: Provider.of<ContactInfoState>(outerContext).totalMessages,
|
||||
reverse: true, // NOTE: There seems to be a bug in flutter that corrects the mouse wheel scroll, but not the drag direction...
|
||||
itemBuilder: (itemBuilderContext, index) {
|
||||
var profileOnion = Provider.of<ProfileInfoState>(outerContext, listen: false).onion;
|
||||
var contactHandle = Provider.of<ContactInfoState>(outerContext, listen: false).onion;
|
||||
var messageIndex = Provider.of<ContactInfoState>(outerContext).totalMessages - index - 1;
|
||||
|
||||
return FutureBuilder(
|
||||
future: messageHandler(outerContext, profileOnion, contactHandle, messageIndex),
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.hasData) {
|
||||
var message = snapshot.data as Message;
|
||||
// Already includes MessageRow,,
|
||||
return message.getWidget(context);
|
||||
} else {
|
||||
return MessageLoadingBubble();
|
||||
}
|
||||
},
|
||||
);
|
||||
return FutureBuilder(
|
||||
future: messageHandler(outerContext, profileOnion, contactHandle, messageIndex),
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.hasData) {
|
||||
var message = snapshot.data as Message;
|
||||
// Already includes MessageRow,,
|
||||
return message.getWidget(context);
|
||||
} else {
|
||||
return MessageLoadingBubble();
|
||||
}
|
||||
},
|
||||
)
|
||||
: null))
|
||||
);
|
||||
},
|
||||
)
|
||||
: null))
|
||||
])));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,6 @@ class MessageRow extends StatefulWidget {
|
|||
}
|
||||
|
||||
class MessageRowState extends State<MessageRow> with SingleTickerProviderStateMixin {
|
||||
bool showMenu = false;
|
||||
bool showBlockedMessage = false;
|
||||
late AnimationController _controller;
|
||||
late Animation<Alignment> _animation;
|
||||
|
@ -70,7 +69,7 @@ class MessageRowState extends State<MessageRow> with SingleTickerProviderStateMi
|
|||
}
|
||||
|
||||
Widget wdgIcons = Visibility(
|
||||
visible: this.showMenu,
|
||||
visible: Provider.of<AppState>(context).hoveredIndex == Provider.of<MessageMetadata>(context).messageIndex,
|
||||
maintainSize: true,
|
||||
maintainAnimation: true,
|
||||
maintainState: true,
|
||||
|
@ -164,12 +163,12 @@ class MessageRowState extends State<MessageRow> with SingleTickerProviderStateMi
|
|||
// For desktop...
|
||||
onHover: (event) {
|
||||
setState(() {
|
||||
this.showMenu = true;
|
||||
Provider.of<AppState>(context, listen: false).hoveredIndex = Provider.of<MessageMetadata>(context).messageIndex;
|
||||
});
|
||||
},
|
||||
onExit: (event) {
|
||||
setState(() {
|
||||
this.showMenu = false;
|
||||
Provider.of<AppState>(context, listen: false).hoveredIndex = -1;
|
||||
});
|
||||
},
|
||||
child: GestureDetector(
|
||||
|
|
|
@ -46,12 +46,14 @@ class _ProfileRowState extends State<ProfileRow> {
|
|||
softWrap: true,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
ExcludeSemantics(
|
||||
child: Text(
|
||||
profile.onion,
|
||||
softWrap: true,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
))
|
||||
Visibility(
|
||||
visible: !Provider.of<Settings>(context).streamerMode,
|
||||
child: ExcludeSemantics(
|
||||
child: Text(
|
||||
profile.onion,
|
||||
softWrap: true,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
)))
|
||||
],
|
||||
)),
|
||||
IconButton(
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
#!/bin/sh
|
||||
|
||||
env LD_LIBRARY_PATH=./lib/ ./lib/cwtch
|
||||
exec env LD_LIBRARY_PATH=./lib/ ./lib/cwtch
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
#!/bin/sh
|
||||
|
||||
env LD_LIBRARY_PATH=~/.local/lib/cwtch/ ~/.local/lib/cwtch/cwtch
|
||||
exec env LD_LIBRARY_PATH=~/.local/lib/cwtch/ ~/.local/lib/cwtch/cwtch
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
#!/bin/sh
|
||||
|
||||
env LD_LIBRARY_PATH=/usr/lib/cwtch /usr/lib/cwtch/cwtch
|
||||
exec env LD_LIBRARY_PATH=/usr/lib/cwtch /usr/lib/cwtch/cwtch
|
||||
|
|
Loading…
Reference in New Issue