From 43ce9b9df28a471d9233230c1d8b88a2ab9a6f55 Mon Sep 17 00:00:00 2001 From: Dan Ballard Date: Mon, 28 Jun 2021 15:24:15 -0700 Subject: [PATCH 01/11] initial import of ui nsis script for testing and adaptation --- windows/nsis/brand_side.bmp | Bin 0 -> 52574 bytes windows/nsis/create.sh | 6 ++ windows/nsis/cwtch-installer.nsi | 92 +++++++++++++++++++++++++++++++ windows/nsis/cwtch_title.bmp | Bin 0 -> 9742 bytes 4 files changed, 98 insertions(+) create mode 100644 windows/nsis/brand_side.bmp create mode 100644 windows/nsis/create.sh create mode 100644 windows/nsis/cwtch-installer.nsi create mode 100644 windows/nsis/cwtch_title.bmp diff --git a/windows/nsis/brand_side.bmp b/windows/nsis/brand_side.bmp new file mode 100644 index 0000000000000000000000000000000000000000..3d03803d6a41d90139914246d3e6bcf0ff706c9b GIT binary patch literal 52574 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 L3`7Qg8Uz0ec2!&j literal 0 HcmV?d00001 diff --git a/windows/nsis/create.sh b/windows/nsis/create.sh new file mode 100644 index 00000000..d5c95dd5 --- /dev/null +++ b/windows/nsis/create.sh @@ -0,0 +1,6 @@ +- 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 diff --git a/windows/nsis/cwtch-installer.nsi b/windows/nsis/cwtch-installer.nsi new file mode 100644 index 00000000..25a6584f --- /dev/null +++ b/windows/nsis/cwtch-installer.nsi @@ -0,0 +1,92 @@ +; 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 "..\windows\cwtch.ico" + +!define MUI_HEADERIMAGE +!define MUI_HEADERIMAGE_BITMAP "..\nsis\cwtch_title.bmp" + +!define MUI_TEXTCOLOR "350052" + +!define MUI_WELCOMEFINISHPAGE_BITMAP "..\nsis\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 "windows\" + #FILESLISTEND + + + # create a shortcut in the start menu programs directory + CreateDirectory "$SMPROGRAMS\Cwtch" + CreateShortcut "$SMPROGRAMS\Cwtch\Cwtch.lnk" "$INSTDIR\ui.exe" "" "$INSTDIR\cwtch.ico" + + ;Store installation folder + WriteRegStr HKCU "Software\Cwtch" "installLocation" $INSTDIR + +SectionEnd diff --git a/windows/nsis/cwtch_title.bmp b/windows/nsis/cwtch_title.bmp new file mode 100644 index 0000000000000000000000000000000000000000..8acc80af148011d3f4d1b9d0e041aae3f509c603 GIT binary patch literal 9742 zcmeH~F|I2o6o!cu$*JBNNE2lRkq557v}f+ET~C{kqwDRLzmmv{8~6qAp0 zU&N;^8pML)IossK@uZ{Vh+Ar`Ud}Y3o`+t6G%%apYHbR1Ij5A#!~L)AnJ4m<>ikRT({fCUF00z^oVjp1#w1qU7iL`aa0GsrX+%F9E52nn)o z&00za9s)#2kagS6QabPuAVPwyF7cMqfrkJQ5@dB(u#^rw1c;Czt1F|Wbl@RCgaldL zoGhgS4*?=1$PxmVEu{kw0U{*GCb0itER>ylD6a?!vI*9J1qU7iL`aY|Y|c_T@DLzE zf~+C+mePTT01*;o4L6H~;J`zG2nn*LLbQ|)JOqf4AZwZ=OX9C!#2p}exDmbH`)JOqf4AZyw=OXikRWTi221I{ zLx2bgvZivhlny)uh>##_nkP%?z(as&KL5R%Ul|v$XUr;Zv#zBEyvnW8{*aew`+&-x zx*iM4(_c@2J?4SOMnCiG>95B;@Yv{Qem(v5m>eCj+n`dJ>l#8)Hh!f#RR-ZFn|$$<7T^VcHdkLNZY>v!tXiF=^d^*rcO%PsSD`@?`H zYZ^zj-c*&Li)|ws_6J0m0zo$zVy3o=$+t*1$SC*EmAJXdAy2Sc4=>}>wCJSf0`|-OZvr2W!qz``KguHx@3Io9?Gkp5``|muKI`B`txu+ zv{4#D3GHMrb6xYpu36lcyU-)9WVPDX7+xm1;r%Qf3Za(SBhD73KM_MhsW7n{K z{o#^ZGly;V`boVm86Y>*Mg8YnnWPIyPHim>YaP0r>m^IHhKdpEvv9ntOH*hNc4#eG zsP48Js#@ANpx?#pcU!Fw!WLb)o-2Z zl6AIkot&oozU7;$M@5aW1bzRgX<3gNS+!cfSJ%1=t7dii%UI#C&3U?9H*ObHYfV=t ztoGckOONx;vaTmLI#-{&GhUNPb$;1j7^r?~3y5Nw)ESp-l6AK@mfrpkZVf?tfbtMp#$LYe;Ke%=2ely7jGC8em??v!p#=2E-5 w_K=qu?^`bhWX|BPZMFZt^3?TM44(da`s* Date: Mon, 28 Jun 2021 17:59:46 -0700 Subject: [PATCH 02/11] updating paths in nsis code and sketching install commands in drone - but need a new container --- .drone.yml | 9 ++++++++- windows/nsis/cwtch-installer.nsi | 12 ++++++------ 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/.drone.yml b/.drone.yml index d1f9aeac..58f599d0 100644 --- a/.drone.yml +++ b/.drone.yml @@ -237,13 +237,20 @@ steps: - echo $Env:pfx > codesign.pfx.b64 - certutil -decode codesign.pfx.b64 codesign.pfx - C:\MSIX-Toolkit\MSIX-Toolkit.x64\signtool sign /v /fd sha256 /a /f codesign.pfx /p $Env:pfx_pass /tr http://timestamp.digicert.com $Env:releasedir\cwtch.exe + + - copy window\runner\resources\knot_128.ico $Env:releasedir\cwtch.ico + - makensis windows\nsis\cwtch-installer.nsi + - C:\MSIX-Toolkit\MSIX-Toolkit.x64\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 + - mkdir deploy - mkdir deploy\$Env:builddir - 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 $Env:zipsha deploy\$Env:builddir + - move *.sha512 deploy\$Env:builddir - name: deploy-windows image: openpriv/flutter-desktop:windows-sdk30-fdev2.3rc diff --git a/windows/nsis/cwtch-installer.nsi b/windows/nsis/cwtch-installer.nsi index 25a6584f..ad8eebc1 100644 --- a/windows/nsis/cwtch-installer.nsi +++ b/windows/nsis/cwtch-installer.nsi @@ -27,14 +27,14 @@ InstallDirRegKey HKCU "Software\Cwtch" "installLocation" !define MUI_INSTALLCOLORS "DFB9DE 281831" ; 128x128, 32bit -!define MUI_ICON "..\windows\cwtch.ico" +!define MUI_ICON "windows/runner/resources/knot_128.ico" !define MUI_HEADERIMAGE -!define MUI_HEADERIMAGE_BITMAP "..\nsis\cwtch_title.bmp" +!define MUI_HEADERIMAGE_BITMAP "windows/nsis/cwtch_title.bmp" !define MUI_TEXTCOLOR "350052" -!define MUI_WELCOMEFINISHPAGE_BITMAP "..\nsis\brand_side.bmp" +!define MUI_WELCOMEFINISHPAGE_BITMAP "windows/nsis/brand_side.bmp" !define MUI_WELCOMEFINISHPAGE_BITMAP_STRETCH NoStretchNoCrop !define MUI_INSTFILESPAGE_COLORS "DFB9DE 281831" @@ -60,7 +60,7 @@ ShowInstDetails show !define MUI_FINISHPAGE_LINK_COLOR "D01972" !insertmacro MUI_PAGE_WELCOME -!insertmacro MUI_PAGE_LICENSE "../LICENSE" +!insertmacro MUI_PAGE_LICENSE "LICENSE" !insertmacro MUI_PAGE_DIRECTORY !insertmacro MUI_PAGE_INSTFILES !insertmacro MUI_PAGE_FINISH @@ -78,13 +78,13 @@ Section # define what to install and place it in the output path # Filler for .sh to populate with contents of deploy/windows #FILESLISTSTART - FILE /r "windows\" + 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\ui.exe" "" "$INSTDIR\cwtch.ico" + CreateShortcut "$SMPROGRAMS\Cwtch\Cwtch.lnk" "$INSTDIR\cwtch.exe" "" "$INSTDIR\cwtch.ico" ;Store installation folder WriteRegStr HKCU "Software\Cwtch" "installLocation" $INSTDIR From 45459cf76a5efd9c8298ebf7027058bbccf022aa Mon Sep 17 00:00:00 2001 From: Sarah Jamie Lewis Date: Tue, 29 Jun 2021 16:41:38 -0700 Subject: [PATCH 03/11] Show Syncing Message + Update libcwtch-go to fix message fetching issues --- LIBCWTCH-GO.version | 2 +- lib/cwtch/cwtchNotifier.dart | 1 + lib/widgets/messagelist.dart | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/LIBCWTCH-GO.version b/LIBCWTCH-GO.version index 271b7350..59f1a531 100644 --- a/LIBCWTCH-GO.version +++ b/LIBCWTCH-GO.version @@ -1 +1 @@ -v1.0.0-7-g520d35a-2021-06-25-16-34 \ No newline at end of file +v1.0.0-12-g2e0b6ef-2021-06-29-23-42 \ No newline at end of file diff --git a/lib/cwtch/cwtchNotifier.dart b/lib/cwtch/cwtchNotifier.dart index d5597674..7551526a 100644 --- a/lib/cwtch/cwtchNotifier.dart +++ b/lib/cwtch/cwtchNotifier.dart @@ -245,6 +245,7 @@ class CwtchNotifier { break; case "ServerStateChange": // Update the Server Cache + EnvironmentConfig.debugLog("server state changes $data"); profileCN.getProfile(data["ProfileOnion"])?.updateServerStatusCache(data["GroupServer"], data["ConnectionState"]); profileCN.getProfile(data["ProfileOnion"])?.contactList.contacts.forEach((contact) { if (contact.isGroup == true && contact.server == data["GroupServer"]) { diff --git a/lib/widgets/messagelist.dart b/lib/widgets/messagelist.dart index 67158294..b17b7bbf 100644 --- a/lib/widgets/messagelist.dart +++ b/lib/widgets/messagelist.dart @@ -24,8 +24,8 @@ class _MessageListState extends State { bool showEphemeralWarning = (isP2P && Provider.of(context).savePeerHistory != "SaveHistory"); bool showOfflineWarning = Provider.of(context).isOnline() == false; - bool showMessageWarning = showEphemeralWarning || showOfflineWarning; bool showSyncing = isGroupAndSyncing; + bool showMessageWarning = showEphemeralWarning || showOfflineWarning || showSyncing; // Only load historical messages when the conversation is with a p2p contact OR the conversation is a server and *not* syncing. bool loadMessages = isP2P || (isGroupAndSynced || isGroupAndNotAuthenticated); From 9c9ea3845683357450ce47fea53f3cbbbf07db6a Mon Sep 17 00:00:00 2001 From: Sarah Jamie Lewis Date: Tue, 29 Jun 2021 17:17:42 -0700 Subject: [PATCH 04/11] Propagate group name on Android properly --- android/app/src/main/kotlin/im/cwtch/flwtch/FlwtchWorker.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/app/src/main/kotlin/im/cwtch/flwtch/FlwtchWorker.kt b/android/app/src/main/kotlin/im/cwtch/flwtch/FlwtchWorker.kt index 7cb33d71..35ebf16c 100644 --- a/android/app/src/main/kotlin/im/cwtch/flwtch/FlwtchWorker.kt +++ b/android/app/src/main/kotlin/im/cwtch/flwtch/FlwtchWorker.kt @@ -178,7 +178,7 @@ class FlwtchWorker(context: Context, parameters: WorkerParameters) : "CreateGroup" -> { val profile = (a.get("ProfileOnion") as? String) ?: "" val server = (a.get("server") as? String) ?: "" - val groupName = (a.get("groupname") as? String) ?: "" + val groupName = (a.get("groupName") as? String) ?: "" Cwtch.createGroup(profile, server, groupName) } "DeleteProfile" -> { From b832f71569e506c97d7e9b878e39a1fe1c1898cf Mon Sep 17 00:00:00 2001 From: Sarah Jamie Lewis Date: Wed, 30 Jun 2021 11:35:07 -0700 Subject: [PATCH 05/11] Fix: #22 - Explictly pop to conversations after AddContact Also a few checks to prevent post-acceptence onChange events from breaking context. --- lib/views/addcontactview.dart | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/views/addcontactview.dart b/lib/views/addcontactview.dart index 5947d3fb..a8a1a422 100644 --- a/lib/views/addcontactview.dart +++ b/lib/views/addcontactview.dart @@ -152,9 +152,14 @@ class _AddContactViewState extends State { Future.delayed(const Duration(milliseconds: 500), () { if (globalErrorHandler.importBundleSuccess) { - final snackBar = SnackBar(content: Text(AppLocalizations.of(context)!.successfullAddedContact + importBundle)); - ScaffoldMessenger.of(context).showSnackBar(snackBar); - Navigator.pop(context); + // TODO: This isn't ideal, but because onChange can be fired during this future check + // and because the context can change after being popped we have this kind of double assertion... + // There is probably a better pattern to handle this... + if (AppLocalizations.of(context) != null) { + final snackBar = SnackBar(content: Text(AppLocalizations.of(context)!.successfullAddedContact + importBundle)); + ScaffoldMessenger.of(context).showSnackBar(snackBar); + Navigator.popUntil(context, (route) => route.settings.name == "conversations"); + } } }); }, From bd29ad8d4c8b7d05a1ec21ab31b0e7188833e543 Mon Sep 17 00:00:00 2001 From: Dan Ballard Date: Wed, 30 Jun 2021 11:57:56 -0700 Subject: [PATCH 06/11] integrating changes from tests in flutter_app --- .drone.yml | 50 ++++++++++++++++++-------------- windows/nsis/create.sh | 6 ---- windows/nsis/cwtch-installer.nsi | 10 +++---- 3 files changed, 33 insertions(+), 33 deletions(-) delete mode 100644 windows/nsis/create.sh diff --git a/.drone.yml b/.drone.yml index 58f599d0..38c902ce 100644 --- a/.drone.yml +++ b/.drone.yml @@ -11,7 +11,7 @@ steps: image: cirrusci/flutter:dev environment: buildbot_key_b64: - from_secret: buildbot_key_b64 + from_secret: buildbot_key_b64 commands: - mkdir ~/.ssh - echo $buildbot_key_b64 > ~/.ssh/id_rsa.b64 @@ -68,8 +68,8 @@ steps: - name: test-build-android image: cirrusci/flutter:dev - when: - event: pull_request + when: + event: pull_request volumes: - name: deps path: /root/.pub-cache @@ -106,7 +106,7 @@ steps: - name: deps path: /root/.pub-cache commands: - # - flutter config --enable-linux-desktop + # - flutter config --enable-linux-desktop - flutter test --coverage - genhtml coverage/lcov.info -o coverage/html @@ -209,21 +209,10 @@ steps: - name: build-windows image: openpriv/flutter-desktop:windows-sdk30-fdev2.3rc - environment: - pfx: - from_secret: pfx - pfx_pass: - from_secret: pfx_pass commands: - 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\\" - flutter build windows --dart-define BUILD_VER=$Env:version --dart-define BUILD_DATE=$Env:builddate - copy windows\libCwtch.dll $Env:releasedir @@ -234,15 +223,32 @@ 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 - echo $Env:pfx > codesign.pfx.b64 - certutil -decode codesign.pfx.b64 codesign.pfx - - C:\MSIX-Toolkit\MSIX-Toolkit.x64\signtool sign /v /fd sha256 /a /f codesign.pfx /p $Env:pfx_pass /tr http://timestamp.digicert.com $Env:releasedir\cwtch.exe - - - copy window\runner\resources\knot_128.ico $Env:releasedir\cwtch.ico + - 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 - - C:\MSIX-Toolkit\MSIX-Toolkit.x64\signtool sign /v /fd sha256 /a /f codesign.pfx /p $Env:pfx_pass /tr http://timestamp.digicert.com cwtch-installer.exe + - 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 - - mkdir deploy - mkdir deploy\$Env:builddir - move $Env:releasedir $Env:builddir @@ -255,8 +261,8 @@ steps: - 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 diff --git a/windows/nsis/create.sh b/windows/nsis/create.sh deleted file mode 100644 index d5c95dd5..00000000 --- a/windows/nsis/create.sh +++ /dev/null @@ -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 diff --git a/windows/nsis/cwtch-installer.nsi b/windows/nsis/cwtch-installer.nsi index ad8eebc1..684a0e3a 100644 --- a/windows/nsis/cwtch-installer.nsi +++ b/windows/nsis/cwtch-installer.nsi @@ -27,14 +27,14 @@ InstallDirRegKey HKCU "Software\Cwtch" "installLocation" !define MUI_INSTALLCOLORS "DFB9DE 281831" ; 128x128, 32bit -!define MUI_ICON "windows/runner/resources/knot_128.ico" +!define MUI_ICON "../runner/resources/knot_128.ico" !define MUI_HEADERIMAGE -!define MUI_HEADERIMAGE_BITMAP "windows/nsis/cwtch_title.bmp" +!define MUI_HEADERIMAGE_BITMAP "cwtch_title.bmp" !define MUI_TEXTCOLOR "350052" -!define MUI_WELCOMEFINISHPAGE_BITMAP "windows/nsis/brand_side.bmp" +!define MUI_WELCOMEFINISHPAGE_BITMAP "brand_side.bmp" !define MUI_WELCOMEFINISHPAGE_BITMAP_STRETCH NoStretchNoCrop !define MUI_INSTFILESPAGE_COLORS "DFB9DE 281831" @@ -60,7 +60,7 @@ ShowInstDetails show !define MUI_FINISHPAGE_LINK_COLOR "D01972" !insertmacro MUI_PAGE_WELCOME -!insertmacro MUI_PAGE_LICENSE "LICENSE" +!insertmacro MUI_PAGE_LICENSE "../../LICENSE" !insertmacro MUI_PAGE_DIRECTORY !insertmacro MUI_PAGE_INSTFILES !insertmacro MUI_PAGE_FINISH @@ -78,7 +78,7 @@ Section # 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/" + FILE /r "..\..\build\windows\runner\Release\" #FILESLISTEND From 445a88ed882d6250a75b17adca2b71f092be3397 Mon Sep 17 00:00:00 2001 From: Dan Ballard Date: Wed, 30 Jun 2021 12:39:51 -0700 Subject: [PATCH 07/11] fix 'Run app` after incaller closes not working --- windows/nsis/cwtch-installer.nsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/windows/nsis/cwtch-installer.nsi b/windows/nsis/cwtch-installer.nsi index 684a0e3a..75a59515 100644 --- a/windows/nsis/cwtch-installer.nsi +++ b/windows/nsis/cwtch-installer.nsi @@ -53,7 +53,7 @@ ShowInstDetails show 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_RUN $INSTDIR/cwtch.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" From a792926b5ce465086f0bbefc677389a6dd7fcf28 Mon Sep 17 00:00:00 2001 From: Sarah Jamie Lewis Date: Wed, 30 Jun 2021 13:59:41 -0700 Subject: [PATCH 08/11] Update LibCwtch-go --- LIBCWTCH-GO.version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LIBCWTCH-GO.version b/LIBCWTCH-GO.version index 59f1a531..a3ef35ec 100644 --- a/LIBCWTCH-GO.version +++ b/LIBCWTCH-GO.version @@ -1 +1 @@ -v1.0.0-12-g2e0b6ef-2021-06-29-23-42 \ No newline at end of file +v1.0.0-20-gf8eedca-2021-06-30-20-48 \ No newline at end of file From 8df3eecd7c309c44b2ec61dbc8372ef3c546e5f5 Mon Sep 17 00:00:00 2001 From: Sarah Jamie Lewis Date: Wed, 30 Jun 2021 13:59:52 -0700 Subject: [PATCH 09/11] Formatting Pass --- lib/licenses.dart | 1 - lib/main.dart | 3 +- lib/notification_manager.dart | 7 +-- lib/opaque.dart | 3 +- lib/settings.dart | 50 +++++++++++++------- lib/views/addeditprofileview.dart | 5 +- lib/views/doublecolview.dart | 2 +- lib/views/globalsettingsview.dart | 2 +- lib/views/messageview.dart | 24 +++++----- lib/views/profilemgrview.dart | 70 +++++++++++++-------------- lib/widgets/contactrow.dart | 20 ++++++-- lib/widgets/invitationbubble.dart | 19 ++++---- lib/widgets/messagelist.dart | 78 +++++++++++++++---------------- lib/widgets/profilerow.dart | 78 ++++++++++++------------------- 14 files changed, 186 insertions(+), 176 deletions(-) diff --git a/lib/licenses.dart b/lib/licenses.dart index 36a9f577..a665eed0 100644 --- a/lib/licenses.dart +++ b/lib/licenses.dart @@ -115,6 +115,5 @@ 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)"); } diff --git a/lib/main.dart b/lib/main.dart index f74ddbdc..b59fe208 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -190,7 +190,8 @@ class FlwtchState extends State { }, ), ); - } else { //dual pane + } else { + //dual pane Provider.of(navKey.currentContext!, listen: false).selectedProfile = args["ProfileOnion"]; Provider.of(navKey.currentContext!, listen: false).selectedConversation = args["Handle"]; } diff --git a/lib/notification_manager.dart b/lib/notification_manager.dart index ea4e9a78..fa5de8c3 100644 --- a/lib/notification_manager.dart +++ b/lib/notification_manager.dart @@ -22,10 +22,7 @@ class LinuxNotificationsManager implements NotificationsManager { } Future notify(String message) async { var iconPath = Uri.file(path.join(path.current, "cwtch.png")); - client.notify(message, appName: "cwtch", - appIcon: iconPath.toString(), - replacesId: this.previous_id).then((Notification value) => - previous_id = value.id); + client.notify(message, appName: "cwtch", appIcon: iconPath.toString(), replacesId: this.previous_id).then((Notification value) => previous_id = value.id); } } @@ -40,4 +37,4 @@ NotificationsManager newDesktopNotificationsManager() { print("Attempted to access DBUS for notifications but failed. Switching off notifications."); } return NullNotificationsManager(); -} \ No newline at end of file +} diff --git a/lib/opaque.dart b/lib/opaque.dart index b6ba50bf..fa09fc41 100644 --- a/lib/opaque.dart +++ b/lib/opaque.dart @@ -314,7 +314,6 @@ abstract class OpaqueThemeType { double contactOnionTextSize() { return 18; } - } class OpaqueDark extends OpaqueThemeType { @@ -1440,4 +1439,4 @@ class Opaque extends OpaqueThemeType { } } -*/ \ No newline at end of file +*/ diff --git a/lib/settings.dart b/lib/settings.dart index d63333dc..843076ba 100644 --- a/lib/settings.dart +++ b/lib/settings.dart @@ -161,26 +161,40 @@ class Settings extends ChangeNotifier { List uiColumns(bool isLandscape) { var m = (!isLandscape || uiColumnModeLandscape == DualpaneMode.CopyPortrait) ? uiColumnModePortrait : uiColumnModeLandscape; - switch(m) { - case DualpaneMode.Single: return [1]; - case DualpaneMode.Dual1to2: return [1, 2]; - case DualpaneMode.Dual1to4: return [1, 4]; + switch (m) { + case DualpaneMode.Single: + return [1]; + case DualpaneMode.Dual1to2: + return [1, 2]; + case DualpaneMode.Dual1to4: + return [1, 4]; } print("impossible column configuration: portrait/$uiColumnModePortrait landscape/$uiColumnModeLandscape"); return [1]; } static List uiColumnModeOptions(bool isLandscape) { - if (isLandscape) return [DualpaneMode.CopyPortrait, DualpaneMode.Single, DualpaneMode.Dual1to2, DualpaneMode.Dual1to4,]; - else return [DualpaneMode.Single, DualpaneMode.Dual1to2, DualpaneMode.Dual1to4]; + if (isLandscape) + return [ + DualpaneMode.CopyPortrait, + DualpaneMode.Single, + DualpaneMode.Dual1to2, + DualpaneMode.Dual1to4, + ]; + else + return [DualpaneMode.Single, DualpaneMode.Dual1to2, DualpaneMode.Dual1to4]; } static DualpaneMode uiColumnModeFromString(String m) { - switch(m) { - case "DualpaneMode.Single": return DualpaneMode.Single; - case "DualpaneMode.Dual1to2": return DualpaneMode.Dual1to2; - case "DualpaneMode.Dual1to4": return DualpaneMode.Dual1to4; - case "DualpaneMode.CopyPortrait": return DualpaneMode.CopyPortrait; + switch (m) { + case "DualpaneMode.Single": + return DualpaneMode.Single; + case "DualpaneMode.Dual1to2": + return DualpaneMode.Dual1to2; + case "DualpaneMode.Dual1to4": + return DualpaneMode.Dual1to4; + case "DualpaneMode.CopyPortrait": + return DualpaneMode.CopyPortrait; } print("Error: ui requested translation of column mode [$m] which doesn't exist"); return DualpaneMode.Single; @@ -188,11 +202,15 @@ class Settings extends ChangeNotifier { static String uiColumnModeToString(DualpaneMode m) { // todo: translate - switch(m) { - case DualpaneMode.Single: return "Single"; - case DualpaneMode.Dual1to2: return "Double (1:2)"; - case DualpaneMode.Dual1to4: return "Double (1:4)"; - case DualpaneMode.CopyPortrait: return "Same as portrait mode setting"; + switch (m) { + case DualpaneMode.Single: + return "Single"; + case DualpaneMode.Dual1to2: + return "Double (1:2)"; + case DualpaneMode.Dual1to4: + return "Double (1:4)"; + case DualpaneMode.CopyPortrait: + return "Same as portrait mode setting"; } } diff --git a/lib/views/addeditprofileview.dart b/lib/views/addeditprofileview.dart index 93a10ccb..26d2dcd7 100644 --- a/lib/views/addeditprofileview.dart +++ b/lib/views/addeditprofileview.dart @@ -166,7 +166,10 @@ class _AddEditProfileViewState extends State { autoFillHints: [AutofillHints.newPassword], validator: (value) { // Password field can be empty when just updating the profile, not on creation - if (Provider.of(context).isEncrypted && Provider.of(context, listen: false).onion.isEmpty && value.isEmpty && usePassword) { + if (Provider.of(context).isEncrypted && + Provider.of(context, listen: false).onion.isEmpty && + value.isEmpty && + usePassword) { return AppLocalizations.of(context)!.passwordErrorEmpty; } if (Provider.of(context).deleteProfileError == true) { diff --git a/lib/views/doublecolview.dart b/lib/views/doublecolview.dart index 2737755e..e7d3a260 100644 --- a/lib/views/doublecolview.dart +++ b/lib/views/doublecolview.dart @@ -29,7 +29,7 @@ class _DoubleColumnViewState extends State { Flexible( flex: cols[1], child: flwtch.selectedConversation == null - ? Card(child:Center(child: Text(AppLocalizations.of(context)!.addContactFirst))) + ? Card(child: Center(child: Text(AppLocalizations.of(context)!.addContactFirst))) : //dev MultiProvider(providers: [ ChangeNotifierProvider.value(value: Provider.of(context)), diff --git a/lib/views/globalsettingsview.dart b/lib/views/globalsettingsview.dart index 2329ea83..310db952 100644 --- a/lib/views/globalsettingsview.dart +++ b/lib/views/globalsettingsview.dart @@ -169,7 +169,7 @@ class _GlobalSettingsViewState extends State { )), 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(5), child: Icon(CwtchIcons.cwtch_knott)), 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', diff --git a/lib/views/messageview.dart b/lib/views/messageview.dart index da13f2c1..bdba1c9f 100644 --- a/lib/views/messageview.dart +++ b/lib/views/messageview.dart @@ -50,17 +50,19 @@ class _MessageViewState extends State { appBar: AppBar( // setting leading to null makes it do the default behaviour; container() hides it leading: Provider.of(context).uiColumns(appState.isLandscape(context)).length > 1 ? Container() : null, - title: Row(children: [ - ProfileImage( - imagePath: Provider.of(context).imagePath, - diameter: 42, - border: Provider.of(context).current().portraitOnlineBorderColor(), - badgeTextColor: Colors.red, - badgeColor: Colors.red, - ), - SizedBox( - width: 10, - ),Text(Provider.of(context).nickname)]), + title: Row(children: [ + ProfileImage( + imagePath: Provider.of(context).imagePath, + diameter: 42, + border: Provider.of(context).current().portraitOnlineBorderColor(), + badgeTextColor: Colors.red, + badgeColor: Colors.red, + ), + SizedBox( + width: 10, + ), + Text(Provider.of(context).nickname) + ]), actions: [ //IconButton(icon: Icon(Icons.chat), onPressed: _pushContactSettings), //IconButton(icon: Icon(Icons.list), onPressed: _pushContactSettings), diff --git a/lib/views/profilemgrview.dart b/lib/views/profilemgrview.dart index 2e65a2f8..80a037f4 100644 --- a/lib/views/profilemgrview.dart +++ b/lib/views/profilemgrview.dart @@ -40,45 +40,41 @@ class _ProfileMgrViewState extends State { // Prevents Android back button from closing the app on the profile manager screen // (which would shutdown connections and all kinds of other expensive to generate things) // TODO pop up a dialogue regarding closing the app? - builder: (context, settings, child) => - WillPopScope( - onWillPop: () async { - _modalShutdown(); - return Provider.of(context, listen: false).cwtchIsClosing; - }, - child: Scaffold( - backgroundColor: settings.theme.backgroundMainColor(), - appBar: AppBar( - title: Row(children: [ - Image( - image: AssetImage("assets/core/knott-white.png"), - filterQuality: FilterQuality.medium, - isAntiAlias: true, - width: 32, - height: 32, - colorBlendMode: BlendMode.dstIn, - color: Provider - .of(context) - .theme - .backgroundHilightElementColor(), - ), - SizedBox( - width: 10, - ), - Expanded(child: Text(AppLocalizations.of(context)!.titleManageProfiles, style: TextStyle(color: settings.current().mainTextColor()))) - ]), - actions: getActions(), + builder: (context, settings, child) => WillPopScope( + onWillPop: () async { + _modalShutdown(); + return Provider.of(context, listen: false).cwtchIsClosing; + }, + child: Scaffold( + backgroundColor: settings.theme.backgroundMainColor(), + appBar: AppBar( + title: Row(children: [ + Image( + image: AssetImage("assets/core/knott-white.png"), + filterQuality: FilterQuality.medium, + isAntiAlias: true, + width: 32, + height: 32, + colorBlendMode: BlendMode.dstIn, + color: Provider.of(context).theme.backgroundHilightElementColor(), ), - floatingActionButton: FloatingActionButton( - onPressed: _pushAddEditProfile, - tooltip: AppLocalizations.of(context)!.addNewProfileBtn, - child: Icon( - Icons.add, - semanticLabel: AppLocalizations.of(context)!.addNewProfileBtn, - ), + SizedBox( + width: 10, ), - body: _buildProfileManager(), - )), + Expanded(child: Text(AppLocalizations.of(context)!.titleManageProfiles, style: TextStyle(color: settings.current().mainTextColor()))) + ]), + actions: getActions(), + ), + floatingActionButton: FloatingActionButton( + onPressed: _pushAddEditProfile, + tooltip: AppLocalizations.of(context)!.addNewProfileBtn, + child: Icon( + Icons.add, + semanticLabel: AppLocalizations.of(context)!.addNewProfileBtn, + ), + ), + body: _buildProfileManager(), + )), ); } diff --git a/lib/widgets/contactrow.dart b/lib/widgets/contactrow.dart index 296ae406..d38d1df1 100644 --- a/lib/widgets/contactrow.dart +++ b/lib/widgets/contactrow.dart @@ -33,7 +33,11 @@ class _ContactRowState extends State { diameter: 64.0, imagePath: contact.imagePath, maskOut: !contact.isOnline(), - border: contact.isOnline() ? Provider.of(context).theme.portraitOnlineBorderColor() : contact.isBlocked ? Provider.of(context).theme.portraitBlockedBorderColor() : Provider.of(context).theme.portraitOfflineBorderColor()), + border: contact.isOnline() + ? Provider.of(context).theme.portraitOnlineBorderColor() + : contact.isBlocked + ? Provider.of(context).theme.portraitBlockedBorderColor() + : Provider.of(context).theme.portraitOfflineBorderColor()), ), Expanded( child: Padding( @@ -44,13 +48,16 @@ class _ContactRowState extends State { Text( contact.nickname, //(contact.isInvitation ? "invite " : "non-invite ") + (contact.isBlocked ? "blokt" : "nonblokt"),// - style: TextStyle(fontSize: Provider.of(context).theme.contactOnionTextSize(), - color: contact.isBlocked ? Provider.of(context).theme.portraitBlockedTextColor() : Provider.of(context).theme.mainTextColor()), //Provider.of(context).biggerFont, + style: TextStyle( + fontSize: Provider.of(context).theme.contactOnionTextSize(), + color: contact.isBlocked + ? Provider.of(context).theme.portraitBlockedTextColor() + : Provider.of(context).theme.mainTextColor()), //Provider.of(context).biggerFont, softWrap: true, overflow: TextOverflow.visible, ), Text(contact.onion, - style: TextStyle(color: contact.isBlocked ? Provider.of(context).theme.portraitBlockedTextColor() : Provider.of(context).theme.mainTextColor())), + style: TextStyle(color: contact.isBlocked ? Provider.of(context).theme.portraitBlockedTextColor() : Provider.of(context).theme.mainTextColor())), ], ))), Padding( @@ -60,7 +67,10 @@ class _ContactRowState extends State { IconButton( padding: EdgeInsets.zero, iconSize: 16, - icon: Icon(Icons.favorite, color: Provider.of(context).theme.mainTextColor(),), + icon: Icon( + Icons.favorite, + color: Provider.of(context).theme.mainTextColor(), + ), tooltip: AppLocalizations.of(context)!.tooltipAcceptContactRequest, onPressed: _btnApprove, ), diff --git a/lib/widgets/invitationbubble.dart b/lib/widgets/invitationbubble.dart index ff86ffca..47057f74 100644 --- a/lib/widgets/invitationbubble.dart +++ b/lib/widgets/invitationbubble.dart @@ -66,18 +66,18 @@ class InvitationBubbleState extends State { return MalformedBubble(); } - var wdgMessage = isGroup && !showGroupInvite ? - Text(AppLocalizations.of(context)!.groupInviteSettingsWarning) : - fromMe - ? senderInviteChrome(AppLocalizations.of(context)!.sendAnInvitation, - isGroup ? Provider.of(context).contactList.getContact(Provider.of(context).inviteTarget)!.nickname : Provider.of(context).message, myKey) - : (inviteChrome(isGroup ? AppLocalizations.of(context)!.inviteToGroup : AppLocalizations.of(context)!.contactSuggestion, Provider.of(context).inviteNick, - Provider.of(context).inviteTarget, myKey)); + var wdgMessage = isGroup && !showGroupInvite + ? Text(AppLocalizations.of(context)!.groupInviteSettingsWarning) + : fromMe + ? senderInviteChrome(AppLocalizations.of(context)!.sendAnInvitation, + isGroup ? Provider.of(context).contactList.getContact(Provider.of(context).inviteTarget)!.nickname : Provider.of(context).message, myKey) + : (inviteChrome(isGroup ? AppLocalizations.of(context)!.inviteToGroup : AppLocalizations.of(context)!.contactSuggestion, Provider.of(context).inviteNick, + Provider.of(context).inviteTarget, myKey)); Widget wdgDecorations; if (isGroup && !showGroupInvite) { wdgDecorations = Text('\u202F'); - } else if (fromMe) { + } else if (fromMe) { wdgDecorations = MessageBubbleDecoration(ackd: Provider.of(context).ackd, errored: Provider.of(context).error, fromMe: fromMe, prettyDate: prettyDate); } else if (isAccepted) { wdgDecorations = Text(AppLocalizations.of(context)!.accepted + '\u202F'); @@ -113,7 +113,8 @@ class InvitationBubbleState extends State { 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(isGroup && !showGroupInvite ? CwtchIcons.enable_experiments : CwtchIcons.send_invite, size: 32))), Center( widthFactor: 1.0, child: Column( diff --git a/lib/widgets/messagelist.dart b/lib/widgets/messagelist.dart index b17b7bbf..5e985b7d 100644 --- a/lib/widgets/messagelist.dart +++ b/lib/widgets/messagelist.dart @@ -16,11 +16,10 @@ class _MessageListState extends State { @override Widget build(BuildContext outerContext) { - - bool isP2P = !Provider.of(context).isGroup; + bool isP2P = !Provider.of(context).isGroup; bool isGroupAndSyncing = Provider.of(context).isGroup == true && Provider.of(context).status == "Authenticated"; bool isGroupAndSynced = Provider.of(context).isGroup && Provider.of(context).status == "Synced"; - bool isGroupAndNotAuthenticated= Provider.of(context).isGroup && Provider.of(context).status != "Authenticated"; + bool isGroupAndNotAuthenticated = Provider.of(context).isGroup && Provider.of(context).status != "Authenticated"; bool showEphemeralWarning = (isP2P && Provider.of(context).savePeerHistory != "SaveHistory"); bool showOfflineWarning = Provider.of(context).isOnline() == false; @@ -37,18 +36,17 @@ class _MessageListState extends State { child: Container( padding: EdgeInsets.all(5.0), color: Provider.of(context).theme.defaultButtonActiveColor(), - child: showSyncing ? - Text(AppLocalizations.of(context)!.serverNotSynced, - textAlign: TextAlign.center) - : showOfflineWarning - ? Text(Provider.of(context).isGroup ? AppLocalizations.of(context)!.serverConnectivityDisconnected : AppLocalizations.of(context)!.peerOfflineMessage, - textAlign: TextAlign.center) - // Only show the ephemeral status for peer conversations, not for groups... - : (showEphemeralWarning - ? Text(AppLocalizations.of(context)!.chatHistoryDefault, textAlign: TextAlign.center) - : - // We are not allowed to put null here, so put an empty text widge - Text("")), + child: showSyncing + ? Text(AppLocalizations.of(context)!.serverNotSynced, textAlign: TextAlign.center) + : showOfflineWarning + ? Text(Provider.of(context).isGroup ? AppLocalizations.of(context)!.serverConnectivityDisconnected : AppLocalizations.of(context)!.peerOfflineMessage, + textAlign: TextAlign.center) + // Only show the ephemeral status for peer conversations, not for groups... + : (showEphemeralWarning + ? Text(AppLocalizations.of(context)!.chatHistoryDefault, textAlign: TextAlign.center) + : + // We are not allowed to put null here, so put an empty text widge + Text("")), )), Expanded( child: Scrollbar( @@ -63,30 +61,32 @@ class _MessageListState extends State { alignment: Alignment.center, image: AssetImage("assets/core/negative_heart_512px.png"), colorFilter: ColorFilter.mode(Provider.of(context).theme.hilightElementTextColor(), BlendMode.srcIn))), - // Don't load messages for syncing server... - child: loadMessages ? ListView.builder( - controller: ctrlr1, - itemCount: Provider.of(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 trueIndex = Provider.of(outerContext).totalMessages - index - 1; - return ChangeNotifierProvider( - key: ValueKey(trueIndex), - create: (x) => MessageState( - context: itemBuilderContext, - profileOnion: Provider.of(outerContext, listen: false).onion, - // We don't want to listen for updates to the contact handle... - contactHandle: Provider.of(x, listen: false).onion, - messageIndex: trueIndex, - ), - builder: (bcontext, child) { - String idx = Provider.of(outerContext).isGroup == true && Provider.of(bcontext).signature.isEmpty == false - ? Provider.of(bcontext).signature - : trueIndex.toString(); - return RepaintBoundary(child: MessageRow(key: Provider.of(bcontext).getMessageKey(idx))); - }); - }, - ) : null ))) + // Don't load messages for syncing server... + child: loadMessages + ? ListView.builder( + controller: ctrlr1, + itemCount: Provider.of(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 trueIndex = Provider.of(outerContext).totalMessages - index - 1; + return ChangeNotifierProvider( + key: ValueKey(trueIndex), + create: (x) => MessageState( + context: itemBuilderContext, + profileOnion: Provider.of(outerContext, listen: false).onion, + // We don't want to listen for updates to the contact handle... + contactHandle: Provider.of(x, listen: false).onion, + messageIndex: trueIndex, + ), + builder: (bcontext, child) { + String idx = Provider.of(outerContext).isGroup == true && Provider.of(bcontext).signature.isEmpty == false + ? Provider.of(bcontext).signature + : trueIndex.toString(); + return RepaintBoundary(child: MessageRow(key: Provider.of(bcontext).getMessageKey(idx))); + }); + }, + ) + : null))) ]))); } } diff --git a/lib/widgets/profilerow.dart b/lib/widgets/profilerow.dart index dfa79f69..de865c8e 100644 --- a/lib/widgets/profilerow.dart +++ b/lib/widgets/profilerow.dart @@ -30,43 +30,29 @@ class _ProfileRowState extends State { padding: const EdgeInsets.all(2.0), //border size child: ProfileImage( badgeCount: 0, - badgeColor: Provider - .of(context) - .theme - .portraitProfileBadgeColor(), - badgeTextColor: Provider - .of(context) - .theme - .portraitProfileBadgeTextColor(), + badgeColor: Provider.of(context).theme.portraitProfileBadgeColor(), + badgeTextColor: Provider.of(context).theme.portraitProfileBadgeTextColor(), diameter: 64.0, imagePath: profile.imagePath, - border: profile.isOnline ? Provider - .of(context) - .theme - .portraitOnlineBorderColor() : Provider - .of(context) - .theme - .portraitOfflineBorderColor())), + border: profile.isOnline ? Provider.of(context).theme.portraitOnlineBorderColor() : Provider.of(context).theme.portraitOfflineBorderColor())), Expanded( child: Column( - children: [ - Text( - profile.nickname, - semanticsLabel: profile.nickname, - style: Provider - .of(context) - .biggerFont, - softWrap: true, - overflow: TextOverflow.ellipsis, - ), - ExcludeSemantics( - child: Text( - profile.onion, - softWrap: true, - overflow: TextOverflow.ellipsis, - )) - ], - )), + children: [ + Text( + profile.nickname, + semanticsLabel: profile.nickname, + style: Provider.of(context).biggerFont, + softWrap: true, + overflow: TextOverflow.ellipsis, + ), + ExcludeSemantics( + child: Text( + profile.onion, + softWrap: true, + overflow: TextOverflow.ellipsis, + )) + ], + )), IconButton( enableFeedback: true, tooltip: AppLocalizations.of(context)!.editProfile + " " + profile.nickname, @@ -83,7 +69,7 @@ class _ProfileRowState extends State { appState.selectedProfile = profile.onion; appState.selectedConversation = null; - _pushContactList(profile, appState.isLandscape(context));//orientation == Orientation.landscape); + _pushContactList(profile, appState.isLandscape(context)); //orientation == Orientation.landscape); }); }, )); @@ -94,19 +80,17 @@ class _ProfileRowState extends State { MaterialPageRoute( settings: RouteSettings(name: "conversations"), builder: (BuildContext buildcontext) { - return OrientationBuilder( - builder: (orientationBuilderContext, orientation) { - return MultiProvider( - providers: [ - ChangeNotifierProvider.value(value: profile), - ChangeNotifierProvider.value(value: profile.contactList), - ], - builder: (innercontext, widget) { - var appState = Provider.of(context); - var settings = Provider.of(context); - return settings.uiColumns(appState.isLandscape(innercontext)).length > 1 ? DoubleColumnView() : ContactsView(); - } - ); + return OrientationBuilder(builder: (orientationBuilderContext, orientation) { + return MultiProvider( + providers: [ + ChangeNotifierProvider.value(value: profile), + ChangeNotifierProvider.value(value: profile.contactList), + ], + builder: (innercontext, widget) { + var appState = Provider.of(context); + var settings = Provider.of(context); + return settings.uiColumns(appState.isLandscape(innercontext)).length > 1 ? DoubleColumnView() : ContactsView(); + }); }); }, ), From 8b30b4a227f7f35e346f5aa91a156b5bdeeeeb74 Mon Sep 17 00:00:00 2001 From: Sarah Jamie Lewis Date: Wed, 30 Jun 2021 15:14:11 -0700 Subject: [PATCH 10/11] Multiline Support - Fixes #49 - Fixes #50 --- lib/views/messageview.dart | 38 ++++++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/lib/views/messageview.dart b/lib/views/messageview.dart index bdba1c9f..258f596e 100644 --- a/lib/views/messageview.dart +++ b/lib/views/messageview.dart @@ -7,6 +7,7 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:cwtch/views/peersettingsview.dart'; import 'package:cwtch/widgets/DropdownContacts.dart'; +import 'package:flutter/services.dart'; import 'package:provider/provider.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; @@ -102,11 +103,13 @@ class _MessageViewState extends State { } void _sendMessage([String? ignoredParam]) { - ChatMessage cm = new ChatMessage(o: 1, d: ctrlrCompose.value.text); - Provider.of(context, listen: false) - .cwtch - .SendMessage(Provider.of(context, listen: false).profileOnion, Provider.of(context, listen: false).onion, jsonEncode(cm)); - _sendMessageHelper(); + if (ctrlrCompose.value.text.isNotEmpty) { + ChatMessage cm = new ChatMessage(o: 1, d: ctrlrCompose.value.text); + Provider.of(context, listen: false) + .cwtch + .SendMessage(Provider.of(context, listen: false).profileOnion, Provider.of(context, listen: false).onion, jsonEncode(cm)); + _sendMessageHelper(); + } } void _sendInvitation([String? ignoredParam]) { @@ -137,12 +140,18 @@ class _MessageViewState extends State { Expanded( child: Container( decoration: BoxDecoration(border: Border(top: BorderSide(color: Provider.of(context).theme.defaultButtonActiveColor()))), + child: RawKeyboardListener( + focusNode: FocusNode(), + onKey: handleKeyPress, child: TextFormField( key: Key('txtCompose'), controller: ctrlrCompose, - autofocus: !Platform.isAndroid, focusNode: focusNode, - textInputAction: TextInputAction.send, + autofocus: !Platform.isAndroid, + textInputAction: TextInputAction.newline, + keyboardType: TextInputType.multiline, + minLines: 1, + maxLines: null, onFieldSubmitted: _sendMessage, decoration: InputDecoration( enabledBorder: InputBorder.none, @@ -160,13 +169,26 @@ class _MessageViewState extends State { tooltip: AppLocalizations.of(context)!.sendMessage, onPressed: _sendMessage, ), - ))), + )))), ), ], ), ); } + // Send the message if enter is pressed without the shift key... + void handleKeyPress(event) { + var data = event.data as RawKeyEventData; + if (data.logicalKey == LogicalKeyboardKey.enter && !event.isShiftPressed) { + final messageWithoutNewLine = ctrlrCompose.value.text.trimRight(); + ctrlrCompose.value = TextEditingValue( + text: messageWithoutNewLine + ); + _sendMessage(); + + } + } + void placeHolder() => {}; // explicitly passing BuildContext ctx here is important, change at risk to own health From 88114ac6eb50e7dabad2a0f42f8d128774bb7457 Mon Sep 17 00:00:00 2001 From: Dan Ballard Date: Wed, 30 Jun 2021 16:27:14 -0700 Subject: [PATCH 11/11] apply newer fluter runloop in run_loop.cpp for windows performance fix --- pubspec.lock | 40 ++++++++++++------------------------- windows/runner/run_loop.cpp | 11 ++++++++-- 2 files changed, 22 insertions(+), 29 deletions(-) diff --git a/pubspec.lock b/pubspec.lock index ec4202b9..58f991e0 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -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: @@ -70,7 +70,7 @@ packages: name: dbus url: "https://pub.dartlang.org" source: hosted - version: "0.5.1" + version: "0.5.2" desktop_notifications: dependency: "direct main" description: @@ -91,14 +91,14 @@ packages: name: ffi url: "https://pub.dartlang.org" source: hosted - version: "1.0.0" + version: "1.1.2" file: dependency: transitive description: name: file url: "https://pub.dartlang.org" source: hosted - version: "6.1.1" + version: "6.1.2" flutter: dependency: "direct main" description: flutter @@ -125,7 +125,7 @@ packages: name: glob url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" + version: "2.0.1" http: dependency: transitive description: @@ -189,20 +189,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.0" - node_interop: - dependency: transitive - description: - name: node_interop - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.1" - node_io: - dependency: transitive - description: - name: node_io - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.1" package_config: dependency: transitive description: @@ -216,7 +202,7 @@ packages: name: package_info_plus url: "https://pub.dartlang.org" source: hosted - version: "1.0.1" + version: "1.0.3" package_info_plus_linux: dependency: transitive description: @@ -244,14 +230,14 @@ packages: name: package_info_plus_web url: "https://pub.dartlang.org" source: hosted - version: "1.0.1" + version: "1.0.2" package_info_plus_windows: dependency: transitive description: name: package_info_plus_windows url: "https://pub.dartlang.org" source: hosted - version: "1.0.1" + version: "1.0.2" path: dependency: transitive description: @@ -265,7 +251,7 @@ packages: name: path_provider url: "https://pub.dartlang.org" source: hosted - version: "2.0.1" + version: "2.0.2" path_provider_linux: dependency: transitive description: @@ -300,14 +286,14 @@ packages: name: pedantic url: "https://pub.dartlang.org" source: hosted - version: "1.11.0" + version: "1.11.1" petitparser: dependency: transitive description: name: petitparser url: "https://pub.dartlang.org" source: hosted - version: "4.1.0" + version: "4.2.0" platform: dependency: transitive description: @@ -382,7 +368,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: @@ -403,7 +389,7 @@ packages: name: win32 url: "https://pub.dartlang.org" source: hosted - version: "2.1.1" + version: "2.2.4" xdg_directories: dependency: transitive description: diff --git a/windows/runner/run_loop.cpp b/windows/runner/run_loop.cpp index 2d6636ab..818b6ae2 100644 --- a/windows/runner/run_loop.cpp +++ b/windows/runner/run_loop.cpp @@ -9,7 +9,14 @@ RunLoop::RunLoop() {} RunLoop::~RunLoop() {} void RunLoop::Run() { - bool keep_running = true; + // Fix/workaround for Windows high CPU usage + // https://github.com/flutter/flutter/issues/78517#issuecomment-814843107 + MSG msg; + while (GetMessage(&msg, nullptr, 0, 0)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + /*bool keep_running = true; TimePoint next_flutter_event_time = TimePoint::clock::now(); while (keep_running) { std::chrono::nanoseconds wait_duration = @@ -40,7 +47,7 @@ void RunLoop::Run() { next_flutter_event_time = std::min(next_flutter_event_time, ProcessFlutterMessages()); } - } + }*/ } void RunLoop::RegisterFlutterInstance(