Watch
1
0
Fork
You've already forked nexus
0
forked from Nexus/nexus

Compare commits

...
Sign in to create a new pull request.
Author SHA1 Message Date
e300f4efc9
small fixups 2026-09-26 21:11:11 -04:00
bab699658f
pop sidebar before pushing notif page 2026-09-26 20:32:44 -04:00
1c1f585362
add JumpToEventController to allow jumping to events from the NotificationsPage when it has been pushed from the NotificationController 2026-09-26 19:37:47 -04:00
c90a1c41b0
working jumps from notif page
Doesn't work from notif page pushed from notif controller
2026-09-26 19:13:30 -04:00
9f070fcdba
reorganize pages into being under widgets 2026-09-26 18:06:51 -04:00
d712bb3193
tweak scroll behavior 2026-09-26 14:52:24 -04:00
3217c17ea0
don't depend on SuperSliverList for scrolls 2026-09-26 13:58:30 -04:00
031fbe326c
change highlight timing 2026-09-26 13:42:31 -04:00
0149aa2f84
fixup jumping to pins 2026-09-26 13:30:39 -04:00
a1efdb0f46
check off jumping on readme 2026-09-26 13:15:48 -04:00
389b65ae61 add support for jumping to out-of-context events (#95)
Fixes #84.

Reviewed-on: Nexus/nexus#95
2026-09-26 13:03:16 -04:00
3429a3ed98
add twim image 2026-09-25 10:20:53 -04:00
7ab92f76bf
fix for janky scrolling when tapping reply with SuperSliverView
I don't like this but it does work.
2026-09-24 22:46:48 -04:00
aecfac9533
free base before buffer 2026-09-24 22:20:31 -04:00
c7b89b8e56
small cleanups 2026-09-24 20:59:18 -04:00
721727d48c
small cleanups 2026-09-24 20:50:28 -04:00
004c3bcd0d
remove outdated error ignores
I believe some of these are fixed, if not they should be noisy so I notice them and can re-add
2026-09-24 20:38:30 -04:00
943cd85e22
treewide: ref.watch(ClientController.provider.notifier) -> ref.read 2026-09-24 20:35:20 -04:00
09904536e7
small fixups 2026-09-24 20:31:22 -04:00
856072e0b0
fixup! refactor chatview to have two sliver lists 2026-09-24 20:22:30 -04:00
110caff170
refactor chatview to have two sliver lists
Co-authored-by: Erwan Leboucher <erwanleboucher@gmail.com>
2026-09-24 20:02:23 -04:00
eeb2e2f54b
extract scroll helpers into their own hook 2026-09-24 18:10:30 -04:00
529a2e35c4
make buildEventOptions an extension 2026-09-24 14:41:13 -04:00
6ad4657d76
refactor chatview 2026-09-24 14:24:41 -04:00
38fd19ad1a
move isInBackground in main 2026-09-24 14:08:54 -04:00
0636366359
fixup errors caused by bump 2026-09-24 11:56:46 -04:00
efe9262a97
tweak timeout 2026-09-24 11:49:19 -04:00
2763a0fdf5
bump deps 2026-09-24 11:47:20 -04:00
a5da44fdea
more restrictive timeout on notification init 2026-09-24 11:42:57 -04:00
ccca02a0bc
Separate out GomuksListenerController from ClientController
Fixes #89
2026-09-24 11:03:16 -04:00
721349ca21
explicit listener for ClientStateController in notifs 2026-09-23 11:22:47 -04:00
5d994bf2bb
wait for metadata to come in on notif's rooms before sending them 2026-09-23 11:17:02 -04:00
a90bf00f18
dispose notif handler 2026-09-23 10:30:12 -04:00
f2efbbeb9f
fixup select 2026-09-22 20:48:59 -04:00
ed761d6071
gate selectable text behind mouse connected 2026-09-22 20:40:55 -04:00
8f35ea2435
Add "Copy Text" context menu option 2026-09-22 20:18:16 -04:00
023e75e063
always make events selectable (on mobile the long press overrides it) 2026-09-22 20:11:18 -04:00
4d0a4605d6
type contextMenuCallback 2026-09-22 19:57:23 -04:00
faa7292001
add codeblock copy button 2026-09-22 19:19:21 -04:00
027033ad9e
allow copying messages when on desktop without mobile mode on 2026-09-22 19:13:32 -04:00
ece3d16318
use dot shorthands in about dialog 2026-09-22 18:48:47 -04:00
5738239da2
fix name of ShowAboutDialog extension 2026-09-22 18:31:38 -04:00
a2791a6717
various small fixups 2026-09-22 15:53:37 -04:00
f910d87a23
don't require login for UP controller to finish init 2026-09-22 15:33:55 -04:00
f4142859ba
fallback isFocused to true 2026-09-22 15:05:57 -04:00
775c77194b
run in background properly on android 2026-09-22 15:02:30 -04:00
41806be9bf
More platform-independent approach to managing registered state 2026-09-22 14:34:08 -04:00
6e47594a91
fix race condition on startup 2026-09-22 11:36:29 -04:00
386b3ad1cf
inline the mention fetch 2026-09-22 10:37:49 -04:00
61f2aa7f2a
update gomuks vendorHash 2026-09-22 10:02:56 -04:00
0c660a98a7
just grab events out of get_mentions for now 2026-09-22 09:57:10 -04:00
09534a6775
use GomuksConfig 2026-09-22 09:53:00 -04:00
0cd815dc79
init ClientController before other providers 2026-09-21 23:03:57 -04:00
800ed0636d
bump nix2flatpak 2026-09-21 22:18:24 -04:00
e4cf2a837c
fixup login 2026-09-21 21:41:18 -04:00
11dca9bf14
seperate URI handler desktop file 2026-09-21 21:20:16 -04:00
436b8642b3
read not watch MultiProviderController providers
Fixes random loading animations
2026-09-21 19:27:10 -04:00
269d97be8f
bump nix2flatpak 2026-09-21 18:53:49 -04:00
43f70f35a3
bump nix2flatpak 2026-09-21 18:00:42 -04:00
92b148f5b6
gate registration behind not flatpak 2026-09-21 17:54:03 -04:00
00a42b5f1a
fixup flatpak build 2026-09-21 17:20:43 -04:00
700b4e720f
open notifications page on notif tap
please please please let me never touch c++ again i hate it

also the c++ got reformatted here but i dont really care
2026-09-21 16:56:12 -04:00
2a11bcb7e8
update hashes 2026-09-21 15:44:10 -04:00
fea39e4191
use xdg_desktop_portal over flutter_local_notifications on linux 2026-09-21 15:43:01 -04:00
deaf564c36
use portals for linux notifs 2026-09-21 14:16:29 -04:00
c0d14ac30e
don't write service by default 2026-09-20 17:27:45 -04:00
1a6a5c36ea
link to module from readme 2026-09-20 17:21:26 -04:00
35ef82accd
fixup module 2026-09-20 17:18:39 -04:00
f40dd22277
use mkEnableOption for enableNotifications 2026-09-20 17:14:56 -04:00
1cfea5a819
add nix module 2026-09-20 17:13:22 -04:00
b3023d8147
don't auto create dbus service 2026-09-20 17:00:10 -04:00
e8fb3a8523
use SharedPreferencesAsync to avoid race condition in Sharedprefs
This was so painful to debug...
2026-09-20 15:45:32 -04:00
0d1ace3fd0
add more logs for notifs 2026-09-20 13:41:22 -04:00
3d690c26d8
hopefully fixup UP on linux when backgrounded 2026-09-20 13:27:47 -04:00
3fee789c90
fixup flatpak perms 2026-09-20 00:07:47 -04:00
d7c64fea80
potentially fix notifs on flatpak 2026-09-20 00:04:50 -04:00
87e7e093f7
Revert "don't invalidate UP controller"
This reverts commit 73c4a7d07f.
2026-09-20 00:02:49 -04:00
8b7e29ae33
Set device name to "Nexus on $platform"
Fixes #86.
2026-09-19 22:41:13 -04:00
673c5bd894
fix memory leaks
Oops! They were pretty slow, but still adds up. This might fix the bug that was stopping Nexus from working on GraphineOS.
2026-09-19 21:13:03 -04:00
650c62fb99
update gomuks hash 2026-09-19 18:45:05 -04:00
4f3b77f9f3
set env for gomuks
Fixes #62
2026-09-19 18:41:09 -04:00
85bb653980
fix gomuks init on android / ios 2026-09-18 15:39:45 -04:00
a9d2ccbcd1
bump gradle 2026-09-18 13:02:40 -04:00
73c4a7d07f
don't invalidate UP controller 2026-09-18 10:57:16 -04:00
57f9498aa3
better wrapping behavior for timestamps on state events 2026-09-18 09:58:49 -04:00
cfab803fa0
show timestamps for state events 2026-09-17 23:21:33 -04:00
f23a35384d
nicer / less intrusive mention style 2026-09-17 14:27:51 -04:00
7f7fb451e6
Bump emoji picker to 1.1.1
Better performance now.
2026-09-17 12:09:16 -04:00
5d62e66cd9
remove duplicate "Windows EXE" entry in "Try it out" section of README
Thanks to @julian45 for spotting this!
2026-09-16 22:11:43 -04:00
009ba504e3
fixup logic for not init-ing UP
An XOR was never the right choice for this
2026-09-16 22:07:00 -04:00
30b922d390
enlarge emojis on emoji overlay 2026-09-16 22:03:42 -04:00
63183e0824
don't init UP on platforms other than Linux or Android 2026-09-16 21:59:55 -04:00
163947fc90
add emoji overlay 2026-09-16 16:52:58 -04:00
11457470a0
move around args to overlays 2026-09-16 16:30:15 -04:00
dca0b7dd7d
refactor overlay system 2026-09-16 16:27:10 -04:00
e5dc270f83
bump emoji picker 2026-09-16 16:27:07 -04:00
810a0b102b
add support for setting recent emoji 2026-09-16 15:46:51 -04:00
ec1603b828
add support for showing recent emoji 2026-09-16 15:18:41 -04:00
5acdbb5be0 Better emoji picker (#73)
Adds a better, custom, emoji picker.

Reviewed-on: Nexus/nexus#73
2026-09-16 14:47:46 -04:00
e21c9e8c22
make highlights work better for Notifications page 2026-09-12 09:52:01 -04:00
ea687471bc
Make TODO on notifications page more useful 2026-09-11 22:42:43 -04:00
8c440447f2
check off Notifications page in readme 2026-09-11 22:42:17 -04:00
8ebec15324
hide label whe not selected for filter 2026-09-11 22:41:38 -04:00
cd8d551e26
take notif filter out of card 2026-09-11 22:39:18 -04:00
118e5a5826
update readme for platform support to be more clear 2026-09-11 22:35:13 -04:00
6ca9b2a948
add notification page filter 2026-09-11 22:34:43 -04:00
23e01c7a0d
Notifications page
Doesn't yet allow for jumping to events
2026-09-11 22:03:42 -04:00
9e7fcdbef7
sticky -> clientSticky to avoid conflicts with sticky events 2026-09-11 19:50:29 -04:00
9507d69458
move windows warning in readme 2026-09-11 19:29:47 -04:00
13d90df226
remove un-needed overrides 2026-09-11 19:28:10 -04:00
e925f9657c
add needed permissions for UnifiedPush to nexus flatpak 2026-09-10 17:14:41 -04:00
b8882d6e48
mark off notification support as added, add notifications page todo 2026-09-10 17:06:14 -04:00
ff9bf3bec4 Push Notifications (#66)
Fixes #35.

Things to do:
- [x] Register with local distributor
- [x] Register with homeserver
- [x] Recieve messages
- [x] Show notifications
- [ ] Notifications page (could come later)

Reviewed-on: Nexus/nexus#66
2026-09-10 15:37:05 -04:00
6e42902322
run GomuksInit on an Isolate
Fixes #70
2026-09-10 15:32:30 -04:00
c105a6035c
use dot shorthands where possible in generate script 2026-09-10 15:21:53 -04:00
3d7ef9b32f
actually generate bindings
Yes `ffigen`, I did actually want you to generate the bindings, not a file consisting only of comments. Crazy, right?
2026-09-10 15:20:56 -04:00
51ef66174a
fix generate script to work with new ffigen 2026-09-10 15:15:12 -04:00
1efb68ebe0
bump deps, remove unwanted and now un-needed analyzer rule
Fixes #69
2026-09-10 15:09:47 -04:00
0a667fda0b
update gomuks vendorHash 2026-09-09 15:44:25 -04:00
da352cd035
cap max length of embeds 2026-09-09 15:37:41 -04:00
0201f71e5d
allow banning left users 2026-09-09 15:26:04 -04:00
4314c88d5c
fallback to empty profile if fetch fails 2026-09-09 15:25:10 -04:00
88cdcf9863
use compat bridge for settings sidebar 2026-08-23 14:02:25 -04:00
e2f25749e0
fix fetching spec versions early 2026-08-23 14:00:11 -04:00
47a3d9d92f
Add comment about why MaterialUiCompatibilityBridge is needed for HtmlWidget
[skip ci]
2026-08-22 15:19:46 -04:00
a680c5cd0c
update navigation_rail_m3e hash 2026-08-22 15:15:39 -04:00
0887421f3e
put bridge for link colors 2026-08-22 15:14:41 -04:00
a090d88a23
add theming workaround for navigation_rail_m3e 2026-08-22 15:12:35 -04:00
32693fb3b5
fix path in nix build 2026-08-22 14:26:28 -04:00
4e1f1b64bc
run APK build on x86_64 2026-08-22 14:18:12 -04:00
20f1c784f6
optimize gomuks build size 2026-08-22 14:16:35 -04:00
9b79304edc
try to optimize APK size 2026-08-22 14:05:31 -04:00
b797b8de9c
fix icons not rendering 2026-08-22 13:51:44 -04:00
56bb75866c
bump JDK version 2026-08-22 13:50:00 -04:00
3baea40669
skip broken android lints 2026-08-22 13:24:26 -04:00
2e72ecd559
fix navigation_rail_m3e hash
Fixes nix build
2026-08-22 13:06:33 -04:00
077044ec19 Move to Flutter 3.47, use the improvements that come with this (#64)
Reviewed-on: Nexus/nexus#64
2026-08-22 13:04:33 -04:00
01b13b4764
set min version of macos to 13.0 2026-08-12 10:46:32 -04:00
050e42cc6f
comp for older macos 2026-08-12 10:34:36 -04:00
67cee201b6
add TODO comment to LinkToMention extension 2026-08-11 20:52:14 -04:00
2d7b067c93
use mobile icon for macOS
this looks better in the macos launcher squircles
2026-08-11 20:39:04 -04:00
a9993013f5
add rooms to mention chips
Needs handling for event links, plus clickability
2026-08-11 20:34:43 -04:00
9c488e8981
only upload .dmgs 2026-08-11 20:08:59 -04:00
5c16f42d20
pin upload-artifact to a commit 2026-08-11 19:58:15 -04:00
092fc616e6
fix paths in macos CI 2026-08-11 19:56:26 -04:00
6cbf78be6b
change step names for macos
[skip ci]
2026-08-11 19:20:08 -04:00
68f4bb0c03
update macos status in readme 2026-08-11 19:18:09 -04:00
9e24f4cb31
add DMG builds 2026-08-11 19:12:56 -04:00
43d2e94d62
make loadOlder properly guard 2026-08-11 10:39:45 -04:00
62fe37c6ae
use mobile icons on iOS 2026-08-11 10:17:24 -04:00
b9dfbd3ca2
update MacOS icons 2026-08-11 10:16:18 -04:00
620440e2a1
Allow logging into homeservers without discovery working 2026-08-10 22:50:13 -04:00
724171384c
change readme wording
[skip ci]
2026-08-08 20:49:23 -04:00
1bd677eb23
add MacOS support to readme 2026-08-08 20:36:48 -04:00
41658c3a9d
change output artifact name for macos ci 2026-08-08 20:33:41 -04:00
b011cc2166
reformat build hook file
[skip ci]
2026-08-08 20:31:09 -04:00
75ad6cbd02
set SDKROOT for macos build 2026-08-08 20:20:02 -04:00
6c1d3d8894
debug macos 2026-08-08 20:08:49 -04:00
842ab0a82c
don't use xcrun clang on macos 2026-08-08 19:57:03 -04:00
a0e5d2fb9e
make macos-related actions not use nix 2026-08-08 19:48:56 -04:00
a2cdc3df68
set CC manually macos 2026-08-08 19:08:20 -04:00
07f8a35b74
bump deps, remove hack for fallback theme that is no longer needed 2026-08-08 19:05:04 -04:00
85b9007c47
bump flake 2026-08-08 18:53:12 -04:00
5bbd51c4bc
fix macos permission issues 2026-08-08 18:52:49 -04:00
21a0e0db70
correctly undo lipo changes 2026-08-08 18:03:57 -04:00
a5f42fe56e
add workaround for lipo issues with Flutter from Nix on MacOS 2026-08-08 17:56:01 -04:00
185c1d2714
undo lipo changes 2026-08-08 17:53:58 -04:00
7eab09585b
Revert "move lipo wrapper"
This reverts commit 56dbd91c96.
2026-08-08 17:51:00 -04:00
c84f0e7e93
dismiss keyboard on scroll of room chat 2026-08-08 17:02:31 -04:00
f7847d587c
only enable autofocus on desktop platforms 2026-08-08 16:57:51 -04:00
56dbd91c96
move lipo wrapper 2026-08-08 16:49:25 -04:00
7bb4d87638 feat: Add iOS platform support (#60)
Co-authored-by: Henry-Hiles <henry@henryhiles.com>
Reviewed-on: Nexus/nexus#60
2026-08-08 16:35:56 -04:00
bf31f5510a
make room dialog scrollable 2026-08-08 16:21:58 -04:00
bd185824f9
set loading when waiting for token exchange 2026-08-08 16:18:54 -04:00
2afd5ae258
put account data keys in model 2026-08-08 16:14:11 -04:00
76f9175857
update gomuks vendorHash 2026-08-08 13:27:10 -04:00
e32941f062
remove old extraEnv for macos
No longer needed.
2026-08-08 13:22:51 -04:00
cf89604ff5
update gomuks
Fixes error when fetching versions after login
2026-08-08 13:21:29 -04:00
83e8084213
catch parsing errors for invalid replies 2026-08-08 11:31:07 -04:00
ae5b6e2b40
bump gomuks, fix profile issues caused by this 2026-08-05 16:28:47 -04:00
1621e917c0
slight formatting change for video player 2026-08-05 16:03:49 -04:00
d1c2b2dd0a
show reactions inline in non-message events that are in bubbles, e.g. stickers
Fixes #59.
2026-08-05 16:03:41 -04:00
82a0dd90b0
update gomuks hash 2026-08-04 21:08:51 -04:00
f97c5548a3
add invite blocking support plus msc4494 support
To accomplish this I also reworked how account data is stored and added a method to fetch capabilities, and another method to set account data
2026-08-04 21:04:55 -04:00
115bec5f05
slightly tweak readme
[skip ci]
2026-07-31 11:55:48 -04:00
fc4aa5a10d
persist member list opened status 2026-07-31 10:20:06 -04:00
f3c31db244
update build requirements 2026-07-29 21:57:03 -04:00
419d75ca83
wrap messages with unknown message types 2026-07-29 19:46:39 -04:00
9831446c66
add a little padding to send errors 2026-07-29 16:18:07 -04:00
d7f49568a7
move attachment sending check to be earlier
fixes sending with keyboard before attachment uploaded
2026-07-29 12:11:57 -04:00
f0f426a647
improve matcher for encrypted media 2026-07-29 12:06:19 -04:00
80fa9673bb
fix pending attachments disappearing when new events are sent 2026-07-29 11:58:12 -04:00
8c25228bd9
comment out macos CI auto running [skip ci] 2026-07-28 20:39:03 -04:00
9bf664624a
clone submodules on macos 2026-07-28 17:43:51 -04:00
e8b90591d5
only include wayland in devshell on macos 2026-07-28 17:16:21 -04:00
b2813a0eb5
use devshell for macos 2026-07-28 17:04:06 -04:00
9298eb815d
use libclang.dylib on macos 2026-07-28 15:57:39 -04:00
06075f75c5
make gomuks nix package build to a .dylib on macos 2026-07-28 15:49:27 -04:00
60968f5f3e
make macos builder build app from nix 2026-07-28 15:29:41 -04:00
afd6168535
fix macos CI name
[skip ci]
2026-07-28 15:15:20 -04:00
2a1cc33ee3
add macos ci
hopefully this works first try :3
2026-07-28 15:13:14 -04:00
5f13d3fbf5
don't show errors when url preview fails 2026-07-27 22:02:20 -04:00
eca9d3b411
use gomuks for URL previews 2026-07-27 16:01:40 -04:00
16fdf0c420
download audio and video using gomuks 2026-07-27 15:46:08 -04:00
3536f74851
mark encrypted media as done 2026-07-26 23:11:01 -04:00
fa451621de
use gomuks for downloading media 2026-07-26 23:01:36 -04:00
90230651e6
default auth method to none
Fixes auth on MAS
2026-07-26 18:26:20 -04:00
92b88e46ac
fix attachments disappearing when editing messages 2026-07-26 17:21:01 -04:00
1799e02844
update gomuks vendorHash 2026-07-26 15:13:39 -04:00
cf26ec7130
bump gomuks 2026-07-26 14:40:20 -04:00
716541b457
fixup oauth animation 2026-07-24 10:13:20 -04:00
965c7ea2dc
add media for twim 2026-07-24 09:59:50 -04:00
85d02f2ac9
bump gomuks 2026-07-23 15:29:23 -04:00
1c446c4cdf
bump gomuks
fixes no loading issue when restarting verification after closing app
2026-07-23 13:58:33 -04:00
51430d2830
Verify state on login
This fixes "already logged in errors" if you started logging in before cancelling, and then trying again.
2026-07-22 21:53:42 -04:00
4e208764f5
remove outdated comment 2026-07-22 16:45:47 -04:00
eecc307f04
disable provider auto retry 2026-07-22 16:35:18 -04:00
6221eb4a7a
bump gomuks
Fixes overly aggressive caching on login, causing issues when changing login server
2026-07-22 16:19:06 -04:00
370549072e
make logout properly pop all settings on mobile 2026-07-22 15:57:21 -04:00
80b938c0be
fix wrong settings categories opening when multiple sections exist 2026-07-22 15:37:50 -04:00
87e1ef0d9b
clean up if statements into one 2026-07-22 12:00:35 -04:00
f8c705531c
ignore setState during build
It seems to happen randomly right now.
2026-07-22 11:59:10 -04:00
2a91959333
fix encrypted uploads 2026-07-21 21:34:49 -04:00
34ddd6d32b
change font weight for tooltips 2026-07-21 20:57:58 -04:00
a8726feef6
allow sending messages without a body if they have an attachment 2026-07-21 20:27:21 -04:00
bd1bad76d7
add camera picking support
Not tested.
2026-07-21 20:21:16 -04:00
c4f63d18b5
add support for sending media
Still needs camera support.
2026-07-21 20:19:01 -04:00
a8285548e8
custom style for tooltips 2026-07-21 18:25:38 -04:00
cdad9b760e
add settings to login page, but gate login settings 2026-07-21 18:00:52 -04:00
06c5411dfc
fix bug flutter bump introduced in mention overlay 2026-07-21 16:28:05 -04:00
f6b5bd4057
bump gomuks 2026-07-21 16:27:53 -04:00
0da3b4da22
don't require non-null metadata 2026-07-21 16:25:15 -04:00
a557cffdbf
remove old comment in gradle 2026-07-20 20:41:09 -04:00
9d7156d176
remove un-needed context 2026-07-20 20:40:24 -04:00
b792247575
slight wording tweak 2026-07-20 20:39:12 -04:00
35fbe1094f
update login status in readme 2026-07-20 20:38:26 -04:00
05d1c3b04a
link to macos issue 2026-07-20 20:38:11 -04:00
22e58e3d05
fix search logic when multiple categories exist 2026-07-20 20:00:44 -04:00
09bc9bdcbd
fix highlightwrapper on new flutter version 2026-07-20 19:55:19 -04:00
7d106ad3a2 OAuth Support (#53)
Rips out the old auth method, adds OAuth support. Fixes #51.

Tested Platforms:
- [x] Linux
    - [x] Flatpak
    - [x] Native (Nix)
- [x] Android
- [ ] Windows
- [ ] MacOS

Reviewed-on: Nexus/nexus#53
2026-07-20 19:46:18 -04:00
5df975f607
wrap settings category in safearea 2026-07-19 00:30:41 -04:00
8f3f9fbef1
wrap select server page in safe area 2026-07-19 00:20:04 -04:00
a9ac891ec4
wrap chat page in a safearea 2026-07-19 00:12:15 -04:00
7992f0e815
treewide(refactor): rename files to follow the same style 2026-07-18 12:12:54 -04:00
15d441e4c4
mark search as fullscreen when categories are pages 2026-07-17 22:20:54 -04:00
7492d3a3d4
add padding to select server page 2026-07-17 22:18:42 -04:00
518b0dd11e
mark settings as done in readme 2026-07-17 20:37:59 -04:00
0ef9b25320 Add settings page (#46)
Fixes #37, fixes #47.

Reviewed-on: Nexus/nexus#46
2026-07-17 20:36:41 -04:00
06824784cb
change event padding 2026-07-14 20:22:39 -04:00
08d67553be
fix message bubble alignment 2026-07-14 20:17:44 -04:00
8b2d354a60
use .of(context) instead of .pop(context) 2026-07-14 20:10:40 -04:00
8773faf7c4
reverse pins list 2026-07-14 19:58:39 -04:00
818e582ddd Support for pinned messages (#49)
The first draft to support pinned messages. Fixes #39.

Co-authored-by: Henry-Hiles <henry@henryhiles.com>
Reviewed-on: Nexus/nexus#49
2026-07-14 19:29:47 -04:00
71a4274ff2
refactor build.dart 2026-07-13 18:38:34 -04:00
7b734a89ac
add client perm for MacOS 2026-07-07 20:05:18 -04:00
ceb749d272
trim SDK path 2026-07-07 19:58:31 -04:00
45240f6cb0
fix generate.dart on macos 2026-07-07 19:26:41 -04:00
4c90fbd7d1
get xcode sdk 2026-07-07 18:51:27 -04:00
8e76da4ac2
remove macos titlebar
Credit to @mirameow:matrix.org for this!
2026-07-07 18:26:37 -04:00
195ebc776a
add macos folder 2026-07-07 15:49:07 -04:00
a1e217ac78
more restrictive ai policy 2026-07-03 14:04:07 -04:00
148bc8f95c
improve creation of editSource 2026-06-23 11:32:37 -04:00
b037dc06c8
add pulseaudio socket to flatpak 2026-06-23 11:11:05 -04:00
3c7c74f745
hide URL previews if generating them throws an error 2026-06-23 10:50:20 -04:00
b727d0342d
bump gomuks 2026-06-21 17:52:05 -04:00
db5735e9e2
Fixup aspect ratio calculation for non-null widths 2026-06-20 23:48:15 -04:00
7c01611859
Default to 1:1 when no width/height are given for an image 2026-06-20 23:39:05 -04:00
632c02a517
update windows tags 2026-06-18 14:52:18 -04:00
355c564123
update gomuks vendorHash 2026-06-18 14:48:37 -04:00
1af957d4a1
bump gomuks 2026-06-18 14:44:56 -04:00
1986e2a627
fixes to creator power level logic 2026-06-17 23:24:25 -04:00
ab40600746 Take into account creators when checking power levels (#44)
Fixes #40.

Reviewed-on: Nexus/nexus#44
Reviewed-by: Henry Hiles <henry@henryhiles.com>
2026-06-17 23:16:51 -04:00
2d0f41000e
improve expandable image viewer 2026-06-13 20:49:45 -04:00
3349ca7253
wrap expanded image stack in a safearea to help with notch issues 2026-06-13 18:44:02 -04:00
18657eb980
improved expandable image widget 2026-06-13 18:31:14 -04:00
b4b157c39f
fix check
Don't check off clickable room mentions (because its not true)
2026-06-12 15:50:16 -04:00
a76b6e6ed3
remove screenshots, now that twim is out 2026-06-12 11:02:00 -04:00
5bbd472999
use gingers profile for an example 2026-06-12 09:56:19 -04:00
6c0e149c25
add profile screenshot 2026-06-12 09:55:28 -04:00
b26c144eea
add new screenshots of sidebars 2026-06-12 09:51:42 -04:00
ddc8db8326
some keyboard navigation fixes
This still isnt perfect, it sometimes skips over nodes, needs investigation.
2026-06-11 13:41:06 -04:00
bc307cbcda
up size of spaces in sidebar 2026-06-11 12:50:47 -04:00
e40de37b9d
move message button above kick/ban 2026-06-10 10:41:25 -04:00
7757825e27
add placeholder while profile loading 2026-06-10 10:40:21 -04:00
795e9b6e9b
add l10n todo comment 2026-06-09 21:15:15 -04:00
abba60c28b
onTapUp -> onTap when possible 2026-06-09 20:40:31 -04:00
8cea4b6cf3
fix user sheet on small screens 2026-06-09 20:37:21 -04:00
d46646d781
redesign user popover 2026-06-09 20:34:56 -04:00
e15d947fac
rename FlashWrapper to HighlightWrapper 2026-06-08 11:03:34 -04:00
562ce5d4ff
Add link to settings issue 2026-06-07 17:12:54 -04:00
f60189bfb8
fix mark all as read behavior with subspaces 2026-06-07 16:57:57 -04:00
309d0df581
fix unread logic to take into account subspaces 2026-06-06 21:19:01 -04:00
3310d9b907
nicer error handling for message parses 2026-06-06 19:13:45 -04:00
8c047827de
Fix text overflows for long subspace names 2026-06-06 19:02:58 -04:00
d513e466fd
Render subspace avatars, if available 2026-06-06 18:40:32 -04:00
84a729aea8
new screenshots, update readme 2026-06-06 17:38:54 -04:00
23e0aa3c4e
change image fit 2026-06-06 17:30:24 -04:00
f0a26b58d1
fix incorrect selected hint 2026-06-06 17:09:54 -04:00
78b5abea7d
fix out of range error 2026-06-06 17:03:06 -04:00
e1d7a30a06
Support one level of subspaces 2026-06-06 15:11:40 -04:00
0c61623a94
fix fallback for null displayName in mention chip 2026-06-06 13:15:41 -04:00
0a9b71230b
set sidebar width to infinity 2026-06-06 13:04:44 -04:00
15c057707f
slightly lower size of sidebar 2026-06-06 13:04:12 -04:00
9cc18e16b8
only show appbar on member list if its a drawer 2026-06-06 13:02:51 -04:00
240984a832
Don't connect M3EToggleButtonGroup
I think it looks nicer this way.
2026-06-06 12:25:09 -04:00
633e83b915
slight cleanups 2026-06-06 12:21:42 -04:00
c5122fc34f
add some more padding to member list 2026-06-06 10:55:12 -04:00
457de3c77c
more performant member list 2026-06-06 10:51:56 -04:00
c9aa0173d8
fix navigation rail hash 2026-06-06 10:18:40 -04:00
22aa26fd05
fix keyboard navigation of forms
Including submit with keyboard, and not defocusing on submit of a form
2026-06-06 10:15:29 -04:00
c10c74a1f3
change max line size for navigation rail 2026-06-05 23:32:12 -04:00
46136c09ad
fix padding color of space sidebar 2026-06-05 21:47:13 -04:00
5f9622e1c9
try to fix android build 2026-06-05 21:39:51 -04:00
6e02cce84f
WIP subspace support 2026-06-05 21:23:06 -04:00
7e7e6877e2
add hash for navigation_rail_m3e to fix nix build 2026-06-05 20:42:52 -04:00
895ab3c96f
redesign sidebar to be m3e 2026-06-05 20:38:03 -04:00
b25840756d
add back shift+enter for newline 2026-06-05 19:40:12 -04:00
735a3357d7
fix logic for deciding when to fetch members 2026-06-05 18:38:27 -04:00
02b7892fb0
better handle when room is null 2026-06-05 18:33:16 -04:00
3afb4befa5
add null check in room chat controller 2026-06-05 18:10:41 -04:00
a11663eece
use M3EToggleButtonGroup 2026-06-05 18:10:41 -04:00
7f12efd338
add some more padding 2026-06-05 18:10:41 -04:00
fcdada6f3e
add support for v12 creators 2026-06-05 18:10:41 -04:00
0c950247b0
improve UI of member list, sort by power level 2026-06-05 18:10:41 -04:00
27dca24889
better login flow
Co-authored-by: Henry-Hiles <henry@henryhiles.com>
2026-06-05 17:28:53 -04:00
621bb74cc9
turn up max zoom of expandable image viewer 2026-06-05 12:52:30 -04:00
33c3a568f9
remove extra indent from nix build 2026-06-04 21:14:53 -04:00
561f6ecc84
use correct fallback for icons 2026-06-04 20:49:14 -04:00
a7ccf0ff00
fix not showing first membership events 2026-06-04 19:26:18 -04:00
0e984fd95b
change some icons for events 2026-06-04 19:25:28 -04:00
c898b2671a
add link to #35 from readme 2026-06-03 10:48:07 -04:00
e63e5a8c08
fix auto scroll down sometimes not triggering 2026-06-03 10:41:34 -04:00
a87c9dc678
warm up emojis controller 2026-06-03 10:24:05 -04:00
5fcc31b427
add a slight offset to the maxScrollExtent jump to not accidentally mark room as read 2026-06-03 10:18:20 -04:00
99270f4bd1
don't reverse CustomScrollView
Reviewed-on: Nexus/nexus#34
2026-06-02 21:09:35 -04:00
d2ec5f035b
treewide: use dot shorthands where possible
Now this feature is stable, we should use it. I might have missed some usecases, but these can be added in future commits.
2026-06-02 12:50:56 -04:00
6281c1d13a
make UrlPreviewController not autoDispose 2026-05-31 22:13:46 -04:00
60315de04a
update screenshots 2026-05-31 22:02:22 -04:00
eb87cbc17b
more elegantly handle empty displaynames 2026-05-31 21:46:29 -04:00
130dbac879
Link to Effective Dart: Style guide in DEVELOPMENT.md
Co-authored-by: istalri <oldangrydanishgirl.unit949@passinbox.com>
2026-05-31 13:46:19 -04:00
2dd3fed62f
add info block for stddef issues 2026-05-31 13:02:41 -04:00
f60a499875
better loading state for message displayname widget 2026-05-30 11:35:12 -04:00
a72ef5ea2d
fix incorrect message grouping heuristics 2026-05-30 11:30:07 -04:00
1b81e31c13
add early return on build hook 2026-05-30 11:19:27 -04:00
db12fd2e9a
remove extra curly bracket in logger 2026-05-30 11:11:19 -04:00
60454ed249
remove deprecated argument to build_runner 2026-05-29 13:14:06 -04:00
0a333e92d1
add an AI policy 2026-05-29 13:10:01 -04:00
31c3173bb5
add member list to readme 2026-05-28 19:16:29 -04:00
c6904e9766
Fix some alignment issues 2026-05-26 21:56:44 -04:00
e5b7512e79
nicer action buttons on user popover 2026-05-26 21:50:40 -04:00
5daa861a31
round menus 2026-05-26 21:26:40 -04:00
82860deff1
make padding symmetrical for load more button 2026-05-26 21:04:17 -04:00
2ec442b35b
fix conditional rendering of popover actions 2026-05-26 20:56:32 -04:00
786c8cb3e2
remove un-needed double check of condition 2026-05-26 20:18:28 -04:00
a150ef2ecf
Fix some textOnly handling 2026-05-26 20:04:09 -04:00
bb037c8162
set max lines for pmp text to 1 2026-05-26 19:58:01 -04:00
eac59c58f5
center align pmp text 2026-05-26 19:54:56 -04:00
4e5c709fb9
slight refactor of callback in message avatar widget 2026-05-26 19:53:05 -04:00
451875b137
add sticker support 2026-05-26 19:43:25 -04:00
e1c81b504a
render TopicContent 2026-05-26 19:30:57 -04:00
f27db22151
render ServerACLContent 2026-05-26 19:29:47 -04:00
3d6ebedd94
render PinnedEventsContent 2026-05-26 19:25:41 -04:00
70eba46c76
add and render HistoryVisibilityContent 2026-05-26 19:22:53 -04:00
ec64a81fed
add create event, fix generic event icon 2026-05-26 19:13:19 -04:00
2ba620350d
refactor message renderer into its own widget 2026-05-26 19:11:09 -04:00
a0c2eefc1e
Add room alias support 2026-05-26 18:44:27 -04:00
9939e59429
Don't underline room topic
This makes finding out that the room dialog exists slightly difficult, but it looks nicer.

We could look into another way to make it obvious that room icon, title, and description are clickable.
2026-05-26 15:35:08 -04:00
e69f04f6e7
Add room details dialog
Fixes #20
2026-05-26 15:31:37 -04:00
4848840538
increase padding for no permission message 2026-05-26 13:09:32 -04:00
64b3127fd1
show last displayname if displayname loading 2026-05-26 12:14:35 -04:00
b836c3b06e
show messages whilst sending 2026-05-26 12:07:43 -04:00
d9f62a9de9
show last avatar if avatar loading 2026-05-26 12:07:35 -04:00
32dd08fd91
expand no permissions message 2026-05-26 10:42:23 -04:00
6de046bf7b
Fix sizing of event previews 2026-05-26 10:14:26 -04:00
ebbb4dc662
make pmp via text smaller 2026-05-26 09:52:35 -04:00
1d6a121ec4
calculate image aspect ratio for more accurate blurhash 2026-05-26 09:47:23 -04:00
ed0292468a
show hashed colors while avatar loading 2026-05-26 09:38:29 -04:00
8b310c955d
Mark windows support as added 2026-05-25 12:01:12 -04:00
14b140e23d
make SDK bound less strict 2026-05-24 10:53:56 -04:00
b47e61e005
rename chat box to composer 2026-05-23 20:21:44 -04:00
05bc9034d1
measure size of chat box to dynamically adjust padding
Fixes #21
2026-05-23 20:14:33 -04:00
d7ea233b18
copy mingw dlls windows 2026-05-23 18:31:36 -04:00
70ffbedba4
fix typo in DEVELOPMENT.md 2026-05-23 12:29:56 -04:00
a1386790a9
update gomuks vendorHash 2026-05-23 12:21:04 -04:00
68d2f654cc
bump gomuks 2026-05-23 12:17:40 -04:00
5368bacf1d
Add a code style guide to DEVELOPMENT.md 2026-05-23 12:13:41 -04:00
564fe3c964 Update flutter version in windows CI 2026-05-21 17:05:39 -04:00
16cf126df4 Remove flutter chat (#26)
Had to squash merge manually as Forgejo was erroring
2026-05-21 17:02:08 -04:00
bd1d5ea745
fixup bugs related to PMP
Closes #25, as "Explain how to send messages using a certain PMP" is now added to the progress list.
2026-05-09 21:42:51 -04:00
1ca802c78b
fix gomuks vendor hash 2026-05-09 21:01:08 -04:00
7b9eda2d36
update submodule 2026-05-09 20:57:47 -04:00
63eb001c09
bump gomuks 2026-05-09 18:25:15 -04:00
00c3503c1f
Add development instructions 2026-05-09 18:24:35 -04:00
469a625c40
add mark as read for rooms/DMs, fixes #24 2026-05-09 11:10:52 -04:00
66ef2de027
fix android build by overriding path_provider_android back to an earlier version
I don't know why this is needed
2026-05-08 22:17:11 -04:00
972c143de2
fix windows build
Bumps flutter version for windows.yml, fixing build
2026-05-08 21:41:33 -04:00
2f39985afb
bump deps 2026-05-08 21:34:22 -04:00
0ab466d011
fix Android icon
Adds a monochrome icon, along with reverting the foreground to its previous state, except 512x512. Should hopefully be the end of Android icon chicanery.
2026-05-06 19:13:23 -04:00
7857bcdc2e
fix icon sizing on login page 2026-05-06 18:17:22 -04:00
9faff092ed
higher res PNGs 2026-05-06 18:16:07 -04:00
0949fa6523
improve android app icon 2026-05-06 18:07:25 -04:00
e310f0f60e
fix some power level checks, fixes #19 2026-05-04 12:53:04 -04:00
7d8b267986
update progress list [skip ci] 2026-05-04 00:06:31 -04:00
c945c26413
Fix outdated repo links 2026-05-03 20:29:59 -04:00
4dc16a5529
Revert "WIP removal of new_events_controller"
This reverts commit 5a99616e9c.
2026-05-03 12:10:37 -04:00
ebd4b8a765
higher res pngs 2026-05-03 12:02:21 -04:00
26b95fac69
fix android icons 2026-05-02 16:42:55 -04:00
152331b262
Don't show icon in readme as forgejo messes up formatting 2026-05-02 16:36:10 -04:00
5f56c52fe0
use center tag 2026-05-02 10:12:32 -04:00
a8ae10c9ce
new icons 2026-05-02 10:02:40 -04:00
ad36dcb2f3 Update README.md 2026-04-28 23:12:07 -04:00
Zach Russell
8b4cd75076 Update windows build chain docs 2026-04-28 23:12:07 -04:00
5a99616e9c
WIP removal of new_events_controller [skip ci] 2026-04-28 20:44:12 -04:00
def69d85e7
add option for aligning bubbles to progress list 2026-04-24 20:03:14 -04:00
f4b2dcb824
hopefully fix debugLocked error 2026-04-14 18:09:31 -04:00
50e1a8e4c7
remove un-needed async 2026-04-14 10:58:25 -04:00
82dab26fd4
fix emoji dep hash 2026-04-13 23:18:01 -04:00
313dc377ec
fetch emoji list from gemoji for a more complete emoji list 2026-04-13 22:44:22 -04:00
413 changed files with 15305 additions and 6993 deletions

View file

@ -27,7 +27,7 @@ jobs:
KEYSTORE_CONTENT: ${{ secrets.KEYSTORE_CONTENT }} KEYSTORE_CONTENT: ${{ secrets.KEYSTORE_CONTENT }}
- name: Build app - name: Build app
run: nix develop --command bash -c "flutter pub get && dart scripts/generate.dart && flutter pub run build_runner build && flutter build apk --release" run: nix develop --command bash -c "flutter pub get && dart scripts/generate.dart && flutter pub run build_runner build && flutter build apk --target-platform android-arm64"
env: env:
KEYSTORE_PATH: ../../keystore.jks KEYSTORE_PATH: ../../keystore.jks
KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }} KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }}

View file

@ -34,4 +34,4 @@ jobs:
uses: actions/upload-artifact@v6 uses: actions/upload-artifact@v6
with: with:
name: flatpak-${{ matrix.arch }} name: flatpak-${{ matrix.arch }}
path: result/nexus.federated.Nexus.flatpak path: result/nexus.federated.nexus.flatpak

48
.github/workflows/ios.yml vendored Normal file
View file

@ -0,0 +1,48 @@
name: "Build iOS App"
on:
push:
branches: ["main"]
tags: ["*"]
workflow_dispatch:
jobs:
build-app:
runs-on: macos-latest
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
submodules: recursive
- name: Set up Flutter
uses: subosito/flutter-action@v2
with:
flutter-version: 3.47.4
- name: Set up Go
uses: actions/setup-go@v6
with:
go-version-file: gomuks/go.mod
- name: Build app
run: |
flutter pub get
dart scripts/generate.dart
flutter pub run build_runner build
flutter build ios --release --no-codesign
# Unsigned IPA: SideStore/AltStore re-sign this on-device with the
# user's own Apple ID at install time, so no certificate is needed here.
- name: Package unsigned IPA
run: |
mkdir Payload
cp -r build/ios/iphoneos/Runner.app Payload/
zip -r Nexus.ipa Payload
- name: Upload IPA artifact
uses: actions/upload-artifact@v6
with:
name: Nexus.ipa
path: Nexus.ipa

47
.github/workflows/macos.yml vendored Normal file
View file

@ -0,0 +1,47 @@
name: "Build MacOS App"
on:
push:
branches: ["main"]
tags: ["*"]
workflow_dispatch:
jobs:
build-app:
runs-on: macos-latest
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
submodules: recursive
- name: Set up Flutter
uses: subosito/flutter-action@v2
with:
flutter-version: 3.47.4
- name: Set up Go
uses: actions/setup-go@v6
with:
go-version-file: gomuks/go.mod
- name: Build App
run: |
flutter pub get
dart scripts/generate.dart
flutter pub run build_runner build
flutter build macos --release
- name: Create DMG
id: create-dmg
uses: L-Super/create-dmg-actions@28511e988b13ca34096d439159a66d468b8e724f
with:
dmg_name: nexus
src_dir: build/macos/Build/Products/Release/Nexus.app
- name: Upload DMG
uses: actions/upload-artifact@v6
with:
name: nexus.dmg
path: ${{ steps.create-dmg.outputs.dmg_path }}

View file

@ -19,17 +19,23 @@ jobs:
- name: Set up Flutter - name: Set up Flutter
uses: subosito/flutter-action@v2 uses: subosito/flutter-action@v2
with: with:
flutter-version: 3.41.5 flutter-version: 3.47.4
- name: Set up Go - name: Set up Go
uses: actions/setup-go@v6 uses: actions/setup-go@v6
with: with:
go-version-file: gomuks/go.mod go-version-file: gomuks/go.mod
- name: Setup MSYS2
uses: msys2/setup-msys2@v2
with:
msystem: MINGW64
install: >-
mingw-w64-x86_64-gcc
- name: Go build - name: Go build
run: | run: |
cd gomuks/pkg/ffi cd gomuks/pkg/ffi
go build -tags goolm -o ../../../libgomuks.dll -buildmode=c-shared go build -tags goolm,sqlite_fts5 -o ../../../libgomuks.dll -buildmode=c-shared
- name: Build with Flutter - name: Build with Flutter
run: | run: |
@ -38,11 +44,12 @@ jobs:
flutter pub run build_runner build flutter pub run build_runner build
flutter build windows --release flutter build windows --release
- name: Upload exe zip - name: Copy MinGW runtime DLLs
uses: actions/upload-artifact@v6 shell: msys2 {0}
with: run: |
name: windows-portable cp /mingw64/bin/libgcc_s_seh-1.dll build/windows/x64/runner/Release/
path: build/windows/x64/runner/Release/ cp /mingw64/bin/libwinpthread-1.dll build/windows/x64/runner/Release/
cp /mingw64/bin/libstdc++-6.dll build/windows/x64/runner/Release/
- name: Install Inno Setup - name: Install Inno Setup
run: choco install innosetup -y run: choco install innosetup -y

1
.gitmodules vendored
View file

@ -1,4 +1,3 @@
[submodule "gomuks"] [submodule "gomuks"]
path = gomuks path = gomuks
url = https://github.com/gomuks/gomuks url = https://github.com/gomuks/gomuks
branch = main

View file

@ -4,7 +4,7 @@
# This file should be version controlled and should not be manually edited. # This file should be version controlled and should not be manually edited.
version: version:
revision: "nixpkgs000000000000000000000000000000000" revision: "6b182d2c7585eba26d4edce0f97630effd256c33"
channel: "stable" channel: "stable"
project_type: app project_type: app
@ -13,11 +13,11 @@ project_type: app
migration: migration:
platforms: platforms:
- platform: root - platform: root
create_revision: nixpkgs000000000000000000000000000000000 create_revision: 6b182d2c7585eba26d4edce0f97630effd256c33
base_revision: nixpkgs000000000000000000000000000000000 base_revision: 6b182d2c7585eba26d4edce0f97630effd256c33
- platform: windows - platform: ios
create_revision: nixpkgs000000000000000000000000000000000 create_revision: 6b182d2c7585eba26d4edce0f97630effd256c33
base_revision: nixpkgs000000000000000000000000000000000 base_revision: 6b182d2c7585eba26d4edce0f97630effd256c33
# User provided section # User provided section

17
.vscode/launch.json vendored Normal file
View file

@ -0,0 +1,17 @@
{
"configurations": [
{
"name": "Flutter",
"type": "dart",
"request": "launch",
"program": "lib/main.dart"
},
{
"name": "Flutter (Headless)",
"type": "dart",
"request": "launch",
"program": "lib/main.dart",
"env": { "FLUTTER_HEADLESS": "1" }
}
]
}

View file

@ -5,8 +5,14 @@
"fluttertagger", "fluttertagger",
"Gomuks", "Gomuks",
"Homeserver", "Homeserver",
"Linkified",
"localpart", "localpart",
"msgtype",
"muks", "muks",
"prefs" "prefs",
"unban",
"unifiedpush",
"unredact",
"webpush"
] ]
} }

70
DEVELOPMENT.md Normal file
View file

@ -0,0 +1,70 @@
# Development Documentation
## Build instructions
Build instructions can be found in [README.md](./README.md#build-it-yourself).
## Updating Gomuks
You can run the following command to update the Gomuks submodule:
```sh
git submodule update --remote
```
## Code Style
See [Effective Dart: Style](https://dart.dev/effective-dart/style) for general rules. There are some extra rules detailed below:
### Controllers and Helpers ([Riverpod](https://pub.dev/packages/riverpod))
Controllers live in `lib/controllers/` and provide a source that exposes data and logic via Riverpod providers, allowing other parts of the code to watch state changes with ref.watch (`ref.watch(MyController.provider)`), access the current value with ref.read (`ref.read(MyController.provider)`), and run helper methods on those classes using the notifier:
```dart
ref.read(MyController.provider.notifier).helperMethod()
```
We use an object oriented style for controllers, where `provider` is a static member on the controller class. E.g.
```dart
class MyController extends AsyncNotifier<DataThisControllerExposes> {
final SomeInputType input;
MyController(this.input);
@override
Future<DataThisControllerExposes> build() async {
return input.foo;
}
static final provider =
AsyncNotifierProvider.family<MyController, DataThisControllerExposes, SomeInputType>(
AuthorController.new,
);
}
```
Providers which are not controllers, e.g. they expose no data, only methods, should instead live in `lib/helpers/`. For an example, see `lib/helpers/launch_helper.dart`. Other, non-provider helpers, like extensions or helper methods can also go in `lib/helpers/`.
### Don't use StatefulWidgets ([Flutter Hooks](https://pub.dev/packages/flutter_hooks))
This project uses Flutter Hooks to help with boilerplate that StatefulWidgets create. Instead of using a StatefulWidget, we just use hooks like `useState` or `useEffect` in the build method of a `HookWidget`, which is a drop in replacement for `StatelessWidget`. If you need both a `WidgetRef` to watch providers, and access to hooks, use `HookConsumerWidget`.
### Models ([Freezed](https://pub.dev/packages/freezed))
We use Freezed for our models to avoid boilerplate and enforce an immutable style of state and data modeling throughout the code. See their documentation for more info, or see our existing models in `lib/models/`.
### Immutable Data Collections ([Fast Immutable Collections](https://pub.dev/packages/fast_immutable_collections))
When possible, use immutable collections instead of the mutable equivalent. For example, use `IMap` over `Map`, `IList` over `List`, `ISet` over `Set`. This matches the immutable style of Riverpod and Freezed.
### Don't create globals
When possible, we prefer not to create global variables or methods. You can usually replace a global variable with a Riverpod controller, and a global method with an extension method.
## LLM/AI Assisted Contributions
LLM generated code is NOT allowed. All contributions should be written by humans. Using LLMs for interacting with others, e.g. for Comments, PRs, etc, is also not allowed.
## Code of Conduct
All contributions must follow the [Federated Nexus Code of Conduct](https://federated.nexus/code/).

140
README.md
View file

@ -15,21 +15,19 @@ A simple and user-friendly Matrix client made with Flutter and a Gomuks backend.
## Progress ## Progress
- [ ] New logo - [x] Platform Support
- [ ] Make context menus appear as bottom sheets on mobile
- [x] Move from the Dart SDK to the Gomuks Backend with Dart bindings: https://git.federated.nexus/Henry-Hiles/nexus/pulls/2
- [ ] Allow using remote Gomuks over websocket
- [ ] Platform Support
- [x] Linux - [x] Linux
- [ ] Windows (WIP) - [x] Windows
- [ ] MacOS - Currently has some bugs, due to us not having any developers on Windows. If you want to fix these, get in contact with us though the [Nexus Client Matrix room](https://matrix.to/#/#nexus:federated.nexus).
- [x] Android - [x] Android
- [ ] iOS - [x] MacOS
- [x] Unsigned .ipa
- [ ] App Store
- [x] iOS
- [x] Unsigned .ipa
- [ ] App Store
- [ ] Web (may not be possible) - [ ] Web (may not be possible)
- [x] Login - [x] Login (via OAuth)
- [x] Username / password auth
- [ ] OAuth / OIDC
- [x] Improve initial sync experience
- [x] Rooms / Spaces - [x] Rooms / Spaces
- [x] Displaying and choosing - [x] Displaying and choosing
- [x] Reading, showing unread - [x] Reading, showing unread
@ -43,7 +41,7 @@ A simple and user-friendly Matrix client made with Flutter and a Gomuks backend.
- [x] `matrix:` Uri - [x] `matrix:` Uri
- [x] Matrix.to link - [x] Matrix.to link
- [ ] From space - [ ] From space
- [ ] Exploring - [ ] From directory
- [x] Leaving - [x] Leaving
- [x] Subspaces - [x] Subspaces
- [x] Messages - [x] Messages
@ -54,13 +52,13 @@ A simple and user-friendly Matrix client made with Flutter and a Gomuks backend.
- [x] HTML/Markdown - [x] HTML/Markdown
- [x] Replies - [x] Replies
- [x] Choose ping on/off - [x] Choose ping on/off
- [ ] Per message profiles - [x] Per message profiles
- [ ] Attachments - [x] Attachments
- [ ] Commands with [MSC4391](https://github.com/matrix-org/matrix-spec-proposals/pull/4391) - [ ] Commands with [MSC4391](https://github.com/matrix-org/matrix-spec-proposals/pull/4391)
- [x] Mentions - [x] Tags
- [x] Users - [x] Users
- [x] Rooms - [x] Rooms
- [ ] Inline emoji picker (Putting this here since it'll be implemented the same way as mentions) - [x] Emojis
- [ ] Custom emojis/stickers - [ ] Custom emojis/stickers
- [ ] GIFs using Gomuks' GIF proxies - [ ] GIFs using Gomuks' GIF proxies
- [x] Receiving - [x] Receiving
@ -70,13 +68,11 @@ A simple and user-friendly Matrix client made with Flutter and a Gomuks backend.
- [x] URL Previews - [x] URL Previews
- [x] Replies - [x] Replies
- [x] Viewing - [x] Viewing
- [ ] Jump to original message - [x] Jump to original message
- [x] In loaded timeline
- [ ] Out of loaded timeline
- [x] Edits - [x] Edits
- [x] Attachments - [x] Attachments
- [x] Unencrypted - [x] Unencrypted
- [ ] Encrypted - [x] Encrypted
- [x] Blurhashing - [x] Blurhashing
- [ ] Downloading attachments - [ ] Downloading attachments
- [x] Opening attachments in their own view - [x] Opening attachments in their own view
@ -85,7 +81,7 @@ A simple and user-friendly Matrix client made with Flutter and a Gomuks backend.
- [x] Users - [x] Users
- [x] Clickable - [x] Clickable
- [x] Rooms - [x] Rooms
- [x] Clickable - [ ] Clickable
- [x] Matrix URIs - [x] Matrix URIs
- [x] Matrix.to links - [x] Matrix.to links
- [x] Events - [x] Events
@ -93,14 +89,12 @@ A simple and user-friendly Matrix client made with Flutter and a Gomuks backend.
- [ ] Clickable - [ ] Clickable
- [x] Custom emojis/stickers - [x] Custom emojis/stickers
- [x] History loading - [x] History loading
- [x] Backwards
- [ ] Forwards
- [x] Editing - [x] Editing
- [x] Deleting - [x] Deleting
- [x] Reactions - [x] Reactions
- [ ] Pins - [x] Pins
- [ ] Displaying - [x] Displaying
- [ ] Creating - [x] Pinning/Unpinning
- [ ] Threads - [ ] Threads
- [x] Profile popouts - [x] Profile popouts
- [x] Working actions - [x] Working actions
@ -111,41 +105,27 @@ A simple and user-friendly Matrix client made with Flutter and a Gomuks backend.
- [ ] Reporting - [ ] Reporting
- [x] Events - [x] Events
- [ ] Rooms - [ ] Rooms
- [ ] Notifications using UnifiedPush - [x] Member list
- [x] Sort by power level
- [ ] Colors based off of power level
- [x] Notifications using UnifiedPush ([#35](https://git.federated.nexus/Nexus/nexus/issues/35))
- [x] Notifications page
- [ ] Group calls using [MSC4195](https://github.com/matrix-org/matrix-spec-proposals/pull/4195) - [ ] Group calls using [MSC4195](https://github.com/matrix-org/matrix-spec-proposals/pull/4195)
- [ ] Invites - [ ] Invites
- [ ] Settings - [x] Settings
- [ ] Matrix: URIs vs Matrix.to links
- [ ] Light/Dark mode
- [ ] SSD or CSD
- [ ] Show media by default
- [ ] Dynamic Theming
- [ ] Devices
- [ ] Viewing devices
- [ ] Verifying devices
- [ ] URL preview: Server / Sending Client (Beeper spec) / None
- [ ] Account changes
- [ ] Display name
- [ ] Profile picture
- [ ] Timezone
- [ ] Pronouns
- [ ] Password
- [ ] About
- [x] Log Out
## Try it out ## Try it out
If you want to try out Nexus, grab one of the following artifacts from CI: If you want to try out Nexus, grab one of the following artifacts from CI:
- [Android APK](https://nightly.link/Henry-Hiles/nexus/workflows/android/main/APK.zip) - [Android APK](https://nightly.link/Henry-Hiles/nexus/workflows/android/main/APK.zip)
- Windows - [Unsigned iOS IPA](https://nightly.link/Henry-Hiles/nexus/workflows/ios/main/Nexus.ipa.zip)
- [Portable Build](https://nightly.link/Henry-Hiles/nexus/workflows/windows/main/windows-portable.zip) - [Unsigned MacOS DMG](https://nightly.link/Henry-Hiles/nexus/workflows/macos/main/nexus.dmg.zip)
- [Installer](https://nightly.link/Henry-Hiles/nexus/workflows/windows/main/windows-installer.zip) - [Windows EXE](https://nightly.link/Henry-Hiles/nexus/workflows/windows/main/windows-installer.zip)
- Flatpak - Flatpak
- [AArch64/Arm64](https://nightly.link/Henry-Hiles/nexus/workflows/flatpak/main/flatpak-aarch64.zip) - [AArch64/Arm64](https://nightly.link/Henry-Hiles/nexus/workflows/flatpak/main/flatpak-aarch64.zip)
- [x86_64/AMD64](https://nightly.link/Henry-Hiles/nexus/workflows/flatpak/main/flatpak-x86_64.zip) - [x86_64/AMD64](https://nightly.link/Henry-Hiles/nexus/workflows/flatpak/main/flatpak-x86_64.zip)
- [NixOS Module](linux/nix/module.nix)
Or, try the Nix package: `nix run git+https://git.federated.nexus/Henry-Hiles/nexus`
## Build it yourself ## Build it yourself
@ -153,19 +133,43 @@ Or, try the Nix package: `nix run git+https://git.federated.nexus/Henry-Hiles/ne
#### Linux #### Linux
- With Nix: Either use direnv and `direnv allow`, or `nix flake develop` - On NixOS: Either use direnv and `direnv allow`, or `nix flake develop`
- Without Nix: Install Flutter, Go, Git, Libclang, and Glibc. Do not use any Snap packages, they cause various compilation issues. - On other distros: Install Flutter, Go, Git, Libclang, Libass, MPV, and Glibc. Do not use any Snap packages, they cause various compilation issues.
#### Windows / MacOS #### Windows
I don't really know. You will need Flutter, Git, Go, and Visual Studio tools, and otherwise I guess just keep installing stuff until there aren't any errors. I will look into this sometimeTM. You will need:
- Flutter
- Git
- Libass
- MPV
- Go
- Visual Studio 2022 (Desktop development with C++)
- [MSYS2/MinGW-w64 GCC](https://www.msys2.org/) (for CGO)
- [LLVM/Clang + libclang](https://clang.llvm.org/get_started.html) (for `ffigen`)
On Windows, make sure these are available in your shell `PATH`:
- `C:\msys64\ucrt64\bin` (or your MinGW bin path containing `x86_64-w64-mingw32-gcc.exe`)
- `C:\Program Files\LLVM\bin` (contains `clang.exe` and `libclang.dll`)
For `dart scripts/generate.dart`, you may also need:
```powershell
$env:CPATH = "C:\msys64\ucrt64\include"
```
#### MacOS
Similar prerequisites apply (Flutter, Git, Go, C toolchain, LLVM/libclang), but exact setup has not been fully documented yet.
### Clone repo ### Clone repo
First, clone and open the repo: First, clone and open the repo:
```sh ```sh
git clone --recurse-submodules https://git.federated.nexus/Henry-Hiles/nexus git clone --recurse-submodules https://git.federated.nexus/Nexus/nexus
cd nexus cd nexus
``` ```
@ -183,10 +187,23 @@ Generate Gomuks bindings:
dart scripts/generate.dart dart scripts/generate.dart
``` ```
> [!NOTE]
> If you are having issues with `stddef.h` not being found, try setting CPATH manually:
>
> ```sh
> export CPATH="$(clang -v 2>&1 | grep "Selected GCC installation" | rev | cut -d' ' -f1 | rev)/include"
> ```
Build webcrypto:
```sh
flutter pub run webcrypto:setup
```
Build generated files, and watch for new changes: Build generated files, and watch for new changes:
```sh ```sh
flutter pub run build_runner watch --delete-conflicting-outputs flutter pub run build_runner watch
``` ```
Run the app: Run the app:
@ -195,6 +212,13 @@ Run the app:
flutter run flutter run
``` ```
Development instructions can be found in [DEVELOPMENT.md](./DEVELOPMENT.md).
## Community ## Community
Join the [Nexus Client Matrix Room](https://matrix.to/#/#nexus:federated.nexus) for questions or help with developing or using Nexus Client. Join the [Nexus Client Matrix room](https://matrix.to/#/#nexus:federated.nexus) for questions or help with developing or using Nexus Client.
# Credits
Thank you Hylke Bons (https://planetpeanut.studio) for making the amazing icon for Nexus!
Thank you Tulir Asokan for making [Gomuks](https://github.com/gomuks/gomuks), and helping us integrate it into Nexus!

22
altstore-source.json Normal file
View file

@ -0,0 +1,22 @@
{
"name": "Nexus",
"identifier": "nexus.federated.nexus.source",
"subtitle": "Nexus for iOS",
"description": "Nexus iOS builds for AltStore and SideStore.",
"iconURL": "https://git.federated.nexus/Nexus/nexus/raw/branch/main/assets/icon.png",
"website": "https://git.federated.nexus/Nexus/nexus",
"apps": [
{
"name": "Nexus",
"bundleIdentifier": "nexus.federated.nexus",
"developerName": "Nexus",
"subtitle": "A Matrix client",
"localizedDescription": "Nexus for iOS. Unsigned builds, resigned at install by AltStore/SideStore.",
"iconURL": "https://git.federated.nexus/Nexus/nexus/raw/branch/main/assets/icon.png",
"category": "social",
"screenshots": [],
"versions": []
}
],
"news": []
}

View file

@ -6,6 +6,12 @@ analyzer:
- "build/**" - "build/**"
- "**/*.g.dart" - "**/*.g.dart"
- "**/*.freezed.dart" - "**/*.freezed.dart"
- android/**
- ios/**
- web/**
- windows/**
- macos/**
- linux/**
include: package:flutter_lints/flutter.yaml include: package:flutter_lints/flutter.yaml
linter: linter:
rules: rules:

View file

@ -1,78 +0,0 @@
plugins {
id "com.android.application"
id "kotlin-android"
// The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
id "dev.flutter.flutter-gradle-plugin"
}
def localProperties = new Properties()
def localPropertiesFile = rootProject.file("local.properties")
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader("UTF-8") { reader ->
localProperties.load(reader)
}
}
def flutterVersionCode = localProperties.getProperty("flutter.versionCode")
if (flutterVersionCode == null) {
flutterVersionCode = "1"
}
def flutterVersionName = localProperties.getProperty("flutter.versionName")
if (flutterVersionName == null) {
flutterVersionName = "1.0"
}
def keystoreProperties = new Properties()
def keystorePropertiesFile = rootProject.file('key.properties')
if (keystorePropertiesFile.exists()) {
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
}
android {
namespace = "nexus.federated.Nexus"
ndkVersion = flutter.ndkVersion
compileSdk = 34
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
kotlinOptions {
// do we want to update.. eventually?
jvmTarget = "17"
}
defaultConfig {
applicationId = "nexus.federated.Nexus"
minSdk = 29
targetSdkVersion flutter.targetSdkVersion
versionCode = flutterVersionCode.toInteger()
versionName = flutterVersionName
}
signingConfigs {
release {
keyAlias "key"
def storePath = keystoreProperties['path'] ?: System.getenv("KEYSTORE_PATH")
storeFile storePath ? file(storePath) : null
keyPassword keystoreProperties['password'] ?: System.getenv("KEYSTORE_PASSWORD")
storePassword keystoreProperties['password'] ?: System.getenv("KEYSTORE_PASSWORD")
}
}
buildTypes {
release {
signingConfig signingConfigs.release
}
debug {
applicationIdSuffix = ".debug"
}
}
}
flutter {
source = "../.."
}

View file

@ -0,0 +1,84 @@
import java.util.Properties
plugins {
id("com.android.application")
id("dev.flutter.flutter-gradle-plugin")
}
val keystoreProperties = Properties()
val keystorePropertiesFile = rootProject.file("key.properties")
if (keystorePropertiesFile.exists()) {
keystorePropertiesFile.inputStream().use {
keystoreProperties.load(it)
}
}
android {
namespace = "nexus.federated.nexus"
compileSdk = 36
ndkVersion = flutter.ndkVersion
compileOptions {
isCoreLibraryDesugaringEnabled = true
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
}
defaultConfig {
applicationId = "nexus.federated.nexus"
minSdk = 29
targetSdk = flutter.targetSdkVersion
versionCode = flutter.versionCode
versionName = flutter.versionName
multiDexEnabled = true
}
signingConfigs {
create("release") {
keyAlias = "key"
val storePath =
keystoreProperties["path"]?.toString()
?: System.getenv("KEYSTORE_PATH")
storeFile = storePath?.let { file(it) }
keyPassword =
keystoreProperties["password"]?.toString()
?: System.getenv("KEYSTORE_PASSWORD")
storePassword =
keystoreProperties["password"]?.toString()
?: System.getenv("KEYSTORE_PASSWORD")
}
}
buildTypes {
release {
signingConfig = signingConfigs.getByName("release")
}
debug {
applicationIdSuffix = ".debug"
}
}
}
dependencies {
implementation("org.unifiedpush.android:embedded-fcm-distributor:3.1.0")
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.1.4")
}
kotlin {
compilerOptions {
jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_21
}
}
flutter {
source = "../.."
}

View file

@ -22,6 +22,14 @@
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true" android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize"> android:windowSoftInputMode="adjustResize">
<meta-data android:name="flutter_deeplinking_enabled" android:value="false" />
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="nexus.federated.nexus" />
</intent-filter>
<meta-data <meta-data
android:name="io.flutter.embedding.android.NormalTheme" android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme" android:resource="@style/NormalTheme"

View file

@ -1,4 +1,4 @@
package nexus.federated.Nexus package nexus.federated.nexus
import io.flutter.embedding.android.FlutterActivity import io.flutter.embedding.android.FlutterActivity

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

Before After
Before After

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Before After
Before After

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.7 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

Before After
Before After

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 7.4 KiB

Before After
Before After

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Before After
Before After

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

View file

@ -6,4 +6,9 @@
android:drawable="@drawable/ic_launcher_foreground" android:drawable="@drawable/ic_launcher_foreground"
android:inset="16%" /> android:inset="16%" />
</foreground> </foreground>
<monochrome>
<inset
android:drawable="@drawable/ic_launcher_monochrome"
android:inset="16%" />
</monochrome>
</adaptive-icon> </adaptive-icon>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.9 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 9.8 KiB

Before After
Before After

View file

@ -1,26 +0,0 @@
allprojects {
repositories {
google()
mavenCentral()
}
}
rootProject.buildDir = "../build"
subprojects {
project.buildDir = "${rootProject.buildDir}/${project.name}"
afterEvaluate {project ->
if (project.hasProperty("android")) {
android {
compileSdkVersion 36
buildToolsVersion '33.0.1'
}
}
}
project.evaluationDependsOn(":app")
}
tasks.register("clean", Delete) {
delete rootProject.buildDir
}

25
android/build.gradle.kts Normal file
View file

@ -0,0 +1,25 @@
allprojects {
repositories {
google()
mavenCentral()
}
}
val newBuildDir: Directory =
rootProject.layout.buildDirectory
.dir("../../build")
.get()
rootProject.layout.buildDirectory.value(newBuildDir)
subprojects {
val newSubprojectBuildDir: Directory = newBuildDir.dir(project.name)
project.layout.buildDirectory.value(newSubprojectBuildDir)
}
subprojects {
project.evaluationDependsOn(":app")
}
tasks.register<Delete>("clean") {
delete(rootProject.layout.buildDirectory)
}

View file

@ -1,3 +1,7 @@
org.gradle.jvmargs=-Xmx4G -XX:+HeapDumpOnOutOfMemoryError org.gradle.jvmargs=-Xmx4G -XX:+HeapDumpOnOutOfMemoryError
android.useAndroidX=true android.useAndroidX=true
android.enableJetifier=true android.enableJetifier=true
# This builtInKotlin flag was added automatically by Flutter migrator
android.builtInKotlin=false
# This newDsl flag was added automatically by Flutter migrator
android.newDsl=false

View file

@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-9.6.0-all.zip

View file

@ -1,25 +0,0 @@
pluginManagement {
def flutterSdkPath = {
def properties = new Properties()
file("local.properties").withInputStream { properties.load(it) }
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
return flutterSdkPath
}()
includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}
plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version "8.13.0" apply false
id "org.jetbrains.kotlin.android" version "2.2.20" apply false
}
include ":app"

View file

@ -0,0 +1,26 @@
pluginManagement {
val flutterSdkPath =
run {
val properties = java.util.Properties()
file("local.properties").inputStream().use { properties.load(it) }
val flutterSdkPath = properties.getProperty("flutter.sdk")
require(flutterSdkPath != null) { "flutter.sdk not set in local.properties" }
flutterSdkPath
}
includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}
plugins {
id("dev.flutter.flutter-plugin-loader") version "1.0.0"
id("com.android.application") version "9.3.1" apply false
id("org.jetbrains.kotlin.android") version "2.4.10" apply false
}
include(":app")

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Before After
Before After

View file

@ -1,21 +1,22 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg <svg
width="100mm" width="512"
height="100mm" height="512"
viewBox="0 0 100 100" viewBox="0 0 512 512"
fill="none"
version="1.1" version="1.1"
id="svg1" id="svg11"
xml:space="preserve"
inkscape:version="1.4.3 (0d15f75042, 2025-12-25)"
sodipodi:docname="background.svg" sodipodi:docname="background.svg"
inkscape:version="1.4.3 (0d15f75042, 2025-12-25)"
inkscape:export-filename="background.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview xmlns:svg="http://www.w3.org/2000/svg">
id="namedview1" <sodipodi:namedview
id="namedview11"
pagecolor="#505050" pagecolor="#505050"
bordercolor="#eeeeee" bordercolor="#eeeeee"
borderopacity="1" borderopacity="1"
@ -23,40 +24,234 @@
inkscape:pageopacity="0" inkscape:pageopacity="0"
inkscape:pagecheckerboard="0" inkscape:pagecheckerboard="0"
inkscape:deskcolor="#505050" inkscape:deskcolor="#505050"
inkscape:document-units="mm" inkscape:zoom="0.69191503"
inkscape:zoom="1.0847363" inkscape:cx="-71.540576"
inkscape:cx="57.156749" inkscape:cy="281.10388"
inkscape:cy="214.33781" inkscape:window-width="2544"
inkscape:window-width="1904" inkscape:window-height="1363"
inkscape:window-height="971"
inkscape:window-x="35" inkscape:window-x="35"
inkscape:window-y="32" inkscape:window-y="32"
inkscape:window-maximized="0" inkscape:window-maximized="0"
inkscape:current-layer="layer1" /><defs inkscape:current-layer="svg11" />
id="defs1"><linearGradient <defs
id="linearGradient10" id="defs11">
inkscape:collect="always"><stop <radialGradient
style="stop-color:#c7a312;stop-opacity:1;" id="paint0_radial_4033_8"
offset="0" cx="0"
id="stop10" /><stop cy="0"
style="stop-color:#26a0b3;stop-opacity:1;" r="1"
gradientTransform="matrix(3.5,24.5214,-15.8099,2.26053,80,52.9904)"
gradientUnits="userSpaceOnUse">
<stop
stop-color="#72AAEE"
id="stop10" />
<stop
offset="1" offset="1"
id="stop11" /></linearGradient><linearGradient stop-color="#3584E4"
inkscape:collect="always" id="stop11" />
xlink:href="#linearGradient10" </radialGradient>
id="linearGradient11" <mask
x1="20.031296" id="mask0_4033_8"
y1="32.697563" maskUnits="userSpaceOnUse"
x2="90.709213" x="56"
y2="66.3423" y="46"
gradientUnits="userSpaceOnUse" /></defs><g width="21"
inkscape:label="Layer 1" height="36">
inkscape:groupmode="layer" <path
id="layer1"><rect d="m 76.4223,63.1501 c 0.3482,0.5123 0.3457,1.1859 -0.0063,1.6956 L 65.0175,81.3524 C 64.7375,81.7579 64.2761,82 63.7832,82 h -5.9804 c -1.1981,0 -1.9127,-1.3352 -1.2481,-2.332 l 9.8906,-14.8359 c 0.3359,-0.5039 0.3359,-1.1603 0,-1.6641 L 57.0729,49.1094 C 56.1869,47.7803 57.1396,46 58.737,46 h 5.2334 c 0.4967,0 0.9613,0.2459 1.2405,0.6568 z"
style="fill:url(#linearGradient11);fill-opacity:1;stroke:none;stroke-width:7.99999;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none" fill="#2779dd"
id="rect10" id="path9" />
width="100" </mask>
height="100" <clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath11">
<rect
width="128"
height="128"
fill="#ffffff"
id="rect12"
x="0" x="0"
y="0" y="0"
ry="28.294127" /></g></svg> transform="rotate(-30)" />
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath12">
<rect
width="128"
height="128"
fill="#ffffff"
id="rect13"
x="0"
y="0"
transform="rotate(-30)" />
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath13">
<rect
width="128"
height="128"
fill="#ffffff"
id="rect14"
x="0"
y="0"
transform="rotate(-30)" />
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath14">
<rect
width="128"
height="128"
fill="#ffffff"
id="rect15"
x="0"
y="0"
transform="rotate(-30)" />
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath15">
<rect
width="128"
height="128"
fill="#ffffff"
id="rect16"
x="0"
y="0"
transform="rotate(-30)" />
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath16">
<rect
width="128"
height="128"
fill="#ffffff"
id="rect17"
x="0"
y="0"
transform="rotate(-30)" />
</clipPath>
<radialGradient
id="paint0_radial_4033_8-3"
cx="0"
cy="0"
r="1"
gradientTransform="matrix(3.5,24.5214,-15.8099,2.26053,174.26633,65.9904)"
gradientUnits="userSpaceOnUse">
<stop
stop-color="#72AAEE"
id="stop10-6" />
<stop
offset="1"
stop-color="#3584E4"
id="stop11-7" />
</radialGradient>
<radialGradient
id="paint0_radial_4033_8-35"
cx="0"
cy="0"
r="1"
gradientTransform="matrix(3.5,24.5214,-15.8099,2.26053,80,52.9904)"
gradientUnits="userSpaceOnUse">
<stop
stop-color="#72AAEE"
id="stop10-62" />
<stop
offset="1"
stop-color="#3584E4"
id="stop11-9" />
</radialGradient>
<mask
id="mask0_4033_8-1"
maskUnits="userSpaceOnUse"
x="56"
y="46"
width="21"
height="36">
<path
d="m 76.4223,63.1501 c 0.3482,0.5123 0.3457,1.1859 -0.0063,1.6956 L 65.0175,81.3524 C 64.7375,81.7579 64.2761,82 63.7832,82 h -5.9804 c -1.1981,0 -1.9127,-1.3352 -1.2481,-2.332 l 9.8906,-14.8359 c 0.3359,-0.5039 0.3359,-1.1603 0,-1.6641 L 57.0729,49.1094 C 56.1869,47.7803 57.1396,46 58.737,46 h 5.2334 c 0.4967,0 0.9613,0.2459 1.2405,0.6568 z"
fill="#2779dd"
id="path9-2" />
</mask>
<radialGradient
id="paint0_radial_4033_8-9"
cx="0"
cy="0"
r="1"
gradientTransform="matrix(14,98.0856,-63.2396,9.04212,320,211.9616)"
gradientUnits="userSpaceOnUse">
<stop
stop-color="#72AAEE"
id="stop10-3" />
<stop
offset="1"
stop-color="#3584E4"
id="stop11-6" />
</radialGradient>
</defs>
<rect
width="512"
height="512"
fill="#ffffff"
id="rect1"
x="0"
y="0"
style="stroke-width:4" />
<rect
x="-1.5384758"
y="-122.66472"
width="35.5569"
height="291.86301"
transform="matrix(3.4641016,2,-2,3.4641016,0,0)"
fill="#9141ac"
id="rect2"
clip-path="url(#clipPath16)" />
<rect
x="34.018467"
y="-122.66468"
width="26.6677"
height="291.86301"
transform="matrix(3.4641016,2,-2,3.4641016,0,0)"
fill="#62a0ea"
id="rect3"
clip-path="url(#clipPath15)" />
<rect
x="60.68605"
y="-122.66468"
width="26.6677"
height="291.86301"
transform="matrix(3.4641016,2,-2,3.4641016,0,0)"
fill="#57e389"
id="rect4"
clip-path="url(#clipPath14)" />
<rect
x="87.353859"
y="-122.66468"
width="26.6677"
height="291.86301"
transform="matrix(3.4641016,2,-2,3.4641016,0,0)"
fill="#f5c211"
id="rect5"
clip-path="url(#clipPath13)" />
<rect
x="114.02161"
y="-122.66477"
width="26.6677"
height="291.86301"
transform="matrix(3.4641016,2,-2,3.4641016,0,0)"
fill="#ff7800"
id="rect6"
clip-path="url(#clipPath12)" />
<rect
x="140.68942"
y="-122.66477"
width="35.5569"
height="291.86301"
transform="matrix(3.4641016,2,-2,3.4641016,0,0)"
fill="#ed333b"
id="rect7"
clip-path="url(#clipPath11)" />
</svg>

Before

Width:  |  Height:  |  Size: 2 KiB

After

Width:  |  Height:  |  Size: 6.7 KiB

Before After
Before After

334
assets/bundled/icon.svg Normal file
View file

@ -0,0 +1,334 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="512"
height="512"
viewBox="0 0 512 512"
fill="none"
version="1.1"
id="svg35"
sodipodi:docname="icon.svg"
inkscape:version="1.4.3 (0d15f75042, 2025-12-25)"
inkscape:export-filename="icon.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview35"
pagecolor="#505050"
bordercolor="#eeeeee"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#505050"
inkscape:zoom="1.321682"
inkscape:cx="69.608271"
inkscape:cy="120.67956"
inkscape:window-width="2544"
inkscape:window-height="1363"
inkscape:window-x="35"
inkscape:window-y="32"
inkscape:window-maximized="0"
inkscape:current-layer="svg35" />
<mask
id="mask0_4023_558"
maskUnits="userSpaceOnUse"
x="12"
y="100"
width="88"
height="16">
<path
d="m 100,104 c 0,6.627 -5.3726,12 -12,12 H 24 c -6.6274,0 -12,-5.373 -12,-12 v -4 c 0,6.627 5.3726,12 12,12 h 64 c 6.6274,0 12,-5.373 12,-12 z"
fill="#d9d9d9"
id="path6" />
</mask>
<mask
id="mask1_4023_558"
maskUnits="userSpaceOnUse"
x="77"
y="27"
width="21"
height="36">
<path
d="m 97.4223,44.1501 c 0.3482,0.5122 0.3457,1.1859 -0.0063,1.6956 L 86.0175,62.3523 C 85.7375,62.7579 85.2761,63 84.7832,63 h -5.9804 c -1.1981,0 -1.9127,-1.3352 -1.2481,-2.3321 l 9.8906,-14.8358 c 0.3359,-0.5039 0.3359,-1.1603 0,-1.6642 L 78.0729,30.1094 C 77.1869,28.7803 78.1396,27 79.737,27 h 5.2334 c 0.4967,0 0.9613,0.2459 1.2405,0.6567 z"
fill="#2779dd"
id="path14" />
</mask>
<g
id="g36"
transform="scale(4)">
<g
clip-path="url(#clip0_4023_558)"
id="g6">
<rect
x="62.0205"
y="-52.425598"
width="24"
height="197"
transform="rotate(30,62.0205,-52.4256)"
fill="#9141ac"
id="rect1" />
<rect
x="82.805099"
y="-40.425598"
width="18"
height="197"
transform="rotate(30,82.8051,-40.4256)"
fill="#62a0ea"
id="rect2" />
<rect
x="98.3936"
y="-31.4256"
width="18"
height="197"
transform="rotate(30,98.3936,-31.4256)"
fill="#57e389"
id="rect3" />
<rect
x="113.982"
y="-22.4256"
width="18"
height="197"
transform="rotate(30,113.982,-22.4256)"
fill="#f5c211"
id="rect4" />
<rect
x="129.57001"
y="-13.4256"
width="18"
height="197"
transform="rotate(30,129.57,-13.4256)"
fill="#ff7800"
id="rect5" />
<rect
x="145.159"
y="-4.4256301"
width="24"
height="197"
transform="rotate(30,145.159,-4.42563)"
fill="#ed333b"
id="rect6" />
</g>
<g
mask="url(#mask0_4023_558)"
id="g10">
<path
d="m 12,100 h 24 v 16 H 12 Z"
fill="url(#paint0_linear_4023_558)"
id="path7"
style="fill:url(#paint0_linear_4023_558)" />
<path
d="m 12,100 h 5 v 16 h -5 z"
fill="url(#paint1_linear_4023_558)"
id="path8"
style="fill:url(#paint1_linear_4023_558)" />
<rect
x="36"
y="100"
width="21"
height="16"
fill="#ca9005"
id="rect8" />
<rect
x="57"
y="100"
width="21"
height="16"
fill="#c64600"
id="rect9" />
<rect
x="78"
y="100"
width="22"
height="16"
fill="url(#paint2_linear_4023_558)"
id="rect10"
style="fill:url(#paint2_linear_4023_558)" />
</g>
<rect
opacity="0.2"
x="24.5"
y="110.5"
width="63"
height="1"
stroke="url(#paint3_linear_4023_558)"
id="rect11"
style="stroke:url(#paint3_linear_4023_558)" />
<path
d="m 85,4 c 22.644,0 41,18.3563 41,41 v 4 c 0,22.6437 -18.356,41 -41,41 -8.3322,0 -16.0825,-2.4875 -22.5526,-6.7576 -0.4653,-0.3071 -1.0341,-0.4203 -1.5783,-0.2987 l -8.8369,1.9749 C 52.0134,84.9228 52,84.9395 52,84.9588 52,84.9816 51.9816,85 51.9588,85 h -0.4617 c -0.0787,0.0036 -0.1564,0.004 -0.2334,0 H 51 c -1.1046,0 -2,-0.8954 -2,-2 v -0.2617 c -0.0043,-0.0811 -0.0042,-0.1632 0,-0.2461 V 78.9749 C 49,78.7126 49.2126,78.5 49.4749,78.5 c 0.2224,0 0.4151,-0.1543 0.4635,-0.3714 l 1.117,-4.9987 C 51.177,72.5857 51.0638,72.017 50.7567,71.5517 46.487,65.0818 44,57.3317 44,49 V 45 C 44,22.3563 62.3563,4 85,4 Z"
fill="url(#paint4_linear_4023_558)"
id="path11"
style="fill:url(#paint4_linear_4023_558)" />
<path
d="m 85,4 c 22.644,0 41,18.3563 41,41 0,22.6437 -18.356,41 -41,41 -8.6457,0 -16.6648,-2.6781 -23.2773,-7.2471 l -9.8018,2.1914 c -1.7167,0.3836 -3.2488,-1.1485 -2.8652,-2.8652 l 2.1904,-9.8027 C 46.6776,61.6641 44,53.6452 44,45 44,22.3563 62.3563,4 85,4 Z"
fill="#ffffff"
id="path12" />
<path
d="m 97.2297,43.8668 c 0.4642,0.683 0.4609,1.5812 -0.0083,2.2608 L 86.1666,62.1365 C 85.7932,62.6772 85.178,63 84.5209,63 H 79.737 c -1.5974,0 -2.5502,-1.7803 -1.6641,-3.1094 l 9.1875,-13.7812 c 0.4478,-0.6718 0.4478,-1.547 0,-2.2188 L 78.0729,30.1094 C 77.1868,28.7803 78.1396,27 79.737,27 h 4.9687 c 0.6623,0 1.2817,0.3279 1.654,0.8757 z"
fill="url(#paint5_radial_4023_558)"
id="path13"
style="fill:url(#paint5_radial_4023_558)" />
<g
mask="url(#mask1_4023_558)"
id="g14">
<rect
x="73"
y="27"
width="17"
height="4"
fill="#2779dd"
id="rect14" />
</g>
</g>
<defs
id="defs35">
<linearGradient
id="paint0_linear_4023_558"
x1="34"
y1="108"
x2="12"
y2="108"
gradientUnits="userSpaceOnUse">
<stop
offset="0.401381"
stop-color="#26A269"
id="stop14" />
<stop
offset="0.801049"
stop-color="#8AEB52"
id="stop15" />
<stop
offset="1"
stop-color="#26A269"
id="stop16" />
</linearGradient>
<linearGradient
id="paint1_linear_4023_558"
x1="12"
y1="108"
x2="17"
y2="108"
gradientUnits="userSpaceOnUse">
<stop
stop-color="#1A5FB4"
id="stop17" />
<stop
offset="1"
stop-color="#35E0F6"
id="stop18" />
</linearGradient>
<linearGradient
id="paint2_linear_4023_558"
x1="100"
y1="108"
x2="78"
y2="108"
gradientUnits="userSpaceOnUse">
<stop
stop-color="#A51D2D"
id="stop19" />
<stop
offset="0.195858"
stop-color="#E5673C"
id="stop20" />
<stop
offset="0.5983"
stop-color="#A51D2D"
id="stop21" />
</linearGradient>
<linearGradient
id="paint3_linear_4023_558"
x1="88"
y1="111.329"
x2="24"
y2="111.329"
gradientUnits="userSpaceOnUse">
<stop
offset="0.102371"
stop-color="white"
stop-opacity="0"
id="stop22" />
<stop
offset="0.253808"
stop-color="white"
id="stop23" />
<stop
offset="0.747697"
stop-color="white"
id="stop24" />
<stop
offset="0.895556"
stop-color="white"
stop-opacity="0"
id="stop25" />
</linearGradient>
<linearGradient
id="paint4_linear_4023_558"
x1="44"
y1="48.036098"
x2="126"
y2="48.036098"
gradientUnits="userSpaceOnUse">
<stop
stop-color="#DBEBF4"
id="stop26" />
<stop
offset="0.147387"
stop-color="#B1D4E7"
id="stop27" />
<stop
offset="0.186621"
stop-color="#8DC0DC"
id="stop28" />
<stop
offset="0.203755"
stop-color="#49AEE7"
id="stop29" />
<stop
offset="0.276122"
stop-color="#7AB5D7"
id="stop30" />
<stop
offset="0.399628"
stop-color="#B3D6E7"
id="stop31" />
<stop
offset="0.507537"
stop-color="#B3D6E7"
id="stop32" />
<stop
offset="1"
stop-color="#DBEBF4"
id="stop33" />
</linearGradient>
<radialGradient
id="paint5_radial_4023_558"
cx="0"
cy="0"
r="1"
gradientTransform="matrix(3.5,24.5214,-15.8099,2.26053,101,33.9904)"
gradientUnits="userSpaceOnUse">
<stop
stop-color="#72AAEE"
id="stop34" />
<stop
offset="1"
stop-color="#3584E4"
id="stop35" />
</radialGradient>
<clipPath
id="clip0_4023_558">
<rect
x="12"
y="36"
width="88"
height="80"
rx="12"
fill="#ffffff"
id="rect35" />
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

BIN
assets/fonts/Roboto.ttf Normal file

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Before After
Before After

View file

@ -1,20 +1,19 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg <svg
width="100mm" width="512"
height="100mm" height="512"
viewBox="0 0 100 100" viewBox="0 0 512 512"
fill="none"
version="1.1" version="1.1"
id="svg1" id="svg11"
xml:space="preserve" sodipodi:docname="foreground.svg"
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)" inkscape:version="1.4.3 (0d15f75042, 2025-12-25)"
sodipodi:docname="nexus.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview xmlns:svg="http://www.w3.org/2000/svg">
id="namedview1" <sodipodi:namedview
id="namedview11"
pagecolor="#505050" pagecolor="#505050"
bordercolor="#eeeeee" bordercolor="#eeeeee"
borderopacity="1" borderopacity="1"
@ -22,105 +21,137 @@
inkscape:pageopacity="0" inkscape:pageopacity="0"
inkscape:pagecheckerboard="0" inkscape:pagecheckerboard="0"
inkscape:deskcolor="#505050" inkscape:deskcolor="#505050"
inkscape:document-units="mm" inkscape:zoom="0.87695313"
inkscape:zoom="1.0847363" inkscape:cx="152.23163"
inkscape:cx="58.07863" inkscape:cy="347.22494"
inkscape:cy="214.3378" inkscape:window-width="2544"
inkscape:window-width="1896" inkscape:window-height="1363"
inkscape:window-height="987"
inkscape:window-x="35" inkscape:window-x="35"
inkscape:window-y="32" inkscape:window-y="32"
inkscape:window-maximized="0" inkscape:window-maximized="0"
inkscape:current-layer="layer1" /><defs inkscape:current-layer="svg11" />
id="defs1" /><g <path
inkscape:label="Layer 1" d="m 256,92 c 90.5748,0 164,73.4252 164,164 0,90.5748 -73.4252,164 -164,164 -34.5828,0 -66.6592,-10.712 -93.1092,-28.9884 l -39.2072,8.7656 c -6.8668,1.5348 -12.9952,-4.594 -11.4608,-11.4608 l 8.7616,-39.2108 C 102.7104,322.6564 92,290.5808 92,256 92,165.4252 165.4252,92 256,92 Z"
inkscape:groupmode="layer" fill="#ffffff"
id="layer1"><path
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:8;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none"
d="M 19.377906,68.106953 80.937684,32.43771"
id="path10" /><path
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:8;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none"
d="m 19.044488,32.469148 61.61782,35.569625"
id="path9" /><path
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:8;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none"
d="M 50,85.574911 V 14.425087"
id="path8" /><circle
style="fill:none;stroke:#ffffff;stroke-width:7.11498;stroke-linecap:round;stroke-linejoin:round"
id="path1"
cx="50"
cy="50"
r="35.574913" /><circle
style="fill:#09bd05;stroke:#ffffff;stroke-width:5;stroke-linecap:round;stroke-linejoin:round;fill-opacity:1;stroke-dasharray:none"
id="path2"
cx="50"
cy="84.604881"
r="8.2508707" /><circle
style="fill:#fe1e24;stroke:#ffffff;stroke-width:5;stroke-linecap:round;stroke-linejoin:round;fill-opacity:1;stroke-dasharray:none"
id="circle2"
cx="50"
cy="15.395123"
r="8.2508707" /><circle
style="fill:#fe941d;stroke:#ffffff;stroke-width:5;stroke-linecap:round;stroke-linejoin:round;fill-opacity:1;stroke-dasharray:none"
id="circle3"
cx="-68.30127"
cy="52.906147"
r="8.2508707"
transform="rotate(-120)" /><circle
style="fill:#001996;stroke:#ffffff;stroke-width:5;stroke-linecap:round;stroke-linejoin:round;fill-opacity:1;stroke-dasharray:none"
id="circle4"
cx="-68.30127"
cy="-16.30361"
r="8.2508707"
transform="rotate(-120)" /><circle
style="fill:#ffff04;stroke:#ffffff;stroke-width:5;stroke-linecap:round;stroke-linejoin:round;fill-opacity:1;stroke-dasharray:none"
id="circle5"
cx="-18.301271"
cy="102.90615"
r="8.2508707"
transform="rotate(-60)" /><circle
style="fill:#770287;stroke:#ffffff;stroke-width:5;stroke-linecap:round;stroke-linejoin:round;fill-opacity:1;stroke-dasharray:none"
id="circle6"
cx="-18.301271"
cy="33.696392"
r="8.2508707"
transform="rotate(-60)" /><circle
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:6.75;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none"
id="path7" id="path7"
cx="50" style="stroke-width:4" />
cy="50" <path
r="9.7918472" /><g d="m 304.9188,251.4672 c 1.8572,2.732 1.844,6.3248 -0.0332,9.0432 L 260.6664,324.546 C 259.1728,326.7088 256.712,328 254.0836,328 H 234.948 c -6.3896,0 -10.2004,-7.1212 -6.6564,-12.4376 l 36.75,-55.1248 c 1.7916,-2.6872 1.7916,-6.188 0,-8.8752 l -36.75,-55.1248 C 224.7476,191.1212 228.5584,184 234.948,184 h 19.8748 c 2.6492,0 5.1268,1.3116 6.616,3.5028 z"
inkscape:label="Layer 1" fill="url(#paint0_radial_4033_8)"
id="layer1-3" id="path8"
transform="matrix(0.08246781,0,0,0.08246781,38.828362,38.828362)" style="fill:url(#paint0_radial_4033_8);stroke-width:4" />
style="stroke:#ffffff"><text <g
xml:space="preserve" mask="url(#mask0_4033_8)"
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:96.3615px;line-height:0;font-family:'Noto Serif';-inkscape-font-specification:'Noto Serif, Heavy';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:end;text-anchor:end;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0;stroke-dasharray:none;stroke-opacity:1" id="g9"
x="-305.64749" transform="scale(4)">
y="194.14493" <rect
id="text2819"><tspan x="52"
sodipodi:role="line" y="46"
id="tspan2817" width="17"
style="stroke:#ffffff;stroke-width:0" height="4"
x="-305.64749" fill="#2779dd"
y="194.14493" /></text><circle id="rect9" />
style="fill:#354b5f;fill-opacity:1;stroke:#ffffff;stroke-width:0;stroke-dasharray:none;stroke-opacity:1" </g>
id="path342" <defs
cx="135.46666" id="defs11">
cy="135.46666" <radialGradient
r="135.46666" /><text id="paint0_radial_4033_8"
xml:space="preserve" cx="0"
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:96.3615px;line-height:0;font-family:'Noto Serif';-inkscape-font-specification:'Noto Serif, Heavy';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:end;text-anchor:end;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0;stroke-dasharray:none;stroke-opacity:1" cy="0"
x="-305.64749" r="1"
y="194.14493" gradientTransform="matrix(14,98.0856,-63.2396,9.04212,320,211.9616)"
id="text2819-3"><tspan gradientUnits="userSpaceOnUse">
sodipodi:role="line" <stop
id="tspan2817-5" stop-color="#72AAEE"
style="stroke:#ffffff;stroke-width:0" id="stop10" />
x="-305.64749" <stop
y="194.14493" /></text><g offset="1"
aria-label="❯" stop-color="#3584E4"
id="text2827-6" id="stop11" />
style="font-size:132.452px;line-height:0;font-family:PowerlineSymbols;-inkscape-font-specification:'PowerlineSymbols, Normal';text-align:end;text-anchor:end;fill:#4e94e4;fill-opacity:1;stroke:#ffffff;stroke-width:0"><path </radialGradient>
d="M 95.096912,209.8167 143.88912,135.46666 95.096912,61.116629 h 32.818568 l 47.92093,74.350031 -47.92093,74.35004 z" <mask
id="path2883-2" id="mask0_4033_8"
style="fill:#4e94e4;fill-opacity:1;stroke:#ffffff;stroke-width:0" /></g></g></g></svg> maskUnits="userSpaceOnUse"
x="56"
y="46"
width="21"
height="36">
<path
d="m 76.4223,63.1501 c 0.3482,0.5123 0.3457,1.1859 -0.0063,1.6956 L 65.0175,81.3524 C 64.7375,81.7579 64.2761,82 63.7832,82 h -5.9804 c -1.1981,0 -1.9127,-1.3352 -1.2481,-2.332 l 9.8906,-14.8359 c 0.3359,-0.5039 0.3359,-1.1603 0,-1.6641 L 57.0729,49.1094 C 56.1869,47.7803 57.1396,46 58.737,46 h 5.2334 c 0.4967,0 0.9613,0.2459 1.2405,0.6568 z"
fill="#2779dd"
id="path9" />
</mask>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath11">
<rect
width="128"
height="128"
fill="#ffffff"
id="rect12"
x="0"
y="0"
transform="rotate(-30)" />
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath12">
<rect
width="128"
height="128"
fill="#ffffff"
id="rect13"
x="0"
y="0"
transform="rotate(-30)" />
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath13">
<rect
width="128"
height="128"
fill="#ffffff"
id="rect14"
x="0"
y="0"
transform="rotate(-30)" />
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath14">
<rect
width="128"
height="128"
fill="#ffffff"
id="rect15"
x="0"
y="0"
transform="rotate(-30)" />
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath15">
<rect
width="128"
height="128"
fill="#ffffff"
id="rect16"
x="0"
y="0"
transform="rotate(-30)" />
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath16">
<rect
width="128"
height="128"
fill="#ffffff"
id="rect17"
x="0"
y="0"
transform="rotate(-30)" />
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 6 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Before After
Before After

View file

@ -1,150 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="100mm"
height="100mm"
viewBox="0 0 100 100"
version="1.1"
id="svg1"
xml:space="preserve"
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
sodipodi:docname="icon.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
id="namedview1"
pagecolor="#505050"
bordercolor="#eeeeee"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#505050"
inkscape:document-units="mm"
inkscape:zoom="1.0847363"
inkscape:cx="57.61769"
inkscape:cy="214.33781"
inkscape:window-width="1896"
inkscape:window-height="963"
inkscape:window-x="35"
inkscape:window-y="32"
inkscape:window-maximized="0"
inkscape:current-layer="layer1" /><defs
id="defs1"><linearGradient
id="linearGradient10"
inkscape:collect="always"><stop
style="stop-color:#c7a312;stop-opacity:1;"
offset="0"
id="stop10" /><stop
style="stop-color:#26a0b3;stop-opacity:1;"
offset="1"
id="stop11" /></linearGradient><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient10"
id="linearGradient11"
x1="20.031296"
y1="32.697563"
x2="90.709213"
y2="66.3423"
gradientUnits="userSpaceOnUse" /></defs><g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"><rect
style="fill:url(#linearGradient11);fill-opacity:1;stroke:none;stroke-width:7.99999;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none"
id="rect10"
width="100"
height="100"
x="0"
y="0"
ry="28.294127" /><path
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:8;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none"
d="M 19.377906,68.106953 80.937684,32.43771"
id="path10" /><path
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:8;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none"
d="m 19.044488,32.469148 61.61782,35.569625"
id="path9" /><path
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:8;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none"
d="M 50,85.574911 V 14.425087"
id="path8" /><circle
style="fill:none;stroke:#ffffff;stroke-width:7.11498;stroke-linecap:round;stroke-linejoin:round"
id="path1"
cx="50"
cy="50"
r="35.574913" /><circle
style="fill:#09bd05;stroke:#ffffff;stroke-width:5;stroke-linecap:round;stroke-linejoin:round;fill-opacity:1;stroke-dasharray:none"
id="path2"
cx="50"
cy="84.604881"
r="8.2508707" /><circle
style="fill:#fe1e24;stroke:#ffffff;stroke-width:5;stroke-linecap:round;stroke-linejoin:round;fill-opacity:1;stroke-dasharray:none"
id="circle2"
cx="50"
cy="15.395123"
r="8.2508707" /><circle
style="fill:#fe941d;stroke:#ffffff;stroke-width:5;stroke-linecap:round;stroke-linejoin:round;fill-opacity:1;stroke-dasharray:none"
id="circle3"
cx="-68.30127"
cy="52.906147"
r="8.2508707"
transform="rotate(-120)" /><circle
style="fill:#001996;stroke:#ffffff;stroke-width:5;stroke-linecap:round;stroke-linejoin:round;fill-opacity:1;stroke-dasharray:none"
id="circle4"
cx="-68.30127"
cy="-16.30361"
r="8.2508707"
transform="rotate(-120)" /><circle
style="fill:#ffff04;stroke:#ffffff;stroke-width:5;stroke-linecap:round;stroke-linejoin:round;fill-opacity:1;stroke-dasharray:none"
id="circle5"
cx="-18.301271"
cy="102.90615"
r="8.2508707"
transform="rotate(-60)" /><circle
style="fill:#770287;stroke:#ffffff;stroke-width:5;stroke-linecap:round;stroke-linejoin:round;fill-opacity:1;stroke-dasharray:none"
id="circle6"
cx="-18.301271"
cy="33.696392"
r="8.2508707"
transform="rotate(-60)" /><circle
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:6.75;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none"
id="path7"
cx="50"
cy="50"
r="9.7918472" /><g
inkscape:label="Layer 1"
id="layer1-3"
transform="matrix(0.08246781,0,0,0.08246781,38.828362,38.828362)"
style="stroke:#ffffff"><text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:96.3615px;line-height:0;font-family:'Noto Serif';-inkscape-font-specification:'Noto Serif, Heavy';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:end;text-anchor:end;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0;stroke-dasharray:none;stroke-opacity:1"
x="-305.64749"
y="194.14493"
id="text2819"><tspan
sodipodi:role="line"
id="tspan2817"
style="stroke:#ffffff;stroke-width:0"
x="-305.64749"
y="194.14493" /></text><circle
style="fill:#354b5f;fill-opacity:1;stroke:#ffffff;stroke-width:0;stroke-dasharray:none;stroke-opacity:1"
id="path342"
cx="135.46666"
cy="135.46666"
r="135.46666" /><text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:96.3615px;line-height:0;font-family:'Noto Serif';-inkscape-font-specification:'Noto Serif, Heavy';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:end;text-anchor:end;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0;stroke-dasharray:none;stroke-opacity:1"
x="-305.64749"
y="194.14493"
id="text2819-3"><tspan
sodipodi:role="line"
id="tspan2817-5"
style="stroke:#ffffff;stroke-width:0"
x="-305.64749"
y="194.14493" /></text><g
aria-label="❯"
id="text2827-6"
style="font-size:132.452px;line-height:0;font-family:PowerlineSymbols;-inkscape-font-specification:'PowerlineSymbols, Normal';text-align:end;text-anchor:end;fill:#4e94e4;fill-opacity:1;stroke:#ffffff;stroke-width:0"><path
d="M 95.096912,209.8167 143.88912,135.46666 95.096912,61.116629 h 32.818568 l 47.92093,74.350031 -47.92093,74.35004 z"
id="path2883-2"
style="fill:#4e94e4;fill-opacity:1;stroke:#ffffff;stroke-width:0" /></g></g></g></svg>

Before

Width:  |  Height:  |  Size: 6.8 KiB

BIN
assets/mobile.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

156
assets/mobile.svg Normal file
View file

@ -0,0 +1,156 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="512"
height="512"
viewBox="0 0 512 512"
fill="none"
version="1.1"
id="svg11"
sodipodi:docname="mobile.svg"
inkscape:version="1.4.3 (0d15f75042, 2025-12-25)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview11"
pagecolor="#505050"
bordercolor="#eeeeee"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#505050"
inkscape:zoom="30.03125"
inkscape:cx="14.51821"
inkscape:cy="11.038502"
inkscape:window-width="2544"
inkscape:window-height="1363"
inkscape:window-x="35"
inkscape:window-y="32"
inkscape:window-maximized="0"
inkscape:current-layer="svg11" />
<g
id="g11"
transform="scale(4)">
<g
clip-path="url(#clip0_4033_8)"
id="g10">
<rect
width="128"
height="128"
fill="#ffffff"
id="rect1"
x="0"
y="0" />
<rect
x="60"
y="-107"
width="35.5569"
height="291.86301"
transform="rotate(30,60,-107)"
fill="#9141ac"
id="rect2" />
<rect
x="90.793198"
y="-89.221497"
width="26.6677"
height="291.86301"
transform="rotate(30,90.7932,-89.2215)"
fill="#62a0ea"
id="rect3" />
<rect
x="113.888"
y="-75.887703"
width="26.6677"
height="291.86301"
transform="rotate(30,113.888,-75.8877)"
fill="#57e389"
id="rect4" />
<rect
x="136.983"
y="-62.553799"
width="26.6677"
height="291.86301"
transform="rotate(30,136.983,-62.5538)"
fill="#f5c211"
id="rect5" />
<rect
x="160.078"
y="-49.220001"
width="26.6677"
height="291.86301"
transform="rotate(30,160.078,-49.22)"
fill="#ff7800"
id="rect6" />
<rect
x="183.173"
y="-35.886101"
width="35.5569"
height="291.86301"
transform="rotate(30,183.173,-35.8861)"
fill="#ed333b"
id="rect7" />
<path
d="m 64,23 c 22.6437,0 41,18.3563 41,41 0,22.6437 -18.3563,41 -41,41 -8.6457,0 -16.6648,-2.678 -23.2773,-7.2471 l -9.8018,2.1914 c -1.7167,0.3837 -3.2488,-1.1485 -2.8652,-2.8652 l 2.1904,-9.8027 C 25.6776,80.6641 23,72.6452 23,64 23,41.3563 41.3563,23 64,23 Z"
fill="#ffffff"
id="path7" />
<path
d="m 76.2297,62.8668 c 0.4643,0.683 0.461,1.5812 -0.0083,2.2608 L 65.1666,81.1365 C 64.7932,81.6772 64.178,82 63.5209,82 H 58.737 c -1.5974,0 -2.5501,-1.7803 -1.6641,-3.1094 l 9.1875,-13.7812 c 0.4479,-0.6718 0.4479,-1.547 0,-2.2188 L 57.0729,49.1094 C 56.1869,47.7803 57.1396,46 58.737,46 h 4.9687 c 0.6623,0 1.2817,0.3279 1.654,0.8757 z"
fill="url(#paint0_radial_4033_8)"
id="path8"
style="fill:url(#paint0_radial_4033_8)" />
<mask
id="mask0_4033_8"
maskUnits="userSpaceOnUse"
x="56"
y="46"
width="21"
height="36">
<path
d="m 76.4223,63.1501 c 0.3482,0.5123 0.3457,1.1859 -0.0063,1.6956 L 65.0175,81.3524 C 64.7375,81.7579 64.2761,82 63.7832,82 h -5.9804 c -1.1981,0 -1.9127,-1.3352 -1.2481,-2.332 l 9.8906,-14.8359 c 0.3359,-0.5039 0.3359,-1.1603 0,-1.6641 L 57.0729,49.1094 C 56.1869,47.7803 57.1396,46 58.737,46 h 5.2334 c 0.4967,0 0.9613,0.2459 1.2405,0.6568 z"
fill="#2779dd"
id="path9" />
</mask>
<g
mask="url(#mask0_4033_8)"
id="g9">
<rect
x="52"
y="46"
width="17"
height="4"
fill="#2779dd"
id="rect9" />
</g>
</g>
</g>
<defs
id="defs11">
<radialGradient
id="paint0_radial_4033_8"
cx="0"
cy="0"
r="1"
gradientTransform="matrix(3.5,24.5214,-15.8099,2.26053,80,52.9904)"
gradientUnits="userSpaceOnUse">
<stop
stop-color="#72AAEE"
id="stop10" />
<stop
offset="1"
stop-color="#3584E4"
id="stop11" />
</radialGradient>
<clipPath
id="clip0_4033_8">
<rect
width="128"
height="128"
fill="#ffffff"
id="rect11"
x="0"
y="0" />
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 4.6 KiB

BIN
assets/monochrome.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

178
assets/monochrome.svg Normal file
View file

@ -0,0 +1,178 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="512"
height="512"
viewBox="0 0 512 512"
fill="none"
version="1.1"
id="svg11"
sodipodi:docname="monochrome.svg"
inkscape:version="1.4.3 (0d15f75042, 2025-12-25)"
inkscape:export-filename="foreground.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview11"
pagecolor="#505050"
bordercolor="#eeeeee"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#505050"
inkscape:zoom="1.240199"
inkscape:cx="156.02335"
inkscape:cy="321.3194"
inkscape:window-width="2544"
inkscape:window-height="1363"
inkscape:window-x="35"
inkscape:window-y="32"
inkscape:window-maximized="0"
inkscape:current-layer="svg11" />
<path
d="m 256,92 c 90.5748,0 164,73.4252 164,164 0,90.5748 -73.4252,164 -164,164 -34.5828,0 -66.6592,-10.712 -93.1092,-28.9884 l -39.2072,8.7656 c -6.8668,1.5348 -12.9952,-4.594 -11.4608,-11.4608 l 8.7616,-39.2108 C 102.7104,322.6564 92,290.5808 92,256 92,165.4252 165.4252,92 256,92 Z"
fill="#ffffff"
id="path7"
style="stroke-width:4"
clip-path="url(#clipPath1)"
inkscape:path-effect="#path-effect1" />
<defs
id="defs11">
<inkscape:path-effect
effect="powerclip"
message=""
id="path-effect1"
is_visible="true"
lpeversion="1"
inverse="true"
flatten="false"
hide_clip="false" />
<radialGradient
id="paint0_radial_4033_8"
cx="0"
cy="0"
r="1"
gradientTransform="matrix(14,98.0856,-63.2396,9.04212,320,211.9616)"
gradientUnits="userSpaceOnUse">
<stop
stop-color="#72AAEE"
id="stop10" />
<stop
offset="1"
stop-color="#3584E4"
id="stop11" />
</radialGradient>
<mask
id="mask0_4033_8"
maskUnits="userSpaceOnUse"
x="56"
y="46"
width="21"
height="36">
<path
d="m 76.4223,63.1501 c 0.3482,0.5123 0.3457,1.1859 -0.0063,1.6956 L 65.0175,81.3524 C 64.7375,81.7579 64.2761,82 63.7832,82 h -5.9804 c -1.1981,0 -1.9127,-1.3352 -1.2481,-2.332 l 9.8906,-14.8359 c 0.3359,-0.5039 0.3359,-1.1603 0,-1.6641 L 57.0729,49.1094 C 56.1869,47.7803 57.1396,46 58.737,46 h 5.2334 c 0.4967,0 0.9613,0.2459 1.2405,0.6568 z"
fill="#2779dd"
id="path9" />
</mask>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath11">
<rect
width="128"
height="128"
fill="#ffffff"
id="rect12"
x="0"
y="0"
transform="rotate(-30)" />
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath12">
<rect
width="128"
height="128"
fill="#ffffff"
id="rect13"
x="0"
y="0"
transform="rotate(-30)" />
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath13">
<rect
width="128"
height="128"
fill="#ffffff"
id="rect14"
x="0"
y="0"
transform="rotate(-30)" />
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath14">
<rect
width="128"
height="128"
fill="#ffffff"
id="rect15"
x="0"
y="0"
transform="rotate(-30)" />
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath15">
<rect
width="128"
height="128"
fill="#ffffff"
id="rect16"
x="0"
y="0"
transform="rotate(-30)" />
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath16">
<rect
width="128"
height="128"
fill="#ffffff"
id="rect17"
x="0"
y="0"
transform="rotate(-30)" />
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath1">
<path
d="m 304.9188,251.4672 c 1.8572,2.732 1.844,6.3248 -0.0332,9.0432 L 260.6664,324.546 C 259.1728,326.7088 256.712,328 254.0836,328 H 234.948 c -6.3896,0 -10.2004,-7.1212 -6.6564,-12.4376 l 36.75,-55.1248 c 1.7916,-2.6872 1.7916,-6.188 0,-8.8752 l -36.75,-55.1248 C 224.7476,191.1212 228.5584,184 234.948,184 h 19.8748 c 2.6492,0 5.1268,1.3116 6.616,3.5028 z"
fill="url(#paint0_radial_4033_8)"
id="path1"
style="display:none;fill:url(#radialGradient1);stroke-width:4" />
<path
id="lpe_path-effect1"
style="fill:url(#radialGradient1);stroke-width:4"
class="powerclip"
d="M 87,87 H 425 V 425 H 87 Z m 217.9188,164.4672 -43.48,-63.9644 C 259.9496,185.3116 257.472,184 254.8228,184 H 234.948 c -6.3896,0 -10.2004,7.1212 -6.6564,12.4376 l 36.75,55.1248 c 1.7916,2.6872 1.7916,6.188 0,8.8752 l -36.75,55.1248 C 224.7476,320.8788 228.5584,328 234.948,328 h 19.1356 c 2.6284,0 5.0892,-1.2912 6.5828,-3.454 l 44.2192,-64.0356 c 1.8772,-2.7184 1.8904,-6.3112 0.0332,-9.0432 z" />
</clipPath>
<radialGradient
inkscape:collect="always"
xlink:href="#paint0_radial_4033_8"
id="radialGradient1"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(14,98.0856,-63.2396,9.04212,320,211.9616)"
cx="0"
cy="0"
r="1" />
</defs>
</svg>

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 423 KiB

After

Width:  |  Height:  |  Size: 616 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 425 KiB

After

Width:  |  Height:  |  Size: 616 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

View file

@ -1,126 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="100mm"
height="100mm"
viewBox="0 0 100 100"
version="1.1"
id="svg1"
xml:space="preserve"
inkscape:version="1.4.3 (0d15f75042, 2025-12-25)"
sodipodi:docname="smallerForeground.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
id="namedview1"
pagecolor="#505050"
bordercolor="#eeeeee"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#505050"
inkscape:document-units="mm"
inkscape:zoom="1.0847363"
inkscape:cx="58.078632"
inkscape:cy="213.41592"
inkscape:window-width="2544"
inkscape:window-height="1363"
inkscape:window-x="35"
inkscape:window-y="32"
inkscape:window-maximized="0"
inkscape:current-layer="layer1" /><defs
id="defs1" /><g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"><path
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:5.41161;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none"
d="M 29.285638,62.248476 70.927843,38.119963"
id="path10" /><path
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:5.41161;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none"
d="M 29.060097,38.141229 70.741564,62.202356"
id="path9" /><path
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:5.41161;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none"
d="M 50,74.064703 V 25.935297"
id="path8" /><circle
style="fill:none;stroke:#ffffff;stroke-width:4.81294;stroke-linecap:round;stroke-linejoin:round"
id="path1"
cx="50"
cy="50"
r="24.064703" /><circle
style="fill:#09bd05;fill-opacity:1;stroke:#ffffff;stroke-width:3.38226;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none"
id="path2"
cx="50"
cy="73.408524"
r="5.5813141" /><circle
style="fill:#fe1e24;fill-opacity:1;stroke:#ffffff;stroke-width:3.38226;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none"
id="circle2"
cx="50"
cy="26.59148"
r="5.5813141" /><circle
style="fill:#fe941d;fill-opacity:1;stroke:#ffffff;stroke-width:3.38226;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none"
id="circle3"
cx="-68.30127"
cy="41.709789"
r="5.5813141"
transform="rotate(-120)" /><circle
style="fill:#001996;fill-opacity:1;stroke:#ffffff;stroke-width:3.38226;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none"
id="circle4"
cx="-68.30127"
cy="-5.1072531"
r="5.5813141"
transform="rotate(-120)" /><circle
style="fill:#ffff04;fill-opacity:1;stroke:#ffffff;stroke-width:3.38226;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none"
id="circle5"
cx="-18.301271"
cy="91.709793"
r="5.5813141"
transform="rotate(-60)" /><circle
style="fill:#770287;fill-opacity:1;stroke:#ffffff;stroke-width:3.38226;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none"
id="circle6"
cx="-18.301271"
cy="44.89275"
r="5.5813141"
transform="rotate(-60)" /><circle
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:4.56605;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none"
id="path7"
cx="50"
cy="50"
r="6.6237097" /><g
inkscape:label="Layer 1"
id="layer1-3"
transform="matrix(0.05578547,0,0,0.05578547,42.442929,42.442929)"
style="stroke:#ffffff"><text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:96.3615px;line-height:0;font-family:'Noto Serif';-inkscape-font-specification:'Noto Serif, Heavy';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:end;text-anchor:end;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0;stroke-dasharray:none;stroke-opacity:1"
x="-305.64749"
y="194.14493"
id="text2819"><tspan
sodipodi:role="line"
id="tspan2817"
style="stroke:#ffffff;stroke-width:0"
x="-305.64749"
y="194.14493" /></text><circle
style="fill:#354b5f;fill-opacity:1;stroke:#ffffff;stroke-width:0;stroke-dasharray:none;stroke-opacity:1"
id="path342"
cx="135.46666"
cy="135.46666"
r="135.46666" /><text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:96.3615px;line-height:0;font-family:'Noto Serif';-inkscape-font-specification:'Noto Serif, Heavy';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:end;text-anchor:end;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0;stroke-dasharray:none;stroke-opacity:1"
x="-305.64749"
y="194.14493"
id="text2819-3"><tspan
sodipodi:role="line"
id="tspan2817-5"
style="stroke:#ffffff;stroke-width:0"
x="-305.64749"
y="194.14493" /></text><g
aria-label="❯"
id="text2827-6"
style="font-size:132.452px;line-height:0;font-family:PowerlineSymbols;-inkscape-font-specification:'PowerlineSymbols, Normal';text-align:end;text-anchor:end;fill:#4e94e4;fill-opacity:1;stroke:#ffffff;stroke-width:0"><path
d="M 95.096912,209.8167 143.88912,135.46666 95.096912,61.116629 h 32.818568 l 47.92093,74.350031 -47.92093,74.35004 z"
id="path2883-2"
style="fill:#4e94e4;fill-opacity:1;stroke:#ffffff;stroke-width:0" /></g></g></g></svg>

Before

Width:  |  Height:  |  Size: 6 KiB

BIN
assets/twim/notif.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 MiB

29
flake.lock generated
View file

@ -5,11 +5,11 @@
"nixpkgs-lib": "nixpkgs-lib" "nixpkgs-lib": "nixpkgs-lib"
}, },
"locked": { "locked": {
"lastModified": 1767609335, "lastModified": 1788450739,
"narHash": "sha256-feveD98mQpptwrAEggBQKJTYbvwwglSbOv53uCfH9PY=", "narHash": "sha256-glZLQlzIn1fXH6PazR2iUmTo7kzzyYSshrWhLS9TqCU=",
"owner": "hercules-ci", "owner": "hercules-ci",
"repo": "flake-parts", "repo": "flake-parts",
"rev": "250481aafeb741edfe23d29195671c19b36b6dca", "rev": "31729ca8cbdb4fa927b34e5f4353e6a83f39e993",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -42,15 +42,16 @@
"nixpkgs": "nixpkgs" "nixpkgs": "nixpkgs"
}, },
"locked": { "locked": {
"lastModified": 1774604963, "lastModified": 1790043059,
"narHash": "sha256-MtAW1FIdirSlUAAO7s1u9auv5y3I6t3uJ+GeEbqiqxI=", "narHash": "sha256-7ID4HL4IrrlalCsxMASkcAr+v0VHTNFp6+sZ+dpvOV8=",
"owner": "neobrain", "owner": "Henry-Hiles",
"repo": "nix2flatpak", "repo": "nix2flatpak",
"rev": "3e04657fbcb49956ac301410b071a7f0b2ad5988", "rev": "290dd282e555cab988c021c2be5f2361e58c4d51",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "neobrain", "owner": "Henry-Hiles",
"ref": "quad/nexus",
"repo": "nix2flatpak", "repo": "nix2flatpak",
"type": "github" "type": "github"
} }
@ -73,11 +74,11 @@
}, },
"nixpkgs-lib": { "nixpkgs-lib": {
"locked": { "locked": {
"lastModified": 1765674936, "lastModified": 1788057806,
"narHash": "sha256-k00uTP4JNfmejrCLJOwdObYC9jHRrr/5M/a/8L2EIdo=", "narHash": "sha256-DTQSMxzDWmT0zhguthvegnVkn7CFqGCv4IHCzk5ZUpM=",
"owner": "nix-community", "owner": "nix-community",
"repo": "nixpkgs.lib", "repo": "nixpkgs.lib",
"rev": "2075416fcb47225d9b68ac469a5c4801a9c4dd85", "rev": "596e2e3940e09b2abbeb03f75fa1828c57fcd72c",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -88,11 +89,11 @@
}, },
"nixpkgs_2": { "nixpkgs_2": {
"locked": { "locked": {
"lastModified": 1767640445, "lastModified": 1790185690,
"narHash": "sha256-UWYqmD7JFBEDBHWYcqE6s6c77pWdcU/i+bwD6XxMb8A=", "narHash": "sha256-xJ+X4hBtOcAFGBOe5nAMyMUeF9foJBmIOu3NjBqBycU=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "9f0c42f8bc7151b8e7e5840fb3bd454ad850d8c5", "rev": "4975466d324710c576dc11ad614684e6bd8cad8e",
"type": "github" "type": "github"
}, },
"original": { "original": {

View file

@ -5,7 +5,7 @@
self.submodules = true; self.submodules = true;
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
flake-parts.url = "github:hercules-ci/flake-parts"; flake-parts.url = "github:hercules-ci/flake-parts";
nix2flatpak.url = "github:neobrain/nix2flatpak"; nix2flatpak.url = "github:Henry-Hiles/nix2flatpak/quad/nexus";
}; };
outputs = outputs =
@ -16,61 +16,12 @@
... ...
}@inputs: }@inputs:
flake-parts.lib.mkFlake { inherit inputs; } { flake-parts.lib.mkFlake { inherit inputs; } {
imports = [ ./linux/nix ];
systems = [ systems = [
"x86_64-linux" "x86_64-linux"
"aarch64-linux" "aarch64-linux"
"aarch64-darwin" "aarch64-darwin"
"x86_64-darwin" "x86_64-darwin"
]; ];
perSystem =
{
lib,
pkgs,
system,
...
}:
{
_module.args.pkgs = import nixpkgs {
inherit system;
config = {
android_sdk.accept_license = true;
allowUnfree = true;
};
};
packages =
let
default = pkgs.callPackage ./linux/nix/pkg {
src = self;
};
in
{
inherit default;
flatpak = inputs.nix2flatpak.lib.${system}.mkFlatpak {
appName = "Nexus";
developer = "QuadRadical";
appId = "nexus.federated.Nexus";
package = default;
runtime = "org.gnome.Platform/49";
permissions = {
share = [ "network" ];
sockets = [
"fallback-x11"
"wayland"
];
devices = [ "dri" ];
};
};
gomuks = pkgs.callPackage ./linux/nix/pkg/gomuks.nix {
src = self;
};
};
devShells.default = pkgs.callPackage ./linux/nix/devshell.nix { };
};
}; };
} }

2
gomuks

@ -1 +1 @@
Subproject commit daa0ba028e7d89ba9fc7580fc8099348e6145cb3 Subproject commit 480938f9e01e7eae2cf249657efae03df76599d6

View file

@ -1,20 +1,60 @@
import "dart:io"; import "dart:io";
import "package:collection/collection.dart";
import "package:hooks/hooks.dart"; import "package:hooks/hooks.dart";
import "package:code_assets/code_assets.dart"; import "package:code_assets/code_assets.dart";
import "package:nexus/helpers/extensions/get_xcode_sdk.dart";
import "package:path/path.dart";
Future<void> main(List<String> args) => build(args, (input, output) async { Future<void> main(List<String> args) => build(args, (input, output) async {
if (!input.config.buildCodeAssets) return;
final codeConfig = input.config.code; final codeConfig = input.config.code;
final targetOS = codeConfig.targetOS; final targetOS = codeConfig.targetOS;
final targetArch = codeConfig.targetArchitecture; final targetArch = codeConfig.targetArchitecture;
String libFileName; String libFileName;
Map<String, String> env = {}; Map<String, String> extraEnv = {};
IOSSdk? iosSdk;
String? iosSdkPath;
String? iosTargetTriple;
switch (targetOS) { switch (targetOS) {
case OS.linux: case OS.linux:
libFileName = "libgomuks.so"; libFileName = "libgomuks.so";
break; break;
case OS.iOS:
// Go only supports buildmode=c-archive for ios, not c-shared, so the
// archive built below gets linked into a dylib via a separate clang
// invocation before being registered as a normal asset like macOS.
libFileName = "libgomuks.dylib";
final iosConfig = codeConfig.iOS;
iosSdk = iosConfig.targetSdk;
final minVersion = iosConfig.targetVersion;
iosSdkPath = await getXCodeTool(sdkType: iosSdk.type);
final archTriple = switch (targetArch) {
Architecture.arm64 => "arm64",
Architecture.x64 => "x86_64",
_ => throw UnsupportedError(
"Unsupported iOS architecture: $targetArch",
),
};
iosTargetTriple = iosSdk == IOSSdk.iPhoneSimulator
? "$archTriple-apple-ios$minVersion.0-simulator"
: "$archTriple-apple-ios$minVersion.0";
extraEnv = {
"GOOS": "ios",
"CC": await getXCodeTool(sdkType: iosSdk.type, findTool: "clang"),
"CGO_CFLAGS": "-isysroot $iosSdkPath -target $iosTargetTriple",
"CGO_LDFLAGS": "-isysroot $iosSdkPath -target $iosTargetTriple",
};
break;
case OS.macOS: case OS.macOS:
libFileName = "libgomuks.dylib"; libFileName = "libgomuks.dylib";
extraEnv = {
"SDKROOT": await getXCodeTool(),
"MACOSX_DEPLOYMENT_TARGET": codeConfig.macOS.targetVersion.toString(),
};
break; break;
case OS.windows: case OS.windows:
libFileName = "libgomuks.dll"; libFileName = "libgomuks.dll";
@ -24,23 +64,48 @@ Future<void> main(List<String> args) => build(args, (input, output) async {
final targetNdkApi = codeConfig.android.targetNdkApi; final targetNdkApi = codeConfig.android.targetNdkApi;
Future<String?> findNdkFromSdk() async {
final androidHome =
Platform.environment["ANDROID_HOME"] ??
Platform.environment["ANDROID_SDK_ROOT"];
if (androidHome == null) return null;
final ndkDir = Directory(join(androidHome, "ndk"));
if (!await ndkDir.exists()) return null;
final versions = await ndkDir.list().toList();
return versions.sortedBy((file) => file.path).lastOrNull?.path;
}
final ndkHome = final ndkHome =
Platform.environment["ANDROID_NDK_HOME"] ?? Platform.environment["ANDROID_NDK_HOME"] ??
Platform.environment["ANDROID_NDK_ROOT"] ?? Platform.environment["ANDROID_NDK_ROOT"] ??
Platform.environment["NDK_HOME"] ?? Platform.environment["NDK_HOME"] ??
await _findNdkFromSdk(); await findNdkFromSdk();
if (ndkHome == null) { if (ndkHome == null) {
throw Exception( throw Exception(
"Could not find Android NDK. Set ANDROID_NDK_HOME or install via sdkmanager.", "Could not find Android NDK. Set ANDROID_NDK_HOME or install via sdkmanager.",
); );
} }
final hostTag = _ndkHostTag(); // TODO: Someone please give me a way to detect host architecture so I can change this
final (goArch, ccTriple) = _androidArch(targetArch); final hostTag =
Platform.environment["ANDROID_HOST_TAG"] ??
"${Platform.operatingSystem}-x86_64";
final ccTriple = switch (targetArch) {
Architecture.arm64 => "aarch64-linux-android",
Architecture.arm => "armv7a-linux-androideabi",
Architecture.x64 => "x86_64-linux-android",
Architecture.ia32 => "i686-linux-android",
_ => throw UnsupportedError(
"Unsupported Android architecture: $targetArch",
),
};
final cc = final cc =
"$ndkHome/toolchains/llvm/prebuilt/$hostTag/bin/$ccTriple$targetNdkApi-clang"; "$ndkHome/toolchains/llvm/prebuilt/$hostTag/bin/$ccTriple$targetNdkApi-clang";
env = {"CGO_ENABLED": "1", "GOOS": "android", "GOARCH": goArch, "CC": cc}; extraEnv = {"GOOS": "android", "CC": cc};
break; break;
default: default:
throw UnsupportedError("Unsupported OS: $targetOS"); throw UnsupportedError("Unsupported OS: $targetOS");
@ -53,16 +118,43 @@ Future<void> main(List<String> args) => build(args, (input, output) async {
final buildDir = input.packageRoot.resolve("build/"); final buildDir = input.packageRoot.resolve("build/");
libFile = buildDir.resolve("${targetArch.name}/$libFileName"); libFile = buildDir.resolve("${targetArch.name}/$libFileName");
// goheif/dav1d supported on Android would need to fix upstream final tags = [
final tags = targetOS == OS.android ? "goolm,noheic" : "goolm"; "sqlite_fts5",
"goolm",
// goheif/dav1d is not supported on Android or iOS, would need to be fixed upstream
if (targetOS == OS.android || targetOS == OS.iOS) "noheic",
].join(",");
final archiveFile = targetOS == OS.iOS
? buildDir.resolve("${targetArch.name}/libgomuks.a")
: libFile;
print( print(
"Building Gomuks shared library $libFileName (${targetOS.name}/${targetArch.name}) to ${libFile.path}...", "Building Gomuks shared library $libFileName (${targetOS.name}/${targetArch.name}) to ${archiveFile.path}...",
); );
final result = await Process.run( final result = await Process.run(
"go", "go",
["build", "-tags", tags, "-o", libFile.path, "-buildmode=c-shared"], [
"build",
"-trimpath",
"-ldflags=-s -w",
"-tags",
tags,
"-o",
archiveFile.path,
"-buildmode=${targetOS == OS.iOS ? "c-archive" : "c-shared"}",
],
workingDirectory: gomuksBuildDir.resolve("pkg/ffi/").toFilePath(), workingDirectory: gomuksBuildDir.resolve("pkg/ffi/").toFilePath(),
environment: env.isNotEmpty ? env : null, environment: {
"CGO_ENABLED": "1",
"GOARCH": switch (targetArch) {
Architecture.arm64 => "arm64",
Architecture.arm => "arm",
Architecture.x64 => "amd64",
Architecture.ia32 => "386",
_ => throw UnsupportedError("Unsupported architecture: $targetArch"),
},
...extraEnv,
},
); );
if (result.exitCode != 0) { if (result.exitCode != 0) {
@ -70,6 +162,35 @@ Future<void> main(List<String> args) => build(args, (input, output) async {
"Failed to build Gomuks shared library\n${result.stderr}", "Failed to build Gomuks shared library\n${result.stderr}",
); );
} }
if (targetOS == OS.iOS) {
print("Linking $archiveFile into $libFile...");
final linkResult = await Process.run("xcrun", [
"--sdk",
iosSdk!.type,
"clang",
"-dynamiclib",
"-isysroot",
iosSdkPath!,
"-target",
iosTargetTriple!,
"-install_name",
"@rpath/libgomuks.dylib",
"-framework",
"Security",
"-framework",
"CoreFoundation",
"-framework",
"SystemConfiguration",
"-force_load",
archiveFile.path,
"-o",
libFile.path,
]);
if (linkResult.exitCode != 0) {
throw Exception("Failed to link Gomuks dylib\n${linkResult.stderr}");
}
}
} }
final generatedFile = "src/third_party/gomuks.g.dart"; final generatedFile = "src/third_party/gomuks.g.dart";
@ -87,43 +208,3 @@ Future<void> main(List<String> args) => build(args, (input, output) async {
..dependencies.add(gomuksBuildDir); ..dependencies.add(gomuksBuildDir);
print("Done!"); print("Done!");
}); });
Future<String?> _findNdkFromSdk() async {
// pretty sure this wont be needed with nix, i'll get this removed
final androidHome =
Platform.environment["ANDROID_HOME"] ??
Platform.environment["ANDROID_SDK_ROOT"];
if (androidHome == null) return null;
final ndkDir = Directory("$androidHome/ndk");
if (!await ndkDir.exists()) return null;
final versions = await ndkDir.list().toList();
if (versions.isEmpty) return null;
versions.sort((a, b) => a.path.compareTo(b.path));
return versions.last.path;
}
String _ndkHostTag() {
if (Platform.isMacOS) {
return "darwin-x86_64";
} else if (Platform.isLinux) {
return "linux-x86_64";
} else if (Platform.isWindows) {
return "windows-x86_64";
}
throw UnsupportedError("Unsupported host platform for Android NDK");
}
(String goArch, String ccTriple) _androidArch(Architecture arch) {
switch (arch) {
case Architecture.arm64:
return ("arm64", "aarch64-linux-android");
case Architecture.arm:
return ("arm", "armv7a-linux-androideabi");
case Architecture.x64:
return ("amd64", "x86_64-linux-android");
case Architecture.ia32:
return ("386", "i686-linux-android");
default:
throw UnsupportedError("Unsupported Android architecture: $arch");
}
}

View file

@ -7,7 +7,7 @@
<key>CFBundleExecutable</key> <key>CFBundleExecutable</key>
<string>App</string> <string>App</string>
<key>CFBundleIdentifier</key> <key>CFBundleIdentifier</key>
<string>nexus.federated.Nexus</string> <string>io.flutter.flutter.app</string>
<key>CFBundleInfoDictionaryVersion</key> <key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string> <string>6.0</string>
<key>CFBundleName</key> <key>CFBundleName</key>
@ -20,7 +20,5 @@
<string>????</string> <string>????</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>1.0</string> <string>1.0</string>
<key>MinimumOSVersion</key>
<string>15.5</string>
</dict> </dict>
</plist> </plist>

View file

@ -1,4 +1,7 @@
platform :ios, 16 # Uncomment this line to define a global platform for your project
# platform :ios, '13.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true' ENV['COCOAPODS_DISABLE_STATS'] = 'true'
project 'Runner', { project 'Runner', {
@ -26,30 +29,15 @@ flutter_ios_podfile_setup
target 'Runner' do target 'Runner' do
use_frameworks! use_frameworks!
use_modular_headers!
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
target 'RunnerTests' do
inherit! :search_paths
end
end end
post_install do |installer| post_install do |installer|
installer.pods_project.targets.each do |target| installer.pods_project.targets.each do |target|
target.build_configurations.each do |config| flutter_additional_ios_build_settings(target)
if config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] == '8.0'
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '11.0'
end end
end end
flutter_additional_ios_build_settings target
end
################ Awesome Notifications pod modification 1 ###################
awesome_pod_file = File.expand_path(File.join('plugins', 'awesome_notifications', 'ios', 'Scripts', 'AwesomePodFile'), '.symlinks')
require awesome_pod_file
update_awesome_pod_build_settings(installer)
################ Awesome Notifications pod modification 1 ###################
end
################ Awesome Notifications pod modification 2 ###################
awesome_pod_file = File.expand_path(File.join('plugins', 'awesome_notifications', 'ios', 'Scripts', 'AwesomePodFile'), '.symlinks')
require awesome_pod_file
update_awesome_main_target_settings('Runner', File.dirname(File.realpath(__FILE__)), flutter_root)
################ Awesome Notifications pod modification 2 ###################

28
ios/Podfile.lock Normal file
View file

@ -0,0 +1,28 @@
PODS:
- Flutter (1.0.0)
- media_kit_libs_ios_video (1.0.4):
- Flutter
- media_kit_video (0.0.1):
- Flutter
DEPENDENCIES:
- Flutter (from `Flutter`)
- media_kit_libs_ios_video (from `.symlinks/plugins/media_kit_libs_ios_video/ios`)
- media_kit_video (from `.symlinks/plugins/media_kit_video/ios`)
EXTERNAL SOURCES:
Flutter:
:path: Flutter
media_kit_libs_ios_video:
:path: ".symlinks/plugins/media_kit_libs_ios_video/ios"
media_kit_video:
:path: ".symlinks/plugins/media_kit_video/ios"
SPEC CHECKSUMS:
Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467
media_kit_libs_ios_video: 5a18affdb97d1f5d466dc79988b13eff6c5e2854
media_kit_video: 1746e198cb697d1ffb734b1d05ec429d1fcd1474
PODFILE CHECKSUM: 3c63482e143d1b91d2d2560aee9fb04ecc74ac7e
COCOAPODS: 1.17.0

View file

@ -8,14 +8,28 @@
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
3965FF1D950A2B2E051F6219 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E598BBDD2ED0112E344B590 /* Pods_Runner.framework */; }; 2ADFEE6C745FFB2100CC9AFD /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8156A45F510382D558AED93A /* Pods_RunnerTests.framework */; };
331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
7884E8682EC3CC0700C636F2 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7884E8672EC3CC0400C636F2 /* SceneDelegate.swift */; };
78A318202AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage in Frameworks */ = {isa = PBXBuildFile; productRef = 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */; };
88D55A5F1C7625122EBEE29D /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 82F9A3759658343C81A0EA4C /* Pods_Runner.framework */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
331C8085294A63A400263BE5 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 97C146E61CF9000F007C117D /* Project object */;
proxyType = 1;
remoteGlobalIDString = 97C146ED1CF9000F007C117D;
remoteInfo = Runner;
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */ /* Begin PBXCopyFilesBuildPhase section */
9705A1C41CF9048500538489 /* Embed Frameworks */ = { 9705A1C41CF9048500538489 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase; isa = PBXCopyFilesBuildPhase;
@ -32,12 +46,19 @@
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; }; 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
22DE4310DAFBE211CDF700B1 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = "<group>"; };
331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
363A89F6FA09BCCBDED440CE /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
5E598BBDD2ED0112E344B590 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 63516CF65A79A5DDDE64B0D1 /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = "<group>"; };
6A2D47C573B065AD356C7183 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; }; 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; }; 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
7884E8672EC3CC0400C636F2 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = FlutterGeneratedPluginSwiftPackage; path = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
8156A45F510382D558AED93A /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
82F9A3759658343C81A0EA4C /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; }; 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
@ -45,35 +66,67 @@
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; }; 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
CA00A9F43BB1AB7D908E180A /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; }; AEB96D8976BD46D6860C7041 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
DFFCB3F45BF495277AE4D3EE /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; }; B8B599FDB72E4713FB7B5A44 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = "<group>"; };
FE5E4162842555A83F8A7FD7 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
8C0A36760DA8B873D8F6DDCE /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
2ADFEE6C745FFB2100CC9AFD /* Pods_RunnerTests.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
97C146EB1CF9000F007C117D /* Frameworks */ = { 97C146EB1CF9000F007C117D /* Frameworks */ = {
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
3965FF1D950A2B2E051F6219 /* Pods_Runner.framework in Frameworks */, 78A318202AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage in Frameworks */,
88D55A5F1C7625122EBEE29D /* Pods_Runner.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
/* End PBXFrameworksBuildPhase section */ /* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */ /* Begin PBXGroup section */
7226BEAE3D25CA120A434CC9 /* Pods */ = { 1CFFAE23B502BCCEB2B191A3 /* Pods */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
DFFCB3F45BF495277AE4D3EE /* Pods-Runner.debug.xcconfig */, AEB96D8976BD46D6860C7041 /* Pods-Runner.debug.xcconfig */,
CA00A9F43BB1AB7D908E180A /* Pods-Runner.release.xcconfig */, 363A89F6FA09BCCBDED440CE /* Pods-Runner.release.xcconfig */,
6A2D47C573B065AD356C7183 /* Pods-Runner.profile.xcconfig */, 22DE4310DAFBE211CDF700B1 /* Pods-Runner.profile.xcconfig */,
B8B599FDB72E4713FB7B5A44 /* Pods-RunnerTests.debug.xcconfig */,
FE5E4162842555A83F8A7FD7 /* Pods-RunnerTests.release.xcconfig */,
63516CF65A79A5DDDE64B0D1 /* Pods-RunnerTests.profile.xcconfig */,
); );
name = Pods;
path = Pods; path = Pods;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
331C8082294A63A400263BE5 /* RunnerTests */ = {
isa = PBXGroup;
children = (
331C807B294A618700263BE5 /* RunnerTests.swift */,
);
path = RunnerTests;
sourceTree = "<group>";
};
594EB1F65336CF9C7958F6FA /* Frameworks */ = {
isa = PBXGroup;
children = (
82F9A3759658343C81A0EA4C /* Pods_Runner.framework */,
8156A45F510382D558AED93A /* Pods_RunnerTests.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
9740EEB11CF90186004384FC /* Flutter */ = { 9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */,
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
9740EEB21CF90195004384FC /* Debug.xcconfig */, 9740EEB21CF90195004384FC /* Debug.xcconfig */,
7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
@ -88,8 +141,9 @@
9740EEB11CF90186004384FC /* Flutter */, 9740EEB11CF90186004384FC /* Flutter */,
97C146F01CF9000F007C117D /* Runner */, 97C146F01CF9000F007C117D /* Runner */,
97C146EF1CF9000F007C117D /* Products */, 97C146EF1CF9000F007C117D /* Products */,
7226BEAE3D25CA120A434CC9 /* Pods */, 331C8082294A63A400263BE5 /* RunnerTests */,
E396C277672D83FCFDB51CCB /* Frameworks */, 1CFFAE23B502BCCEB2B191A3 /* Pods */,
594EB1F65336CF9C7958F6FA /* Frameworks */,
); );
sourceTree = "<group>"; sourceTree = "<group>";
}; };
@ -97,6 +151,7 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
97C146EE1CF9000F007C117D /* Runner.app */, 97C146EE1CF9000F007C117D /* Runner.app */,
331C8081294A63A400263BE5 /* RunnerTests.xctest */,
); );
name = Products; name = Products;
sourceTree = "<group>"; sourceTree = "<group>";
@ -111,41 +166,55 @@
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
74858FAE1ED2DC5600515810 /* AppDelegate.swift */, 74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
7884E8672EC3CC0400C636F2 /* SceneDelegate.swift */,
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
); );
path = Runner; path = Runner;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
E396C277672D83FCFDB51CCB /* Frameworks */ = {
isa = PBXGroup;
children = (
5E598BBDD2ED0112E344B590 /* Pods_Runner.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
/* End PBXGroup section */ /* End PBXGroup section */
/* Begin PBXNativeTarget section */ /* Begin PBXNativeTarget section */
331C8080294A63A400263BE5 /* RunnerTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */;
buildPhases = (
EE82EC529EB6C0F1FA480659 /* [CP] Check Pods Manifest.lock */,
331C807D294A63A400263BE5 /* Sources */,
331C807F294A63A400263BE5 /* Resources */,
8C0A36760DA8B873D8F6DDCE /* Frameworks */,
);
buildRules = (
);
dependencies = (
331C8086294A63A400263BE5 /* PBXTargetDependency */,
);
name = RunnerTests;
productName = RunnerTests;
productReference = 331C8081294A63A400263BE5 /* RunnerTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
97C146ED1CF9000F007C117D /* Runner */ = { 97C146ED1CF9000F007C117D /* Runner */ = {
isa = PBXNativeTarget; isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = ( buildPhases = (
A3B5CB395514F4BF9CDF304E /* [CP] Check Pods Manifest.lock */, 0830C6758DA3ECA81FB12386 /* [CP] Check Pods Manifest.lock */,
9740EEB61CF901F6004384FC /* Run Script */, 9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */, 97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */, 97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */, 97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */, 9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */,
C3C8545BDAC52D360D298A29 /* [CP] Embed Pods Frameworks */, 1D165FDFB9D0D939B041966D /* [CP] Embed Pods Frameworks */,
F46F66CC32F585BBF2FB675E /* [CP] Copy Pods Resources */,
); );
buildRules = ( buildRules = (
); );
dependencies = ( dependencies = (
); );
name = Runner; name = Runner;
packageProductDependencies = (
78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */,
);
productName = Runner; productName = Runner;
productReference = 97C146EE1CF9000F007C117D /* Runner.app */; productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
productType = "com.apple.product-type.application"; productType = "com.apple.product-type.application";
@ -160,6 +229,10 @@
LastUpgradeCheck = 1510; LastUpgradeCheck = 1510;
ORGANIZATIONNAME = ""; ORGANIZATIONNAME = "";
TargetAttributes = { TargetAttributes = {
331C8080294A63A400263BE5 = {
CreatedOnToolsVersion = 14.0;
TestTargetID = 97C146ED1CF9000F007C117D;
};
97C146ED1CF9000F007C117D = { 97C146ED1CF9000F007C117D = {
CreatedOnToolsVersion = 7.3.1; CreatedOnToolsVersion = 7.3.1;
LastSwiftMigration = 1100; LastSwiftMigration = 1100;
@ -175,16 +248,27 @@
Base, Base,
); );
mainGroup = 97C146E51CF9000F007C117D; mainGroup = 97C146E51CF9000F007C117D;
packageReferences = (
781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "FlutterGeneratedPluginSwiftPackage" */,
);
productRefGroup = 97C146EF1CF9000F007C117D /* Products */; productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
projectDirPath = ""; projectDirPath = "";
projectRoot = ""; projectRoot = "";
targets = ( targets = (
97C146ED1CF9000F007C117D /* Runner */, 97C146ED1CF9000F007C117D /* Runner */,
331C8080294A63A400263BE5 /* RunnerTests */,
); );
}; };
/* End PBXProject section */ /* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */ /* Begin PBXResourcesBuildPhase section */
331C807F294A63A400263BE5 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
97C146EC1CF9000F007C117D /* Resources */ = { 97C146EC1CF9000F007C117D /* Resources */ = {
isa = PBXResourcesBuildPhase; isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
@ -199,6 +283,45 @@
/* End PBXResourcesBuildPhase section */ /* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */
0830C6758DA3ECA81FB12386 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
1D165FDFB9D0D939B041966D /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1; alwaysOutOfDate = 1;
@ -230,7 +353,7 @@
shellPath = /bin/sh; shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
}; };
A3B5CB395514F4BF9CDF304E /* [CP] Check Pods Manifest.lock */ = { EE82EC529EB6C0F1FA480659 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
@ -245,61 +368,44 @@
outputFileListPaths = ( outputFileListPaths = (
); );
outputPaths = ( outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", "$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt",
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh; shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0; showEnvVarsInLog = 0;
}; };
C3C8545BDAC52D360D298A29 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
F46F66CC32F585BBF2FB675E /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Copy Pods Resources";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */ /* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */
331C807D294A63A400263BE5 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
97C146EA1CF9000F007C117D /* Sources */ = { 97C146EA1CF9000F007C117D /* Sources */ = {
isa = PBXSourcesBuildPhase; isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
7884E8682EC3CC0700C636F2 /* SceneDelegate.swift in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
/* End PBXSourcesBuildPhase section */ /* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
331C8086294A63A400263BE5 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 97C146ED1CF9000F007C117D /* Runner */;
targetProxy = 331C8085294A63A400263BE5 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */ /* Begin PBXVariantGroup section */
97C146FA1CF9000F007C117D /* Main.storyboard */ = { 97C146FA1CF9000F007C117D /* Main.storyboard */ = {
isa = PBXVariantGroup; isa = PBXVariantGroup;
@ -324,6 +430,7 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO; ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++"; CLANG_CXX_LIBRARY = "libc++";
@ -353,6 +460,7 @@
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO; ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
GCC_C_LANGUAGE_STANDARD = gnu99; GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES; GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
@ -374,20 +482,17 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = { buildSettings = {
APPLICATION_EXTENSION_API_ONLY = NO;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = AppIcon;
BUILD_LIBRARY_FOR_DISTRIBUTION = NO;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = P3ZD9TNSKZ; DEVELOPMENT_TEAM = PK66NJM372;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
PRODUCT_BUNDLE_IDENTIFIER = nexus.federated.Nexus; PRODUCT_BUNDLE_IDENTIFIER = nexus.federated.nexus;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
@ -395,10 +500,61 @@
}; };
name = Profile; name = Profile;
}; };
331C8088294A63A400263BE5 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = B8B599FDB72E4713FB7B5A44 /* Pods-RunnerTests.debug.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = nexus.federated.nexus.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
};
name = Debug;
};
331C8089294A63A400263BE5 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = FE5E4162842555A83F8A7FD7 /* Pods-RunnerTests.release.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = nexus.federated.nexus.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
};
name = Release;
};
331C808A294A63A400263BE5 /* Profile */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 63516CF65A79A5DDDE64B0D1 /* Pods-RunnerTests.profile.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = nexus.federated.nexus.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
};
name = Profile;
};
97C147031CF9000F007C117D /* Debug */ = { 97C147031CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO; ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = AppIcon;
CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++"; CLANG_CXX_LIBRARY = "libc++";
@ -428,6 +584,7 @@
DEBUG_INFORMATION_FORMAT = dwarf; DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES; ENABLE_TESTABILITY = YES;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
GCC_C_LANGUAGE_STANDARD = gnu99; GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO; GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES; GCC_NO_COMMON_BLOCKS = YES;
@ -454,6 +611,7 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO; ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = AppIcon;
CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++"; CLANG_CXX_LIBRARY = "libc++";
@ -483,6 +641,7 @@
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO; ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
GCC_C_LANGUAGE_STANDARD = gnu99; GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES; GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
@ -506,20 +665,17 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
buildSettings = { buildSettings = {
APPLICATION_EXTENSION_API_ONLY = NO;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = AppIcon;
BUILD_LIBRARY_FOR_DISTRIBUTION = NO;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = P3ZD9TNSKZ; DEVELOPMENT_TEAM = PK66NJM372;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
PRODUCT_BUNDLE_IDENTIFIER = nexus.federated.Nexus; PRODUCT_BUNDLE_IDENTIFIER = nexus.federated.nexus;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_OPTIMIZATION_LEVEL = "-Onone";
@ -532,20 +688,17 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = { buildSettings = {
APPLICATION_EXTENSION_API_ONLY = NO;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = AppIcon;
BUILD_LIBRARY_FOR_DISTRIBUTION = NO;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = P3ZD9TNSKZ; DEVELOPMENT_TEAM = PK66NJM372;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
PRODUCT_BUNDLE_IDENTIFIER = nexus.federated.Nexus; PRODUCT_BUNDLE_IDENTIFIER = nexus.federated.nexus;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
@ -556,6 +709,16 @@
/* End XCBuildConfiguration section */ /* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */ /* Begin XCConfigurationList section */
331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
331C8088294A63A400263BE5 /* Debug */,
331C8089294A63A400263BE5 /* Release */,
331C808A294A63A400263BE5 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
isa = XCConfigurationList; isa = XCConfigurationList;
buildConfigurations = ( buildConfigurations = (
@ -577,6 +740,20 @@
defaultConfigurationName = Release; defaultConfigurationName = Release;
}; };
/* End XCConfigurationList section */ /* End XCConfigurationList section */
/* Begin XCLocalSwiftPackageReference section */
781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "FlutterGeneratedPluginSwiftPackage" */ = {
isa = XCLocalSwiftPackageReference;
relativePath = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage;
};
/* End XCLocalSwiftPackageReference section */
/* Begin XCSwiftPackageProductDependency section */
78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */ = {
isa = XCSwiftPackageProductDependency;
productName = FlutterGeneratedPluginSwiftPackage;
};
/* End XCSwiftPackageProductDependency section */
}; };
rootObject = 97C146E61CF9000F007C117D /* Project object */; rootObject = 97C146E61CF9000F007C117D /* Project object */;
} }

View file

@ -5,6 +5,24 @@
<BuildAction <BuildAction
parallelizeBuildables = "YES" parallelizeBuildables = "YES"
buildImplicitDependencies = "YES"> buildImplicitDependencies = "YES">
<PreActions>
<ExecutionAction
ActionType = "Xcode.IDEStandardExecutionActionsCore.ExecutionActionType.ShellScriptAction">
<ActionContent
title = "Run Prepare Flutter Framework Script"
scriptText = "/bin/sh &quot;$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh&quot; prepare&#10;">
<EnvironmentBuildable>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</EnvironmentBuildable>
</ActionContent>
</ExecutionAction>
</PreActions>
<BuildActionEntries> <BuildActionEntries>
<BuildActionEntry <BuildActionEntry
buildForTesting = "YES" buildForTesting = "YES"

View file

@ -1,13 +1,17 @@
import UIKit
import Flutter import Flutter
import UIKit
@main @main
@objc class AppDelegate: FlutterAppDelegate { @objc class AppDelegate: FlutterAppDelegate, FlutterImplicitEngineDelegate {
override func application( override func application(
_ application: UIApplication, _ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool { ) -> Bool {
GeneratedPluginRegistrant.register(with: self) UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate
return super.application(application, didFinishLaunchingWithOptions: launchOptions) return super.application(application, didFinishLaunchingWithOptions: launchOptions)
} }
func didInitializeImplicitFlutterEngine(_ engineBridge: FlutterImplicitEngineBridge) {
GeneratedPluginRegistrant.register(with: engineBridge.pluginRegistry)
}
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 176 KiB

After

Width:  |  Height:  |  Size: 78 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 846 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

After

Width:  |  Height:  |  Size: 4 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 5.3 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 5 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 5.3 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 8.3 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 6.5 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 7.5 KiB

Before After
Before After

View file

@ -3,7 +3,7 @@
<plist version="1.0"> <plist version="1.0">
<dict> <dict>
<key>CADisableMinimumFrameDurationOnPhone</key> <key>CADisableMinimumFrameDurationOnPhone</key>
<true/> <false/>
<key>CFBundleDevelopmentRegion</key> <key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string> <string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key> <key>CFBundleDisplayName</key>
@ -22,30 +22,40 @@
<string>$(FLUTTER_BUILD_NAME)</string> <string>$(FLUTTER_BUILD_NAME)</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>????</string> <string>????</string>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>nexus.federated.nexus</string>
</array>
</dict>
</array>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>$(FLUTTER_BUILD_NUMBER)</string> <string>$(FLUTTER_BUILD_NUMBER)</string>
<key>LSSupportsOpeningDocumentsInPlace</key>
<true/>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>file</string>
<string>https</string>
<string>http</string>
<string>mailto</string>
<string>tel</string>
</array>
<key>UIFileSharingEnabled</key>
<true/>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>LSRequiresIPhoneOS</key> <key>LSRequiresIPhoneOS</key>
<true/> <true/>
<key>NSCameraUsageDescription</key> <key>UIApplicationSceneManifest</key>
<string>This app needs camera access to scan asset QR codes</string> <dict>
<key>NSMicrophoneUsageDescription</key> <key>UIApplicationSupportsMultipleScenes</key>
<string>This app doesn't use your microphone.</string> <false/>
<key>NSPhotoLibraryUsageDescription</key> <key>UISceneConfigurations</key>
<string>This app doesn't use your photo library.</string> <dict>
<key>UIWindowSceneSessionRoleApplication</key>
<array>
<dict>
<key>UISceneClassName</key>
<string>UIWindowScene</string>
<key>UISceneConfigurationName</key>
<string>flutter</string>
<key>UISceneDelegateClassName</key>
<string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
<key>UISceneStoryboardFile</key>
<string>Main</string>
</dict>
</array>
</dict>
</dict>
<key>UIApplicationSupportsIndirectInputEvents</key> <key>UIApplicationSupportsIndirectInputEvents</key>
<true/> <true/>
<key>UILaunchStoryboardName</key> <key>UILaunchStoryboardName</key>

View file

@ -0,0 +1,6 @@
import Flutter
import UIKit
class SceneDelegate: FlutterSceneDelegate {
}

View file

@ -0,0 +1,12 @@
import Flutter
import UIKit
import XCTest
class RunnerTests: XCTestCase {
func testExample() {
// If you add code to the Runner application, consider adding tests here.
// See https://developer.apple.com/documentation/xctest for more information about using XCTest.
}
}

View file

@ -0,0 +1,22 @@
import "dart:convert";
import "package:fast_immutable_collections/fast_immutable_collections.dart";
import "package:flutter_riverpod/flutter_riverpod.dart";
import "package:nexus/models/account_data.dart";
class AccountDataController extends Notifier<AccountData> {
@override
AccountData build() => .new();
void update(IMap<String, IMap<String, dynamic>> newAccountData) =>
state = .fromJson({
...json.decode(json.encode(state.toJson())),
...newAccountData
.map((key, value) => MapEntry(key, value["content"]))
.unlock,
});
static final provider = NotifierProvider<AccountDataController, AccountData>(
AccountDataController.new,
);
}

View file

@ -1,16 +0,0 @@
import "package:fast_immutable_collections/fast_immutable_collections.dart";
import "package:flutter_riverpod/flutter_riverpod.dart";
import "package:nexus/models/account_data.dart";
class AccountDataController extends Notifier<IMap<String, AccountData>> {
@override
IMap<String, AccountData> build() => const IMap.empty();
void update(IMap<String, AccountData> newData) =>
state = IMap({...state.unlock, ...newData.unlock});
static final provider =
NotifierProvider<AccountDataController, IMap<String, AccountData>>(
AccountDataController.new,
);
}

View file

@ -0,0 +1,36 @@
import "package:file_selector/file_selector.dart";
import "package:flutter_riverpod/flutter_riverpod.dart";
import "package:nexus/controllers/client.dart";
import "package:nexus/controllers/rooms.dart";
import "package:nexus/models/content/content.dart";
import "package:nexus/models/content/message.dart";
import "package:path/path.dart";
class AttachmentController(final String roomId)
extends Notifier<(String, MessageContent?)?> {
@override
Null build() => null;
Future<void> add(XFile file) async {
final filename = basename(file.path);
state = (filename, null);
final isEncrypted = ref.read(
RoomsController.provider.select(
(value) =>
value[roomId]?.state[EventType.encryption.type]?.isNotEmpty == true,
),
);
final content = await ref
.watch(ClientController.provider.notifier)
.uploadMedia(.new(path: file.path, encrypt: isEncrypted));
state = (filename, content);
}
static final provider = NotifierProvider.family
.autoDispose<AttachmentController, (String, MessageContent?)?, String>(
AttachmentController.new,
);
}

Some files were not shown because too many files have changed in this diff Show more