Compare commits

..

4 Commits

Author SHA1 Message Date
erinn 0f3aabdea5 Merge branch 'trunk' of git.openprivacy.ca:flutter/flutter_app into dualpane
continuous-integration/drone/pr Build is passing Details
2021-06-24 00:36:59 -07:00
erinn 8bbaa2e28d dual pane wiring 2021-06-24 00:36:41 -07:00
erinn f3858e5fd7 Merge branch 'trunk' of git.openprivacy.ca:flutter/flutter_app into dualpane 2021-06-23 17:35:40 -07:00
erinn 108494be53 dualpane settings wiring 2021-06-23 17:35:33 -07:00
43 changed files with 421 additions and 398 deletions

View File

@ -1,3 +1,184 @@
---
kind: pipeline
type: docker
name: linux-android-test
clone:
disable: true
steps:
- name: clone
image: cirrusci/flutter:dev
environment:
buildbot_key_b64:
from_secret: buildbot_key_b64
commands:
- mkdir ~/.ssh
- echo $buildbot_key_b64 > ~/.ssh/id_rsa.b64
- base64 -d ~/.ssh/id_rsa.b64 > ~/.ssh/id_rsa
- chmod 400 ~/.ssh/id_rsa
# force by pass of ssh host key check, less secure
- ssh-keyscan -H git.openprivacy.ca >> ~/.ssh/known_hosts
- git clone gogs@git.openprivacy.ca:flutter/flutter_app.git .
- git checkout $DRONE_COMMIT
- name: fetch
image: cirrusci/flutter:dev
volumes:
- name: deps
path: /root/.pub-cache
commands:
- ./fetch-tor.sh
- echo `git describe --tags` > VERSION
- echo `date +%G-%m-%d-%H-%M` > BUILDDATE
- flutter pub get
- mkdir deploy
- ./fetch-libcwtch-go.sh
#- name: quality
# image: golang
# volumes:
# - name: deps
# path: /go
# commands:
# - go list ./... | xargs go vet
# - go list ./... | xargs golint
# #Todo: fix all the lint errors and add `-set_exit_status` above to enforce linting
- name: build-linux
image: openpriv/flutter-desktop:linux-dev
volumes:
- name: deps
path: /root/.pub-cache
commands:
- flutter build linux --dart-define BUILD_VER=`cat VERSION` --dart-define BUILD_DATE=`cat BUILDDATE`
- mkdir deploy/linux
- cp -r build/linux/x64/release/bundle/* deploy/linux
- cp linux/cwtch.*.desktop deploy/linux
- cp linux/install-*.sh deploy/linux
- cp linux/cwtch.png deploy/linux
- cp linux/libCwtch.so deploy/linux/lib/
# should not be needed, should be in data/flutter_assets and work from there
#- cp /sdks/flutter/bin/cache/artifacts/engine/linux-x64/icudtl.dat deploy/linux
- cp linux/tor deploy/linux
- cd deploy
- mv linux cwtch
- tar -czf cwtch-`cat ../VERSION`.tar.gz cwtch
- rm -r cwtch
- name: test-build-android
image: cirrusci/flutter:dev
when:
event: pull_request
volumes:
- name: deps
path: /root/.pub-cache
commands:
- flutter build apk --debug
- name: build-android
image: cirrusci/flutter:dev
when:
event: push
environment:
upload_jks_file_b64:
from_secret: upload_jks_file_b64
upload_jks_pass:
from_secret: upload_jks_pass
volumes:
- name: deps
path: /root/.pub-cache
commands:
- echo $upload_jks_file_b64 > upload-keystore.jks.b64
- base64 -i --decode upload-keystore.jks.b64 > android/app/upload-keystore.jks
- sed -i "s/%jks-password%/$upload_jks_pass/g" android/key.properties
- flutter build appbundle --dart-define BUILD_VER=`cat VERSION` --dart-define BUILD_DATE=`cat BUILDDATE`
# cant do debug for final release, this is just a stop gap
- flutter build apk --dart-define BUILD_VER=`cat VERSION` --dart-define BUILD_DATE=`cat BUILDDATE`
# or build apk --split-per-abi ?
- cp build/app/outputs/bundle/release/app-release.aab deploy/
- cp build/app/outputs/apk/release/app-release.apk deploy/
#- cp build/app/outputs/flutter-apk/app-debug.apk deploy/android
- name: widget-tests
image: cirrusci/flutter:dev
volumes:
- name: deps
path: /root/.pub-cache
commands:
# - flutter config --enable-linux-desktop
- flutter test --coverage
- genhtml coverage/lcov.info -o coverage/html
# Todo: gonna need more work on container
# https://flutter.dev/desktop
# requirements: Visual Studio 2019 (not to be confused with Visual Studio Code) with the “Desktop development with C++” workload installed, including all of its default components
#- name: build-windows
# image: cirrusci/flutter:dev
#- volumes:
# - name: deps
# path: /root/.pub-cache
# commands:
# - flutter config --enable-windows-desktop
# - flutter build windows
- name: deploy-buildfiles
image: kroniak/ssh-client
environment:
BUILDFILES_KEY:
from_secret: buildfiles_key
secrets: [gogs_account_token]
when:
event: push
status: [ success ]
commands:
- echo $BUILDFILES_KEY > ~/id_rsab64
- base64 -d ~/id_rsab64 > ~/id_rsa
- chmod 400 ~/id_rsa
- export DIR=flwtch-`cat VERSION`-`cat BUILDDATE`
- mv deploy $DIR
- cp -r coverage/html $DIR/coverage-tests
- cp -r test/failures $DIR/test-failures || true
- cd $DIR
- find . -type f -exec sha256sum {} \; > ./../sha256s.txt
- mv ./../sha256s.txt .
- cd ..
# TODO: do deployment once files actaully compile
- scp -r -o StrictHostKeyChecking=no -i ~/id_rsa $DIR buildfiles@openprivacy.ca:/home/buildfiles/buildfiles/
- name: notify-email
image: drillster/drone-email
settings:
host: build.openprivacy.ca
port: 25
skip_verify: true
from: drone@openprivacy.ca
when:
status: [ failure ]
- name: notify-gogs
image: openpriv/drone-gogs
when:
event: pull_request
status: [ success, changed, failure ]
environment:
GOGS_ACCOUNT_TOKEN:
from_secret: gogs_account_token
settings:
gogs_url: https://git.openprivacy.ca
volumes:
- name: deps
temp: {}
trigger:
repo: flutter/flutter_app
branch: trunk
event:
- push
- pull_request
---
kind: pipeline
type: docker
name: windows
@ -40,11 +221,26 @@ steps:
- name: build-windows
image: openpriv/flutter-desktop:windows-sdk30-fdev2.3rc
environment:
pfx:
from_secret: pfx
pfx_pass:
from_secret: pfx_pass
commands:
- move pubspec.yaml pubspec.yaml.orig
- (Get-Content -path pubspec.yaml.orig -Raw) -Replace 'pfx_pass',"$Env:pfx_pass" | Set-Content -path pubspec.yaml
- flutter pub get
- $Env:version += type .\VERSION
- $Env:builddate += type .\BUILDDATE
- $Env:buildname = 'flwtch-win-' + $Env:version + '-' + $Env:builddate
- $Env:builddir = $Env:buildname
- $Env:zip = 'cwtch-' + $Env:version + '.zip'
- $Env:zipsha = $Env:zip + '.sha512'
- $Env:msix = 'cwtch-install-' + $Env:version + '.msix'
- $Env:msixsha = $Env:msix + '.sha512'
- $Env:releasedir = "build\\windows\\runner\\Release\\"
- echo $Env:releasedir
- echo $Env:builddir
- flutter build windows --dart-define BUILD_VER=$Env:version --dart-define BUILD_DATE=$Env:builddate
- copy windows\libCwtch.dll $Env:releasedir
# flutter hasn't worked out it's packaging of required dll's so we have to resort to this manual nonsense
@ -54,46 +250,24 @@ steps:
- copy C:\BuildTools\VC\Redist\MSVC\14.29.30036\x64\Microsoft.VC142.CRT\vcruntime140_1.dll $Env:releasedir
- copy C:\BuildTools\VC\Redist\MSVC\14.29.30036\x64\Microsoft.VC142.CRT\msvcp140.dll $Env:releasedir
- powershell -command "Expand-Archive -Path tor.zip -DestinationPath $Env:releasedir\Tor"
- name: package-windows
image: openpriv/nsis:latest
environment:
pfx:
from_secret: pfx
pfx_pass:
from_secret: pfx_pass
commands:
- $Env:version += type .\VERSION
- $Env:builddate += type .\BUILDDATE
- $Env:releasedir = "build\\windows\\runner\\Release\\"
- $Env:zip = 'cwtch-' + $Env:version + '.zip'
- $Env:zipsha = $Env:zip + '.sha512'
- $Env:msix = 'cwtch-install-' + $Env:version + '.msix'
- $Env:msixsha = $Env:msix + '.sha512'
- $Env:buildname = 'flwtch-win-' + $Env:version + '-' + $Env:builddate
- $Env:builddir = $Env:buildname
- dir $Env:releasedir
- echo $Env:pfx > codesign.pfx.b64
- certutil -decode codesign.pfx.b64 codesign.pfx
- signtool sign /v /fd sha256 /a /f codesign.pfx /p $Env:pfx_pass /tr http://timestamp.digicert.com $Env:releasedir\cwtch.exe
- copy windows\runner\resources\knot_128.ico $Env:releasedir\cwtch.ico
- makensis windows\nsis\cwtch-installer.nsi
- move windows\nsis\cwtch-installer.exe cwtch-installer.exe
- signtool sign /v /fd sha256 /a /f codesign.pfx /p $Env:pfx_pass /tr http://timestamp.digicert.com cwtch-installer.exe
- powershell -command "(Get-FileHash cwtch-installer.exe -Algorithm sha512).Hash" > cwtch-installer.sha512
- flutter pub run msix:create
- mkdir deploy
- mkdir deploy\$Env:builddir
- dir deploy
- powershell -command "move $Env:releasedir\cwtch.msix deploy\$Env:builddir\$Env:msix"
- move $Env:releasedir $Env:builddir
- powershell -command "Compress-Archive -Path $Env:builddir -DestinationPath cwtch.zip"
- powershell -command "(Get-FileHash cwtch.zip -Algorithm sha512).Hash" > $Env:zipsha
- move cwtch-installer.exe deploy\$Env:builddir\cwtch-installer.exe
- move cwtch.zip deploy\$Env:builddir\$Env:zip
- move *.sha512 deploy\$Env:builddir
- powershell -command "Compress-Archive -Path $Env:builddir -DestinationPath $Env:zip"
- powershell -command "move $Env:zip deploy\$Env:builddir\"
- powershell -command "(Get-FileHash deploy\$Env:builddir\$Env:zip -Algorithm sha512).Hash" > deploy\$Env:builddir\$Env:sha
- name: deploy-windows
image: openpriv/flutter-desktop:windows-sdk30-fdev2.3rc
when:
event: push
status: [ success ]
event: push
status: [ success ]
environment:
BUILDFILES_KEY:
from_secret: buildfiles_key

View File

@ -1 +1 @@
v0.0.2-108-g3964348-2021-06-24-17-42
v0.0.2-104-gc1b7e4c-2021-06-22-23-59

View File

@ -1,9 +0,0 @@
MIT License
Copyright (c) 2021 Open Privacy Research Society
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -1,4 +1,4 @@
# Cwtch UI
# flwtch
A Flutter based Cwtch UI

View File

@ -1,6 +1,6 @@
Invoke-WebRequest -Uri https://dist.torproject.org/torbrowser/10.0.18/tor-win64-0.4.5.9.zip -OutFile tor.zip
Invoke-WebRequest -Uri https://www.torproject.org/dist/torbrowser/10.0.16/tor-win32-0.4.5.7.zip -OutFile tor.zip
if ((Get-FileHash tor.zip -Algorithm sha512).Hash -ne '72764eb07ad8ab511603aba0734951ca003989f5f4686af91ba220217b4a8a4bcc5f571b59f52c847932f6efedf847b111621983050fcddbb8099d43ca66fb07' ) { Write-Error 'tor.zip sha512sum mismatch' }
if ((Get-FileHash tor.zip -Algorithm sha512).Hash -ne '2b7d683f036d0fec149f1d2bdfcf5b7ef4c337005a2b685c056b00047fdb2b57d4c25b8559ad7ef5c7a030b273934be82a9f83ef6e391f5d7d13d8d6c83e8048' ) { Write-Error 'tor.zip sha512sum mismatch' }
Expand-Archive -Path tor.zip -DestinationPath Tor

View File

@ -37,8 +37,7 @@ class CwtchNotifier {
appState.SetAppError(data["Error"]);
break;
case "NewPeer":
// 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["ContactsJson"], data["ServerList"], data["Online"] == "true", data["tag"] != "v1-defaultPassword");
profileCN.add(data["Identity"], data["name"], data["picture"], data["ContactsJson"], data["ServerList"], data["Online"] == "true");
break;
case "PeerCreated":
profileCN.getProfile(data["ProfileOnion"])?.contactList.add(ContactInfoState(

View File

@ -1,10 +1,6 @@
{
"@@locale": "de",
"@@last_modified": "2021-06-24T23:32:06+02:00",
"tooltipHidePassword": "Hide Password",
"tooltipShowPassword": "Show Password",
"serverNotSynced": "Syncing New Messages (This can take some time)...",
"groupInviteSettingsWarning": "You have been invited to join a group! Please enable the Group Chat Experiment in Settings to view this Invitation.",
"@@last_modified": "2021-06-16T23:15:48+02:00",
"shutdownCwtchAction": "Shutdown Cwtch",
"shutdownCwtchDialog": "Are you sure you want to shutdown Cwtch? This will close all connections, and exit the application.",
"shutdownCwtchDialogTitle": "Shutdown Cwtch?",
@ -158,6 +154,7 @@
"inviteToGroupLabel": "In die Gruppe einladen",
"groupNameLabel": "Gruppenname",
"viewServerInfo": "Server Info",
"serverNotSynced": "Out of Sync",
"serverSynced": "Synced",
"serverConnectivityDisconnected": "Server getrennt",
"serverConnectivityConnected": "Server verbunden",

View File

@ -1,10 +1,6 @@
{
"@@locale": "en",
"@@last_modified": "2021-06-24T23:32:06+02:00",
"tooltipHidePassword": "Hide Password",
"tooltipShowPassword": "Show Password",
"serverNotSynced": "Syncing New Messages (This can take some time)...",
"groupInviteSettingsWarning": "You have been invited to join a group! Please enable the Group Chat Experiment in Settings to view this Invitation.",
"@@last_modified": "2021-06-16T23:15:48+02:00",
"shutdownCwtchAction": "Shutdown Cwtch",
"shutdownCwtchDialog": "Are you sure you want to shutdown Cwtch? This will close all connections, and exit the application.",
"shutdownCwtchDialogTitle": "Shutdown Cwtch?",
@ -158,6 +154,7 @@
"inviteToGroupLabel": "Invite to group",
"groupNameLabel": "Group Name",
"viewServerInfo": "Server Info",
"serverNotSynced": "Out of Sync",
"serverSynced": "Synced",
"serverConnectivityDisconnected": "Server Disconnected",
"serverConnectivityConnected": "Server Connected",

View File

@ -1,10 +1,6 @@
{
"@@locale": "es",
"@@last_modified": "2021-06-24T23:32:06+02:00",
"tooltipHidePassword": "Hide Password",
"tooltipShowPassword": "Show Password",
"serverNotSynced": "Fuera de sincronización con el servidor",
"groupInviteSettingsWarning": "You have been invited to join a group! Please enable the Group Chat Experiment in Settings to view this Invitation.",
"@@last_modified": "2021-06-16T23:15:48+02:00",
"shutdownCwtchAction": "Shutdown Cwtch",
"shutdownCwtchDialog": "Are you sure you want to shutdown Cwtch? This will close all connections, and exit the application.",
"shutdownCwtchDialogTitle": "Shutdown Cwtch?",
@ -158,6 +154,7 @@
"inviteToGroupLabel": "Invitar al grupo",
"groupNameLabel": "Nombre del grupo",
"viewServerInfo": "Información del servidor",
"serverNotSynced": "Fuera de sincronización con el servidor",
"serverSynced": "Sincronizado",
"serverConnectivityDisconnected": "Servidor desconectado",
"serverConnectivityConnected": "Servidor conectado",

View File

@ -1,10 +1,6 @@
{
"@@locale": "fr",
"@@last_modified": "2021-06-24T23:32:06+02:00",
"tooltipHidePassword": "Hide Password",
"tooltipShowPassword": "Show Password",
"serverNotSynced": "Syncing New Messages (This can take some time)...",
"groupInviteSettingsWarning": "You have been invited to join a group! Please enable the Group Chat Experiment in Settings to view this Invitation.",
"@@last_modified": "2021-06-16T23:15:48+02:00",
"shutdownCwtchAction": "Shutdown Cwtch",
"shutdownCwtchDialog": "Are you sure you want to shutdown Cwtch? This will close all connections, and exit the application.",
"shutdownCwtchDialogTitle": "Shutdown Cwtch?",
@ -158,6 +154,7 @@
"inviteToGroupLabel": "Inviter quelqu'un",
"groupNameLabel": "Nom du groupe",
"viewServerInfo": "Server Info",
"serverNotSynced": "Out of Sync",
"serverSynced": "Synced",
"serverConnectivityDisconnected": "Server Disconnected",
"serverConnectivityConnected": "Server Connected",

View File

@ -1,10 +1,6 @@
{
"@@locale": "it",
"@@last_modified": "2021-06-24T23:32:06+02:00",
"tooltipHidePassword": "Hide Password",
"tooltipShowPassword": "Show Password",
"serverNotSynced": "Non sincronizzato",
"groupInviteSettingsWarning": "You have been invited to join a group! Please enable the Group Chat Experiment in Settings to view this Invitation.",
"@@last_modified": "2021-06-16T23:15:48+02:00",
"shutdownCwtchAction": "Shutdown Cwtch",
"shutdownCwtchDialog": "Are you sure you want to shutdown Cwtch? This will close all connections, and exit the application.",
"shutdownCwtchDialogTitle": "Shutdown Cwtch?",
@ -158,6 +154,7 @@
"inviteToGroupLabel": "Invitare nel gruppo",
"groupNameLabel": "Nome del gruppo",
"viewServerInfo": "Informazioni sul server",
"serverNotSynced": "Non sincronizzato",
"serverSynced": "Sincronizzato",
"serverConnectivityDisconnected": "Server disconnesso",
"serverConnectivityConnected": "Server connesso",

View File

@ -1,10 +1,6 @@
{
"@@locale": "pt",
"@@last_modified": "2021-06-24T23:32:06+02:00",
"tooltipHidePassword": "Hide Password",
"tooltipShowPassword": "Show Password",
"serverNotSynced": "Syncing New Messages (This can take some time)...",
"groupInviteSettingsWarning": "You have been invited to join a group! Please enable the Group Chat Experiment in Settings to view this Invitation.",
"@@last_modified": "2021-06-16T23:15:48+02:00",
"shutdownCwtchAction": "Shutdown Cwtch",
"shutdownCwtchDialog": "Are you sure you want to shutdown Cwtch? This will close all connections, and exit the application.",
"shutdownCwtchDialogTitle": "Shutdown Cwtch?",
@ -158,6 +154,7 @@
"inviteToGroupLabel": "Convidar ao grupo",
"groupNameLabel": "Nome do Grupo",
"viewServerInfo": "Server Info",
"serverNotSynced": "Out of Sync",
"serverSynced": "Synced",
"serverConnectivityDisconnected": "Server Disconnected",
"serverConnectivityConnected": "Server Connected",

View File

@ -114,7 +114,4 @@ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.''');
yield LicenseEntryWithLineBreaks(["flaticons"], "Icons made by Freepik (https://www.freepik.com) from Flaticon (www.flaticon.com)");
}

View File

@ -22,7 +22,7 @@ import 'dart:io' show Platform, exit;
import 'opaque.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
var globalSettings = Settings(Locale("en", ''), OpaqueDark());
var globalSettings = Settings(Locale("en", ''), Opaque.dark);
var globalErrorHandler = ErrorHandler();
var globalTorStatus = TorStatus();
var globalAppState = AppState();

View File

@ -13,8 +13,9 @@ import 'dart:typed_data';
import 'package:flutter_test/flutter_test.dart';
import 'package:glob/glob.dart';
//import 'package:glob/list_local_fs.dart';
var globalSettings = Settings(Locale("en", ''), OpaqueDark());
var globalSettings = Settings(Locale("en", ''), Opaque.dark);
var globalErrorHandler = ErrorHandler();
void main() {

View File

@ -38,10 +38,10 @@ class ProfileListState extends ChangeNotifier {
List<ProfileInfoState> _profiles = [];
int get num => _profiles.length;
void add(String onion, String name, String picture, String contactsJson, String serverJson, bool online, bool encrypted) {
void add(String onion, String name, String picture, String contactsJson, String serverJson, bool online) {
var idx = _profiles.indexWhere((element) => element.onion == onion);
if (idx == -1) {
_profiles.add(ProfileInfoState(onion: onion, nickname: name, imagePath: picture, contactsJson: contactsJson, serversJson: serverJson, online: online, encrypted: encrypted));
_profiles.add(ProfileInfoState(onion: onion, nickname: name, imagePath: picture, contactsJson: contactsJson, serversJson: serverJson, online: online));
} else {
_profiles[idx].updateFrom(onion, name, picture, contactsJson, serverJson, online);
}
@ -177,10 +177,6 @@ class ProfileInfoState extends ChangeNotifier {
int _unreadMessages = 0;
bool _online = false;
// assume profiles are encrypted...this will be set to false
// in the constructor if the profile is encrypted with the defacto password.
bool _encrypted = true;
ProfileInfoState({
required this.onion,
nickname = "",
@ -189,13 +185,11 @@ class ProfileInfoState extends ChangeNotifier {
contactsJson = "",
serversJson = "",
online = false,
encrypted = true,
}) {
this._nickname = nickname;
this._imagePath = imagePath;
this._unreadMessages = unreadMessages;
this._online = online;
this._encrypted = encrypted;
if (contactsJson != null && contactsJson != "" && contactsJson != "null") {
List<dynamic> contacts = jsonDecode(contactsJson);
@ -249,9 +243,6 @@ class ProfileInfoState extends ChangeNotifier {
notifyListeners();
}
// Check encrypted status for profile info screen
bool get isEncrypted => this._encrypted;
String get nickname => this._nickname;
set nickname(String newValue) {
this._nickname = newValue;
@ -437,8 +428,7 @@ class ContactInfoState extends ChangeNotifier {
bool isOnline() {
if (this.isGroup == true) {
// We now have an out of sync warning so we will mark these as online...
return this.status == "Authenticated" || this.status == "Synced";
return this.status == "Synced";
} else {
return this.status == "Authenticated";
}

View File

@ -10,11 +10,6 @@ import 'package:cwtch/settings.dart';
abstract class OpaqueThemeType {
static final Color red = Color(0xFFFF0000);
String identifier() {
return "dummy";
}
Color backgroundMainColor() {
return red;
}
@ -309,15 +304,9 @@ abstract class OpaqueThemeType {
// ... more to come
// Sizes
double contactOnionTextSize() {
return 18;
}
}
class OpaqueDark extends OpaqueThemeType {
class CwtchDark extends OpaqueThemeType {
static final Color darkGreyPurple = Color(0xFF281831);
static final Color deepPurple = Color(0xFF422850);
static final Color mauvePurple = Color(0xFF8E64A5);
@ -330,10 +319,6 @@ class OpaqueDark extends OpaqueThemeType {
static final Color softGreen = Color(0xFFA0FFB0);
static final Color softRed = Color(0xFFFFA0B0);
String identifier() {
return "dark";
}
Color backgroundMainColor() {
return darkGreyPurple;
}
@ -627,7 +612,7 @@ class OpaqueDark extends OpaqueThemeType {
}
}
class OpaqueLight extends OpaqueThemeType {
class CwtchLight extends OpaqueThemeType {
static final Color whitePurple = Color(0xFFFFFDFF);
static final Color softPurple = Color(0xFFFDF3FC);
static final Color purple = Color(0xFFDFB9DE);
@ -640,10 +625,6 @@ class OpaqueLight extends OpaqueThemeType {
static final Color softGreen = Color(0xFFA0FFB0);
static final Color softRed = Color(0xFFFFA0B0);
String identifier() {
return "light";
}
Color backgroundMainColor() {
return whitePurple;
}
@ -937,99 +918,6 @@ class OpaqueLight extends OpaqueThemeType {
}
}
ThemeData mkThemeData(Settings opaque) {
return ThemeData(
visualDensity: VisualDensity.adaptivePlatformDensity,
primarySwatch: Colors.red,
primaryIconTheme: IconThemeData(
color: opaque.current().mainTextColor(),
),
primaryColor: opaque.current().backgroundMainColor(),
canvasColor: opaque.current().backgroundPaneColor(),
backgroundColor: opaque.current().backgroundMainColor(),
highlightColor: opaque.current().hilightElementTextColor(),
iconTheme: IconThemeData(
color: opaque.current().mainTextColor(),
),
cardColor: opaque.current().backgroundMainColor(),
appBarTheme: AppBarTheme(
backgroundColor: opaque.current().backgroundPaneColor(),
titleTextStyle: TextStyle(
color: opaque.current().mainTextColor(),
),
actionsIconTheme: IconThemeData(
color: opaque.current().mainTextColor(),
)),
bottomNavigationBarTheme: BottomNavigationBarThemeData(type: BottomNavigationBarType.fixed, backgroundColor: opaque.current().backgroundHilightElementColor()),
textButtonTheme: TextButtonThemeData(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(opaque.current().defaultButtonColor()),
foregroundColor: MaterialStateProperty.all(opaque.current().defaultButtonTextColor()),
overlayColor: MaterialStateProperty.all(opaque.current().defaultButtonActiveColor()),
padding: MaterialStateProperty.all(EdgeInsets.all(20))),
),
elevatedButtonTheme: ElevatedButtonThemeData(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(opaque.current().defaultButtonColor()),
foregroundColor: MaterialStateProperty.all(opaque.current().defaultButtonTextColor()),
overlayColor: MaterialStateProperty.all(opaque.current().defaultButtonActiveColor()),
padding: MaterialStateProperty.all(EdgeInsets.all(20)),
shape: MaterialStateProperty.all(RoundedRectangleBorder(
borderRadius: BorderRadius.circular(18.0),
)),
),
),
scrollbarTheme: ScrollbarThemeData(
isAlwaysShown: false, thumbColor: MaterialStateProperty.all(opaque.current().scrollbarActiveColor()), trackColor: MaterialStateProperty.all(opaque.current().scrollbarDefaultColor())),
tabBarTheme: TabBarTheme(indicator: UnderlineTabIndicator(borderSide: BorderSide(color: opaque.current().defaultButtonActiveColor()))),
dialogTheme: DialogTheme(
backgroundColor: opaque.current().backgroundPaneColor(),
titleTextStyle: TextStyle(color: opaque.current().mainTextColor()),
contentTextStyle: TextStyle(color: opaque.current().mainTextColor())),
textTheme: TextTheme(
headline1: TextStyle(color: opaque.current().mainTextColor()),
headline2: TextStyle(color: opaque.current().mainTextColor()),
headline3: TextStyle(color: opaque.current().mainTextColor()),
headline4: TextStyle(color: opaque.current().mainTextColor()),
headline5: TextStyle(color: opaque.current().mainTextColor()),
headline6: TextStyle(color: opaque.current().mainTextColor()),
bodyText1: TextStyle(color: opaque.current().mainTextColor()),
bodyText2: TextStyle(color: opaque.current().mainTextColor()),
subtitle1: TextStyle(color: opaque.current().mainTextColor()),
subtitle2: TextStyle(color: opaque.current().mainTextColor()),
caption: TextStyle(color: opaque.current().mainTextColor()),
button: TextStyle(color: opaque.current().mainTextColor()),
overline: TextStyle(color: opaque.current().mainTextColor())),
switchTheme: SwitchThemeData(
overlayColor: MaterialStateProperty.all(opaque.current().defaultButtonActiveColor()),
thumbColor: MaterialStateProperty.all(opaque.current().mainTextColor()),
trackColor: MaterialStateProperty.all(opaque.current().dropShadowColor()),
),
floatingActionButtonTheme: FloatingActionButtonThemeData(backgroundColor: opaque.current().defaultButtonColor(), hoverColor: opaque.current().defaultButtonActiveColor()),
textSelectionTheme: TextSelectionThemeData(
cursorColor: opaque.current().defaultButtonActiveColor(), selectionColor: opaque.current().defaultButtonActiveColor(), selectionHandleColor: opaque.current().defaultButtonActiveColor()),
);
}
/*
OpaqueThemeType _current = CwtchDark();
void setDark() {
_current = CwtchDark();
}
void setLight() {
_current = CwtchLight();
}
OpaqueThemeType current() {
if (_current == null) {
setDark();
}
return _current;
}
class Opaque extends OpaqueThemeType {
Color backgroundMainColor() {
return current().backgroundMainColor();
@ -1338,9 +1226,22 @@ class Opaque extends OpaqueThemeType {
}
static late OpaqueThemeType _current;
//static final OpaqueThemeType dark = CwtchDark();
//static final OpaqueThemeType light = CwtchLight();
static final OpaqueThemeType dark = CwtchDark();
static final OpaqueThemeType light = CwtchLight();
static void setDark() {
_current = dark;
}
static void setLight() {
_current = light;
}
static OpaqueThemeType current() {
if (_current == null) {
setDark();
}
return _current;
}
int scale = 2;
static final String gcdOS = "linux";
@ -1440,4 +1341,76 @@ class Opaque extends OpaqueThemeType {
}
}
*/
ThemeData mkThemeData(Settings opaque) {
return ThemeData(
visualDensity: VisualDensity.adaptivePlatformDensity,
primarySwatch: Colors.red,
primaryIconTheme: IconThemeData(
color: opaque.current().mainTextColor(),
),
primaryColor: opaque.current().backgroundMainColor(),
canvasColor: opaque.current().backgroundPaneColor(),
backgroundColor: opaque.current().backgroundMainColor(),
highlightColor: opaque.current().hilightElementTextColor(),
iconTheme: IconThemeData(
color: opaque.current().mainTextColor(),
),
cardColor: opaque.current().backgroundMainColor(),
appBarTheme: AppBarTheme(
backgroundColor: opaque.current().backgroundPaneColor(),
titleTextStyle: TextStyle(
color: opaque.current().mainTextColor(),
),
actionsIconTheme: IconThemeData(
color: opaque.current().mainTextColor(),
)),
bottomNavigationBarTheme: BottomNavigationBarThemeData(type: BottomNavigationBarType.fixed, backgroundColor: opaque.current().backgroundHilightElementColor()),
textButtonTheme: TextButtonThemeData(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(opaque.current().defaultButtonColor()),
foregroundColor: MaterialStateProperty.all(opaque.current().defaultButtonTextColor()),
overlayColor: MaterialStateProperty.all(opaque.current().defaultButtonActiveColor()),
padding: MaterialStateProperty.all(EdgeInsets.all(20))),
),
elevatedButtonTheme: ElevatedButtonThemeData(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(opaque.current().defaultButtonColor()),
foregroundColor: MaterialStateProperty.all(opaque.current().defaultButtonTextColor()),
overlayColor: MaterialStateProperty.all(opaque.current().defaultButtonActiveColor()),
padding: MaterialStateProperty.all(EdgeInsets.all(20)),
shape: MaterialStateProperty.all(RoundedRectangleBorder(
borderRadius: BorderRadius.circular(18.0),
)),
),
),
scrollbarTheme: ScrollbarThemeData(
isAlwaysShown: false, thumbColor: MaterialStateProperty.all(opaque.current().scrollbarActiveColor()), trackColor: MaterialStateProperty.all(opaque.current().scrollbarDefaultColor())),
tabBarTheme: TabBarTheme(indicator: UnderlineTabIndicator(borderSide: BorderSide(color: opaque.current().defaultButtonActiveColor()))),
dialogTheme: DialogTheme(
backgroundColor: opaque.current().backgroundPaneColor(),
titleTextStyle: TextStyle(color: opaque.current().mainTextColor()),
contentTextStyle: TextStyle(color: opaque.current().mainTextColor())),
textTheme: TextTheme(
headline1: TextStyle(color: opaque.current().mainTextColor()),
headline2: TextStyle(color: opaque.current().mainTextColor()),
headline3: TextStyle(color: opaque.current().mainTextColor()),
headline4: TextStyle(color: opaque.current().mainTextColor()),
headline5: TextStyle(color: opaque.current().mainTextColor()),
headline6: TextStyle(color: opaque.current().mainTextColor()),
bodyText1: TextStyle(color: opaque.current().mainTextColor()),
bodyText2: TextStyle(color: opaque.current().mainTextColor()),
subtitle1: TextStyle(color: opaque.current().mainTextColor()),
subtitle2: TextStyle(color: opaque.current().mainTextColor()),
caption: TextStyle(color: opaque.current().mainTextColor()),
button: TextStyle(color: opaque.current().mainTextColor()),
overline: TextStyle(color: opaque.current().mainTextColor())),
switchTheme: SwitchThemeData(
overlayColor: MaterialStateProperty.all(opaque.current().defaultButtonActiveColor()),
thumbColor: MaterialStateProperty.all(opaque.current().mainTextColor()),
trackColor: MaterialStateProperty.all(opaque.current().dropShadowColor()),
),
floatingActionButtonTheme: FloatingActionButtonThemeData(backgroundColor: opaque.current().defaultButtonColor(), hoverColor: opaque.current().defaultButtonActiveColor()),
textSelectionTheme: TextSelectionThemeData(
cursorColor: opaque.current().defaultButtonActiveColor(), selectionColor: opaque.current().defaultButtonActiveColor(), selectionHandleColor: opaque.current().defaultButtonActiveColor()),
);
}

View File

@ -33,13 +33,13 @@ class Settings extends ChangeNotifier {
/// Set the dark theme.
void setDark() {
theme = OpaqueDark();
theme = Opaque.dark;
notifyListeners();
}
/// Set the Light theme.
void setLight() {
theme = OpaqueLight();
theme = Opaque.light;
notifyListeners();
}
@ -202,7 +202,10 @@ class Settings extends ChangeNotifier {
/// Convert this Settings object to a JSON representation for serialization on the
/// event bus.
dynamic asJson() {
var themeString = theme.identifier();
var themeString = "light";
if (theme == Opaque.dark) {
themeString = "dark";
}
return {
"Locale": this.locale.languageCode,

View File

@ -155,7 +155,7 @@ class _AddEditProfileViewState extends State<AddEditProfileView> {
visible: usePassword,
child: Column(mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[
Visibility(
visible: Provider.of<ProfileInfoState>(context, listen: false).onion.isNotEmpty && Provider.of<ProfileInfoState>(context).isEncrypted,
visible: Provider.of<ProfileInfoState>(context, listen: false).onion.isNotEmpty,
child: Column(mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [
CwtchLabel(label: AppLocalizations.of(context)!.currentPasswordLabel),
SizedBox(
@ -165,7 +165,7 @@ class _AddEditProfileViewState extends State<AddEditProfileView> {
controller: ctrlrOldPass,
validator: (value) {
// Password field can be empty when just updating the profile, not on creation
if (Provider.of<ProfileInfoState>(context).isEncrypted && Provider.of<ProfileInfoState>(context, listen: false).onion.isEmpty && value.isEmpty && usePassword) {
if (Provider.of<ProfileInfoState>(context, listen: false).onion.isEmpty && value.isEmpty && usePassword) {
return AppLocalizations.of(context)!.passwordErrorEmpty;
}
if (Provider.of<ErrorHandler>(context).deleteProfileError == true) {

View File

@ -64,7 +64,7 @@ class _GlobalSettingsViewState extends State<GlobalSettingsView> {
}).toList())),
SwitchListTile(
title: Text(AppLocalizations.of(context)!.settingTheme, style: TextStyle(color: settings.current().mainTextColor())),
value: settings.current().identifier() == "light",
value: settings.current() == Opaque.light,
onChanged: (bool value) {
if (value) {
settings.setLight();
@ -169,7 +169,13 @@ class _GlobalSettingsViewState extends State<GlobalSettingsView> {
)),
AboutListTile(
icon: Icon(Icons.info, color: settings.current().mainTextColor()),
applicationIcon: Padding(padding:EdgeInsets.all(5), child: Icon(CwtchIcons.cwtch_knott)),
applicationIcon: Padding(
padding: EdgeInsets.all(20),
child: Image(
image: AssetImage("assets/knott.png"),
width: 128,
height: 128,
)),
applicationName: "Cwtch (Flutter UI)",
applicationVersion: AppLocalizations.of(context)!.versionBuilddate.replaceAll("%1", EnvironmentConfig.BUILD_VER).replaceAll("%2", EnvironmentConfig.BUILD_DATE),
applicationLegalese: '\u{a9} 2021 Open Privacy Research Society',

View File

@ -2,7 +2,6 @@ import 'dart:convert';
import 'dart:io';
import 'package:cwtch/cwtch_icons_icons.dart';
import 'package:cwtch/widgets/profileimage.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:cwtch/views/peersettingsview.dart';
@ -50,17 +49,7 @@ class _MessageViewState extends State<MessageView> {
appBar: AppBar(
// setting leading to null makes it do the default behaviour; container() hides it
leading: Provider.of<Settings>(context).uiColumns(appState.isLandscape(context)).length > 1 ? Container() : null,
title: Row(children: [
ProfileImage(
imagePath: Provider.of<ContactInfoState>(context).imagePath,
diameter: 42,
border: Provider.of<Settings>(context).current().portraitOnlineBorderColor(),
badgeTextColor: Colors.red,
badgeColor: Colors.red,
),
SizedBox(
width: 10,
),Text(Provider.of<ContactInfoState>(context).nickname)]),
title: Text(Provider.of<ContactInfoState>(context).nickname),
actions: [
//IconButton(icon: Icon(Icons.chat), onPressed: _pushContactSettings),
//IconButton(icon: Icon(Icons.list), onPressed: _pushContactSettings),

View File

@ -77,6 +77,7 @@ class _PeerSettingsViewState extends State<PeerSettingsView> {
};
final setPeerAttributeJson = jsonEncode(setPeerAttribute);
Provider.of<FlwtchState>(context, listen: false).cwtch.SendProfileEvent(profileOnion, setPeerAttributeJson);
// todo translations
final snackBar = SnackBar(content: Text(AppLocalizations.of(context)!.nickChangeSuccess));
ScaffoldMessenger.of(context).showSnackBar(snackBar);
},

View File

@ -13,7 +13,7 @@ class SplashView extends StatelessWidget {
body: Center(
child: Column(mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [
Image(
image: AssetImage("assets/core/knott-white.png"),
image: AssetImage("assets/knott.png"),
filterQuality: FilterQuality.medium,
isAntiAlias: true,
width: 200,

View File

@ -20,8 +20,6 @@ class _ContactRowState extends State<ContactRow> {
var contact = Provider.of<ContactInfoState>(context);
return Card(
clipBehavior: Clip.antiAlias,
color: Provider.of<AppState>(context).selectedConversation == contact.onion ? Provider.of<Settings>(context).theme.backgroundHilightElementColor() : null,
borderOnForeground: false,
child: InkWell(
child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
Padding(
@ -33,7 +31,7 @@ class _ContactRowState extends State<ContactRow> {
diameter: 64.0,
imagePath: contact.imagePath,
maskOut: !contact.isOnline(),
border: contact.isOnline() ? Provider.of<Settings>(context).theme.portraitOnlineBorderColor() : contact.isBlocked ? Provider.of<Settings>(context).theme.portraitBlockedBorderColor() : Provider.of<Settings>(context).theme.portraitOfflineBorderColor()),
border: contact.isOnline() ? Provider.of<Settings>(context).theme.portraitOnlineBorderColor() : Provider.of<Settings>(context).theme.portraitOfflineBorderColor()),
),
Expanded(
child: Padding(
@ -43,14 +41,11 @@ class _ContactRowState extends State<ContactRow> {
children: [
Text(
contact.nickname, //(contact.isInvitation ? "invite " : "non-invite ") + (contact.isBlocked ? "blokt" : "nonblokt"),//
style: TextStyle(fontSize: Provider.of<Settings>(context).theme.contactOnionTextSize(),
color: contact.isBlocked ? Provider.of<Settings>(context).theme.portraitBlockedTextColor() : Provider.of<Settings>(context).theme.mainTextColor()), //Provider.of<FlwtchState>(context).biggerFont,
style: Provider.of<FlwtchState>(context).biggerFont,
softWrap: true,
overflow: TextOverflow.visible,
),
Text(contact.onion,
style: TextStyle(color: contact.isBlocked ? Provider.of<Settings>(context).theme.portraitBlockedTextColor() : Provider.of<Settings>(context).theme.mainTextColor())),
Text(contact.onion),
],
))),
Padding(

View File

@ -14,6 +14,7 @@ import 'messagebubbledecorations.dart';
// Like MessageBubble but for displaying chat overlay 100/101 invitations
// Offers the user an accept/reject button if they don't have a matching contact already
// todo: Reject buttons currently aren't tracked and will reset when the message is reloaded
class InvitationBubble extends StatefulWidget {
@override
InvitationBubbleState createState() => InvitationBubbleState();
@ -34,7 +35,6 @@ class InvitationBubbleState extends State<InvitationBubble> {
isAccepted = Provider.of<ProfileInfoState>(context).contactList.getContact(Provider.of<MessageState>(context).inviteTarget) != null;
var prettyDate = "";
var borderRadiousEh = 15.0;
var showGroupInvite = Provider.of<Settings>(context).isExperimentEnabled(TapirGroupsExperiment);
rejected = Provider.of<MessageState>(context).flags & 0x01 == 0x01;
var myKey = Provider.of<MessageState>(context).profileOnion + "::" + Provider.of<MessageState>(context).contactHandle + "::" + Provider.of<MessageState>(context).messageIndex.toString();
@ -66,18 +66,14 @@ class InvitationBubbleState extends State<InvitationBubble> {
return MalformedBubble();
}
var wdgMessage = isGroup && !showGroupInvite ?
Text(AppLocalizations.of(context)!.groupInviteSettingsWarning) :
fromMe
var wdgMessage = fromMe
? senderInviteChrome(AppLocalizations.of(context)!.sendAnInvitation,
isGroup ? Provider.of<ProfileInfoState>(context).contactList.getContact(Provider.of<MessageState>(context).inviteTarget)!.nickname : Provider.of<MessageState>(context).message, myKey)
: (inviteChrome(isGroup ? AppLocalizations.of(context)!.inviteToGroup : AppLocalizations.of(context)!.contactSuggestion, Provider.of<MessageState>(context).inviteNick,
Provider.of<MessageState>(context).inviteTarget, myKey));
Widget wdgDecorations;
if (isGroup && !showGroupInvite) {
wdgDecorations = Text('\u202F');
} else if (fromMe) {
if (fromMe) {
wdgDecorations = MessageBubbleDecoration(ackd: Provider.of<MessageState>(context).ackd, errored: Provider.of<MessageState>(context).error, fromMe: fromMe, prettyDate: prettyDate);
} else if (isAccepted) {
wdgDecorations = Text(AppLocalizations.of(context)!.accepted + '\u202F');
@ -113,7 +109,7 @@ class InvitationBubbleState extends State<InvitationBubble> {
child: Padding(
padding: EdgeInsets.all(9.0),
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(isGroup && !showGroupInvite ? CwtchIcons.enable_experiments : CwtchIcons.send_invite, size: 32))),
Center(widthFactor: 1, child: Padding(padding: EdgeInsets.all(10.0), child: Icon(CwtchIcons.send_invite, size: 32))),
Center(
widthFactor: 1.0,
child: Column(

View File

@ -19,8 +19,6 @@ class _MessageListState extends State<MessageList> {
bool showEphemeralWarning = (Provider.of<ContactInfoState>(context).isGroup == false && Provider.of<ContactInfoState>(context).savePeerHistory != "SaveHistory");
bool showOfflineWarning = Provider.of<ContactInfoState>(context).isOnline() == false;
bool showMessageWarning = showEphemeralWarning || showOfflineWarning;
bool showSyncing = Provider.of<ContactInfoState>(context).isGroup == true && Provider.of<ContactInfoState>(context).status != "Synced";
return RepaintBoundary(
child: Container(
child: Column(children: [
@ -29,10 +27,7 @@ class _MessageListState extends State<MessageList> {
child: Container(
padding: EdgeInsets.all(5.0),
color: Provider.of<Settings>(context).theme.defaultButtonActiveColor(),
child: showSyncing ?
Text(AppLocalizations.of(context)!.serverNotSynced,
textAlign: TextAlign.center)
: showOfflineWarning
child: showOfflineWarning
? Text(Provider.of<ContactInfoState>(context).isGroup ? AppLocalizations.of(context)!.serverConnectivityDisconnected : AppLocalizations.of(context)!.peerOfflineMessage,
textAlign: TextAlign.center)
// Only show the ephemeral status for peer conversations, not for groups...
@ -55,7 +50,6 @@ class _MessageListState extends State<MessageList> {
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: ListView.builder(
controller: ctrlr1,
itemCount: Provider.of<ContactInfoState>(outerContext).totalMessages,

View File

@ -2,7 +2,6 @@ import 'package:cwtch/cwtch_icons_icons.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../settings.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
// Provides a styled Password Input Field for use in Form Widgets.
// Callers must provide a text controller, label helper text and a validator.
@ -23,9 +22,9 @@ class _CwtchTextFieldState extends State<CwtchPasswordField> {
@override
Widget build(BuildContext context) {
// todo: translations
var label = AppLocalizations.of(context)!.tooltipShowPassword;
var label = "View Password";
if (!obscureText) {
label = AppLocalizations.of(context)!.tooltipHidePassword;
label = "Hide Password";
}
return Consumer<Settings>(builder: (context, theme, child) {

View File

@ -38,7 +38,7 @@ class _ProfileImageState extends State<ProfileImage> {
filterQuality: FilterQuality.medium,
// We need some theme specific blending here...we might want to consider making this a theme level attribute
colorBlendMode: !widget.maskOut
? Provider.of<Settings>(context).theme.identifier() == "dark"
? Provider.of<Settings>(context).theme == Opaque.dark
? BlendMode.softLight
: BlendMode.darken
: BlendMode.srcOut,

View File

@ -72,7 +72,7 @@ class _ProfileRowState extends State<ProfileRow> {
tooltip: AppLocalizations.of(context)!.editProfile + " " + profile.nickname,
icon: Icon(Icons.create, color: Provider.of<Settings>(context).current().mainTextColor()),
onPressed: () {
_pushAddEditProfile(onion: profile.onion, displayName: profile.nickname, profileImage: profile.imagePath, encrypted: profile.isEncrypted);
_pushAddEditProfile(onion: profile.onion, displayName: profile.nickname, profileImage: profile.imagePath);
},
)
],
@ -113,13 +113,13 @@ class _ProfileRowState extends State<ProfileRow> {
);
}
void _pushAddEditProfile({onion: "", displayName: "", profileImage: "", encrypted: true}) {
void _pushAddEditProfile({onion: "", displayName: "", profileImage: ""}) {
Navigator.of(context).push(MaterialPageRoute<void>(
builder: (BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider<ProfileInfoState>(
create: (_) => ProfileInfoState(onion: onion, nickname: displayName, imagePath: profileImage, encrypted: encrypted),
create: (_) => ProfileInfoState(onion: onion, nickname: displayName, imagePath: profileImage),
),
],
builder: (context, widget) => AddEditProfileView(),

View File

@ -6,6 +6,10 @@
#include "generated_plugin_registrant.h"
#include <window_size/window_size_plugin.h>
void fl_register_plugins(FlPluginRegistry* registry) {
g_autoptr(FlPluginRegistrar) window_size_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "WindowSizePlugin");
window_size_plugin_register_with_registrar(window_size_registrar);
}

View File

@ -3,6 +3,7 @@
#
list(APPEND FLUTTER_PLUGIN_LIST
window_size
)
set(PLUGIN_BUNDLED_LIBRARIES)

View File

@ -1,13 +1,13 @@
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
ansicolor:
archive:
dependency: transitive
description:
name: ansicolor
name: archive
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.1"
version: "3.1.2"
args:
dependency: transitive
description:
@ -42,7 +42,7 @@ packages:
name: charcode
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.1"
version: "1.2.0"
clock:
dependency: transitive
description:
@ -57,6 +57,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.15.0"
crypto:
dependency: transitive
description:
name: crypto
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.1"
cupertino_icons:
dependency: "direct main"
description:
@ -104,6 +111,11 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
flutter_driver:
dependency: "direct main"
description: flutter
source: sdk
version: "0.0.0"
flutter_localizations:
dependency: "direct main"
description: flutter
@ -119,6 +131,11 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
fuchsia_remote_debug_protocol:
dependency: transitive
description: flutter
source: sdk
version: "0.0.0"
glob:
dependency: "direct main"
description:
@ -140,13 +157,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "4.0.0"
injector:
dependency: transitive
integration_test:
dependency: "direct main"
description:
name: injector
name: integration_test
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
version: "1.0.2+3"
intl:
dependency: transitive
description:
@ -175,13 +192,6 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.4.0"
msix:
dependency: "direct dev"
description:
name: msix
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.3"
nested:
dependency: transitive
description:
@ -203,13 +213,6 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.1"
package_config:
dependency: transitive
description:
name: package_config
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
package_info_plus:
dependency: "direct main"
description:
@ -369,6 +372,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
sync_http:
dependency: transitive
description:
name: sync_http
url: "https://pub.dartlang.org"
source: hosted
version: "0.3.0"
term_glyph:
dependency: transitive
description:
@ -382,7 +392,7 @@ packages:
name: test_api
url: "https://pub.dartlang.org"
source: hosted
version: "0.4.1"
version: "0.4.0"
typed_data:
dependency: transitive
description:
@ -397,6 +407,20 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
vm_service:
dependency: transitive
description:
name: vm_service
url: "https://pub.dartlang.org"
source: hosted
version: "6.2.0"
webdriver:
dependency: transitive
description:
name: webdriver
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.0"
win32:
dependency: transitive
description:
@ -418,13 +442,6 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "5.1.2"
yaml:
dependency: transitive
description:
name: yaml
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.0"
sdks:
dart: ">=2.13.0 <3.0.0"
flutter: ">=1.20.0"

View File

@ -15,7 +15,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 1.0.0+15
version: 1.0.0+14
environment:
sdk: ">=2.12.0 <3.0.0"
@ -37,8 +37,13 @@ dependencies:
desktop_notifications: 0.5.0
glob: any
# todo: flutter_driver causes version conflict. eg https://github.com/flutter/flutter/issues/44829
# testing-related deps
integration_test: ^1.0.0
flutter_test:
sdk: flutter
flutter_driver:
sdk: flutter
dev_dependencies:
msix: ^2.1.3

View File

@ -14,8 +14,8 @@ import 'package:provider/provider.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
var settingsEnglishDark = Settings(Locale("en", ''), OpaqueDark());
var settingsEnglishLight = Settings(Locale("en", ''), OpaqueLight());
var settingsEnglishDark = Settings(Locale("en", ''), Opaque.dark);
var settingsEnglishLight = Settings(Locale("en", ''), Opaque.light);
ChangeNotifierProvider<Settings> getSettingsEnglishDark() => ChangeNotifierProvider.value(value: settingsEnglishDark);
void main() {

View File

@ -14,8 +14,8 @@ import 'package:provider/provider.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
var settingsEnglishDark = Settings(Locale("en", ''), OpaqueDark());
var settingsEnglishLight = Settings(Locale("en", ''), OpaqueLight());
var settingsEnglishDark = Settings(Locale("en", ''), Opaque.dark);
var settingsEnglishLight = Settings(Locale("en", ''), Opaque.light);
ChangeNotifierProvider<Settings> getSettingsEnglishDark() => ChangeNotifierProvider.value(value: settingsEnglishDark);
void main() {

View File

@ -14,8 +14,8 @@ import 'package:provider/provider.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
var settingsEnglishDark = Settings(Locale("en", ''), OpaqueDark());
var settingsEnglishLight = Settings(Locale("en", ''), OpaqueLight());
var settingsEnglishDark = Settings(Locale("en", ''), Opaque.dark);
var settingsEnglishLight = Settings(Locale("en", ''), Opaque.light);
ChangeNotifierProvider<Settings> getSettingsEnglishDark() => ChangeNotifierProvider.value(value: settingsEnglishDark);
String file(String slug) {

View File

@ -14,8 +14,8 @@ import 'package:provider/provider.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
var settingsEnglishDark = Settings(Locale("en", ''), OpaqueDark());
var settingsEnglishLight = Settings(Locale("en", ''), OpaqueLight());
var settingsEnglishDark = Settings(Locale("en", ''), Opaque.dark);
var settingsEnglishLight = Settings(Locale("en", ''), Opaque.light);
ChangeNotifierProvider<Settings> getSettingsEnglishDark() => ChangeNotifierProvider.value(value: settingsEnglishDark);
String file(String slug) {

View File

@ -6,6 +6,9 @@
#include "generated_plugin_registrant.h"
#include <window_size/window_size_plugin.h>
void RegisterPlugins(flutter::PluginRegistry* registry) {
WindowSizePluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("WindowSizePlugin"));
}

View File

@ -3,6 +3,7 @@
#
list(APPEND FLUTTER_PLUGIN_LIST
window_size
)
set(PLUGIN_BUNDLED_LIBRARIES)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

View File

@ -1,6 +0,0 @@
- cp nsis/cwtch-installer.nsi deploy/
- cd deploy
- makensis -V3 cwtch-installer.nsi
- export BUILDDATE=`date +%G-%m-%d-%H-%M`
- export FILENAME=cwtch-installer-$BUILDDATE.exe
- mv cwtch-installer.exe $FILENAME

View File

@ -1,92 +0,0 @@
; USAGE: Run in ui/deploy, requires the output be in 'windows' directory
!include "MUI2.nsh"
; General settings ----------------------------
Name "Cwtch"
; !define MUI_BRANDINGTEXT "SIG Beta Ver. 1.0"
Unicode True
# define the name of the installer
Outfile "cwtch-installer.exe"
# For removing Start Menu shortcut in Windows 7
#RequestExecutionLevel user
RequestExecutionLevel admin ;Require admin rights on NT6+ (When UAC is turned on)
# define the directory to install to, the desktop in this case as specified
# by the predefined $DESKTOP variable
InstallDir "$PROGRAMFILES\Cwtch"
;Get installation folder from registry if available
InstallDirRegKey HKCU "Software\Cwtch" "installLocation"
; MUI Interface -----------------------------
!define MUI_INSTALLCOLORS "DFB9DE 281831"
; 128x128, 32bit
!define MUI_ICON "../runner/resources/knot_128.ico"
!define MUI_HEADERIMAGE
!define MUI_HEADERIMAGE_BITMAP "cwtch_title.bmp"
!define MUI_TEXTCOLOR "350052"
!define MUI_WELCOMEFINISHPAGE_BITMAP "brand_side.bmp"
!define MUI_WELCOMEFINISHPAGE_BITMAP_STRETCH NoStretchNoCrop
!define MUI_INSTFILESPAGE_COLORS "DFB9DE 281831"
!define MUI_INSTFILESPAGE_PROGRESSBAR "colored"
!define MUI_FINISHPAGE_NOAUTOCLOSE
ShowInstDetails show
; Pages --------
!define MUI_WELCOMEPAGE_TITLE "Welcome to the Cwtch installer"
!define MUI_WELCOMEPAGE_TEXT "Cwtch (pronounced: kutch) is a Welsh word roughly meaning 'a hug that creates a safe space'$\n$\n\
Cwtch is a platform for building consentful, decentralized, untrusted infrastructure using metadata resistant group communication applications. Currently there is a selfnamed instant messaging prototype app that is driving development and testing. Many Further apps are planned as the platform matures."
!define MUI_FINISHPAGE_TITLE "Enjoy Cwtch"
!define MUI_FINISHPAGE_RUN $INSTDIR/ui.exe
!define MUI_FINISHPAGE_TEXT "You can keep up-to-date on Cwtch and report any issues you have at https://cwtch.im"
!define MUI_FINISHPAGE_LINK "https://cwtch.im"
!define MUI_FINISHPAGE_LINK_LOCATION "https://cwtch.im"
!define MUI_FINISHPAGE_LINK_COLOR "D01972"
!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_LICENSE "../../LICENSE"
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
; Languages --------------------------------
!insertmacro MUI_LANGUAGE "English"
# default section
Section
# define the output path for this file
SetOutPath $INSTDIR
# define what to install and place it in the output path
# Filler for .sh to populate with contents of deploy/windows
#FILESLISTSTART
FILE /r "..\..\build\windows\runner\Release\"
#FILESLISTEND
# create a shortcut in the start menu programs directory
CreateDirectory "$SMPROGRAMS\Cwtch"
CreateShortcut "$SMPROGRAMS\Cwtch\Cwtch.lnk" "$INSTDIR\cwtch.exe" "" "$INSTDIR\cwtch.ico"
;Store installation folder
WriteRegStr HKCU "Software\Cwtch" "installLocation" $INSTDIR
SectionEnd

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.5 KiB