Compare commits

...

998 Commits
7.beta ... main

Author SHA1 Message Date
Kévin Commaille
e3c34328ee
utils: Avoid to use a temp file for decoding images when possible
By using the new API from glycin.
2025-08-13 11:45:22 +02:00
Kévin Commaille
0e9d34dd9d
Upgrade glycin
Tests the beta for GNOME 49 with the loaders in the Flatpak runtime.
2025-08-13 11:45:22 +02:00
Kévin Commaille
4597519128
utils: Simplify TokioDrop API
It is now just a wrapper.
2025-08-13 11:45:22 +02:00
Kévin Commaille
8a7c690d21
session: Do not expose Matrix client as property 2025-08-13 11:45:22 +02:00
Kévin Commaille
07cc8f9787
Upgrade matrix-sdk
Brings in fixes for sending media with the unauthenticated endpoints.
2025-08-13 10:28:28 +02:00
Kévin Commaille
2a09a76fb0
Upgrade crate dependencies
Just run `cargo update`.
2025-08-11 15:22:48 +02:00
Kévin Commaille
ddc5001a79
Release Fractal 12 2025-08-11 13:35:54 +02:00
Kévin Commaille
ae53630df3
Fix new clippy lints 2025-08-11 13:35:54 +02:00
Alexandre Franke
6f090f3883 Update French translation 2025-08-11 10:53:01 +00:00
Artur S0
b343862f35 Update Russian translation 2025-08-08 12:00:32 +00:00
Anders Jonsson
c7c9d5d974 Update Swedish translation 2025-08-06 18:29:06 +00:00
Kévin Commaille
10ed8358f9
Upgrade ruma and matrix-sdk
Brings in important bug fixes.
2025-08-06 18:40:09 +02:00
Rafael Fontenelle
0be7615056 Update Brazilian Portuguese translation 2025-08-06 01:49:36 +00:00
Ekaterine Papava
a0955e225a Update Georgian translation 2025-08-05 23:20:44 +00:00
Luming Zh
2ae6f75938 Update Chinese (China) translation 2025-08-02 00:10:48 +00:00
Davide Ferracin
420ec4d24e Update Italian translation 2025-08-01 15:53:08 +00:00
Evan Paterakis
7bd9e7fa45 notification-count: center label to background 2025-08-01 11:36:36 +00:00
Martin
e9f6873d8a Update Slovenian translation 2025-08-01 10:38:41 +00:00
Yuri Chornoivan
9dcee3a6ac Update Ukrainian translation 2025-07-31 18:28:41 +00:00
Kévin Commaille
5fb9e981b7
Release Fractal 12.rc 2025-07-31 18:50:36 +02:00
Kévin Commaille
643114867a room-history: Allow to click on sender's name to mention them 2025-07-31 16:13:32 +00:00
Kévin Commaille
879c6acf57 room-details: Warn when upgrading changes the creators of a room 2025-07-31 15:30:17 +00:00
Yuri Chornoivan
cbbab3adda Update Ukrainian translation 2025-07-30 18:56:55 +00:00
Kévin Commaille
87f3c2aff0
room-details: Do no allow to "downgrade" a room 2025-07-30 16:35:13 +02:00
Kévin Commaille
32d80497cf
room-details: Use a custom upgrade dialog 2025-07-30 16:35:12 +02:00
Martin
93061a79a0 Update Slovenian translation 2025-07-29 08:54:12 +00:00
Luming Zh
7d74ca2372 Update Chinese (China) translation 2025-07-29 01:25:07 +00:00
Kévin Commaille
5d2189a6bb
power-level-selection: Add info popover to explain the creator role 2025-07-28 14:00:39 +02:00
Kévin Commaille
d4b92ad765
login: Show offline banner when applicable during initial sync after login 2025-07-28 10:27:18 +02:00
Kévin Commaille
9a1f24ddb9
login: Remove unused LoginPage variant 2025-07-28 10:16:30 +02:00
Kévin Commaille
908f114400
Clarify the source of session restoration errors in logs 2025-07-28 10:06:21 +02:00
Luming Zh
53f35d19ed Update Chinese (China) translation 2025-07-27 00:58:49 +00:00
Martin
77fd709836 Update Slovenian translation 2025-07-26 20:18:48 +00:00
Kévin Commaille
f3d7b6c2e1
utils: Don't auto-enable backups
We want backups to be enabled at the same time as recovery.
2025-07-26 13:42:32 +02:00
Martin
94d2f562b8 Update Slovenian translation 2025-07-24 16:29:16 +00:00
Yuri Chornoivan
b68d4e2ae1 Update Ukrainian translation 2025-07-24 11:35:02 +00:00
Kévin Commaille
8cfc2e1ac7
Upgrade ruma and matrix-sdk
And add support for room version 12.
2025-07-24 12:04:22 +02:00
Martin
36bfd90672 Update Slovenian translation 2025-07-23 11:23:00 +00:00
Luming Zh
dc2618d0f4 Update Chinese (China) translation 2025-07-23 00:21:59 +00:00
Yuri Chornoivan
fa62fc4240 Update Ukrainian translation 2025-07-22 13:53:40 +00:00
Kévin Commaille
d81a70b4c6
utils: Add functions to clean up strings before using them 2025-07-21 17:36:50 +02:00
Kévin Commaille
34957f7282
room-history: Do not send read receipts if the window is not active 2025-07-21 16:14:59 +02:00
Kévin Commaille
98fc1110df
room-details: Support empty list of members with assigned power levels 2025-07-21 09:47:22 +02:00
Kévin Commaille
06cecb946e
window: Avoid showing session page every time that selected session changes
We use different objects for the different stages of initialization of
the session, so the selected item will change several times. However, if
the user switches to another page like the greeter, we don't want to
show the selected session page when it is loaded.

So this separates updating the session in the SessionView, and showing
the proper page for the session. We still show the proper page if we
were showing the loading screen or the SessionView.
2025-07-20 17:19:13 +02:00
Kévin Commaille
86061a7680
sidebar-data: Fix visibility 2025-07-20 16:33:08 +02:00
Kévin Commaille
4584c0b5ec
Move sidebar_data::Selection to utils as FixedSelection
To be able to reuse it.
2025-07-20 16:33:05 +02:00
Kévin Commaille
3673ca15e2
session-list: Always set loading state when setting error 2025-07-20 16:29:37 +02:00
Kévin Commaille
b632397022
app: Get rid of SessionIntentType 2025-07-20 16:29:37 +02:00
Ekaterine Papava
a19bf7d1e2 Update Georgian translation 2025-07-20 02:49:28 +00:00
Kévin Commaille
57ae0ef0c4
Downgrade curve25519-dalek
The current version was yanked.
2025-07-19 17:05:30 +02:00
Kévin Commaille
7f39417349
room-history: Show a banner when there are pending invite requests
And the user can accept or deny it.
2025-07-19 17:05:29 +02:00
Kévin Commaille
4625b5bb97
session: Allow to knock on a room in explore view and room preview 2025-07-19 17:05:29 +02:00
Kévin Commaille
bfcf5550cf
sidebar: Show our invite requests 2025-07-19 17:05:29 +02:00
Kévin Commaille
b672f52bf8
room-details: Allow to change join rule to knock 2025-07-19 17:05:29 +02:00
Kévin Commaille
25f2dc1cc8
components: Add dialog to ask what to do about unsaved changes
To reduce code duplication and be consistent about the wording.
2025-07-19 17:05:29 +02:00
Kévin Commaille
454f3e15ae
room-details: Be consistent about wording around knock feature
Always talk about requesting an invite
2025-07-19 17:05:29 +02:00
Kévin Commaille
83ca3e8a2b
sender-avatar: Remove action to deny invite request
We don't show an avatar for invite requests, so it's very unlikely to
ever appear.
2025-07-19 17:05:29 +02:00
Kévin Commaille
f526ad5d6b
room-details: Show the list of users that knocked on the room 2025-07-19 17:05:29 +02:00
Kévin Commaille
fecf32f3c6
session: Move membership lists to MemberList
Allows to reuse the same list filtered by membership in several places.

We also use an enum that is a subset of Membership for identifying the
lists, allowing to do exhaustive matches, which will catch when new
variants are added.
2025-07-19 17:05:28 +02:00
Kévin Commaille
34ad0aae0f
utils: Allow to change item in SingleItemListModel 2025-07-19 17:05:28 +02:00
Kévin Commaille
f07ee800a8
user-page: Be consistent about wording around knock feature
Always talk about requesting an invite.
2025-07-19 17:05:28 +02:00
Martin
47acd98a6b Update Slovenian translation 2025-07-19 09:24:27 +00:00
Yuri Chornoivan
94b4b5c4b1 Update Ukrainian translation 2025-07-19 06:01:18 +00:00
Luming Zh
99a7fdb9bd Update Chinese (China) translation 2025-07-18 23:38:59 +00:00
Anders Jonsson
c3bb69aaed message-dialogs: Fix typo 2025-07-17 16:30:38 +02:00
Kévin Commaille
0a92b9772a
room-details: Ask to confirm some changes in PermissionsMemberRow
When muting, promoting to the same level as our own user, or demoting
oneself like on the UserPage.
2025-07-17 12:27:45 +02:00
Kévin Commaille
edf6f80adc
room-details: Ask to confirm some changes in PermissionsAddMembersSubpage
When muting or promoting to the same level as our own user, like on the
UserPage.
2025-07-17 12:27:45 +02:00
Kévin Commaille
87406c1278
room-details: Only show members with default PL in view to add custom PLs
It is more consistent with the wording that way.
2025-07-17 12:27:45 +02:00
Kévin Commaille
c5d7b4d6e7
room-details: Fix member selection not toggled when using PermissionsSelectMemberRow checkbox
It only worked when activating the full row.
2025-07-17 12:27:45 +02:00
Kévin Commaille
8c7b452b1f
user-page: Allow to change own power level and ask for confirmation 2025-07-17 12:27:45 +02:00
Kévin Commaille
d3ce661865
Upgrade ruma and matrix-sdk
This upgrade is more about Ruma, to test the main branch that contains
several breaking changes before it is released.
2025-07-14 20:35:41 +02:00
Kévin Commaille
ab2f70a258 build: Remove ffmpeg-full extension
It is not compatible with the 25.08beta freedesktop.org runtime base.
It was replaced by the codecs-extra extension which is auto-downloaded
with the runtime.
2025-07-14 10:33:30 +00:00
Kévin Commaille
12e2c9cbfb
Upgrade matrix-sdk
To the new release.
2025-07-10 16:46:05 +02:00
Aefgh Threenine
431d849bcd Update Thai translation 2025-07-09 16:24:41 +00:00
Anders Jonsson
4319c3160b Update Swedish translation 2025-07-08 16:38:42 +00:00
Kévin Commaille
9299056daa
ci: Upgrade cargo-nextest 2025-07-08 15:09:33 +02:00
Kévin Commaille
81900cdc6d
Upgrade matrix-sdk
And run `cargo update`.
2025-07-08 15:09:33 +02:00
Kévin Commaille
ca1599296c
Update manifest, CI and instructions for 25.08beta runtime base 2025-07-07 18:05:35 +02:00
Kévin Commaille
b4bcb46fae
Port to Rust 2024 2025-06-29 17:44:20 +02:00
Kévin Commaille
591026c65c Upgrade matrix-sdk
And run cargo update.
2025-06-29 14:45:57 +00:00
Kévin Commaille
4b1b3fb12b Upgrade glycin-loaders to 1.2.2 2025-06-29 14:45:57 +00:00
Daniel Rusek
a089732ba2 Update Czech translation 2025-06-26 13:06:25 +00:00
Álvaro Burns
f9b1f23b11 Update Brazilian Portuguese translation 2025-06-26 11:39:40 +00:00
Kévin Commaille
4a65b1cb29
docs: Update Flathub instructions 2025-06-26 11:03:20 +02:00
Kévin Commaille
b31f4ff67b
Release Fractal 12.beta 2025-06-26 09:04:39 +02:00
Luming Zh
938396b500 Update Chinese (China) translation 2025-06-25 11:22:49 +00:00
Martin
1006b9b2b4 Update Slovenian translation 2025-06-24 18:51:50 +00:00
Yuri Chornoivan
1c27842ab3 Update Ukrainian translation 2025-06-24 17:44:43 +00:00
Kévin Commaille
0eec6d8189
room-history: Display the sender of membership change events 2025-06-24 10:01:31 +02:00
Kévin Commaille
3f611f7ca2
message-toolbar: Use the sender of the tombstone event for routing the successor room
We shouldn't use the server name in the room ID, it is supposed to be an
opaque string and the `!localpart:server_name` format might change.
2025-06-21 13:47:34 +02:00
Baxrom Raxmatov
aaf145feb7 Add Uzbek (Latin) translation 2025-06-21 09:02:09 +00:00
David Akopov
3a6628adea
sidebar-section: signal aggregate notification count & highlight changes
Add notification-count, highligh and has-notifications properties to the
sidebar section model and signal on corresponding changes.
Aggregation is done as follows:
  is-read := conjunction_over_all_rooms_in_section(is-read)
  highligh := union_over_rooms_in_section(highligh)
  has-notification := any_over_rooms(has-notifications)
  notification-count := sum_over_rooms_in_section(notification-count)

Functionality of ExpressionList is reused on one of the intermediate
models to populate watches (internally on the underlying model) and signal
change of notification-count or highlight with the room indices.
This implementation recalculates the aggregate expressions via
naive iterations (discarding exactly which room(s)' values  were
changed).

UI state bits are reflected accordingly to consume the signalled changes.

Fixes: #1048
2025-06-20 21:31:33 +04:00
Kévin Commaille
a213ec8467
Release Fractal 11.2 2025-06-10 17:44:19 +02:00
Kévin Commaille
85bcfc74bc
Upgrade matrix-sdk
Use the newly released version.
2025-06-10 14:29:44 +02:00
Rafael Fontenelle
59c6e88311 Update Brazilian Portuguese translation 2025-06-08 01:18:31 +00:00
Luming Zh
37c8490abc Update Chinese (China) translation 2025-05-29 23:14:03 +00:00
Juliano de Souza Camargo
7f687871b7 Update Brazilian Portuguese translation 2025-05-29 12:19:26 +00:00
Yuri Chornoivan
da49563c35 Update Ukrainian translation 2025-05-28 19:34:41 +00:00
Martin
b31d74e8ba Update Slovenian translation 2025-05-28 18:11:52 +00:00
Kévin Commaille
d65fbacac6
room-history: Replace ratio character with colon in timestamps
Apparently using the ratio character can create issues for RTL languages.
2025-05-28 13:05:32 +02:00
Kévin Commaille
58ebb7e3bc
room-history: Add back support for redacted messages
We need it in case of replies to a redacted message.
2025-05-28 10:50:37 +02:00
Kévin Commaille
d025f24928
media-viewer: Allow to show a media without an event ID 2025-05-28 10:34:12 +02:00
Yuri Chornoivan
56a82d7cbf Update Ukrainian translation 2025-05-28 06:14:33 +00:00
Kévin Commaille
655676de7e
sidebar: Allow to mark a room as unread 2025-05-27 11:20:44 +02:00
Ekaterine Papava
44ea6d38ac Update Georgian translation 2025-05-25 01:59:45 +00:00
Luming Zh
e69bc3efaf Update Chinese (China) translation 2025-05-25 00:47:38 +00:00
Yuri Chornoivan
e903be2564 Update Ukrainian translation 2025-05-24 15:41:56 +00:00
Martin
b0dd62a90b Update Slovenian translation 2025-05-23 22:37:09 +00:00
Kévin Commaille
774f4b4690 ci: Fix cargo-sort check 2025-05-23 12:08:11 +00:00
Kévin Commaille
3388795df5 session: Synchronize the media previews safety settings with the Matrix account data
To share the setting between clients.
2025-05-23 12:08:11 +00:00
Kévin Commaille
59b6740ce5 account-settings: Refactor NotificationsPage 2025-05-23 12:08:11 +00:00
Kévin Commaille
4f573e54d4 Upgrade matrix-sdk 2025-05-23 12:08:11 +00:00
Luming Zh
134d271f68 Update Chinese (China) translation 2025-05-23 11:13:55 +00:00
Kévin Commaille
e1452fcda4
invite: Refactor and fix visibility 2025-05-21 12:41:29 +02:00
Kévin Commaille
edac9e3381
room-history: Make sure that mentions respect safety settings
Gets rid of a potential attack factor.
2025-05-21 12:25:04 +02:00
Kévin Commaille
366a602260
Upgrade matrix-sdk dependency 2025-05-20 11:11:28 +02:00
Álvaro Burns
45ee641a78 Update Brazilian Portuguese translation 2025-05-19 11:31:53 +00:00
Daniel Rusek
f7370be6a5 Update Czech translation 2025-05-19 11:26:23 +00:00
Kévin Commaille
2dd845f7e0
ci: Include flatpak template as a project rather than URL
It might get rid of the 429 errors.
2025-05-19 10:06:33 +02:00
Kévin Commaille
8ccb67cb8a
build: Enable frame pointers for Rust modules
It seems to be necessary to build the aarch64 flatpak in CI, and it
doesn't hurt anyway.
2025-05-19 09:55:35 +02:00
Kévin Commaille
0931854b98
Revert "ci: Allow failure of aarch64 jobs"
This reverts commit 69dde233e43179e4515df9c1875805af1642e082.
2025-05-19 09:50:05 +02:00
Sabri Ünal
9697badf22 Update Turkish translation 2025-05-18 16:44:26 +00:00
Martin
679c29069d Update Slovenian translation 2025-05-18 15:53:59 +00:00
Yuri Chornoivan
76b92815b0 Update Ukrainian translation 2025-05-18 15:23:58 +00:00
Kévin Commaille
e5ed751c1f
notifications: Fix notifications for invites
There was a race condition where we would not be able to show the invite
for a room because we didn't have the room yet in the room list.
2025-05-18 12:08:21 +02:00
Kévin Commaille
b84a584995
account-settings: Add safety setting to hide avatars in invites
For consistency, we also hide avatars for invites that were rejected or
retracted, if we manage to find that out for left rooms.
2025-05-18 11:26:02 +02:00
Kévin Commaille
6035b4ee37
misc: Fix new clippy warnings 2025-05-16 18:28:51 +02:00
Álvaro Burns
5bd1122a2b Update Brazilian Portuguese translation 2025-05-16 10:49:43 +00:00
Luming Zh
cc028458bd Update Chinese (China) translation 2025-05-16 09:06:43 +00:00
Kévin Commaille
b9757404e3
Release Fractal 11.1 2025-05-15 10:47:45 +02:00
Ekaterine Papava
ecc9eab92e Update Georgian translation 2025-05-15 03:44:46 +00:00
Martin
6649018303 Update Slovenian translation 2025-05-14 17:31:01 +00:00
Yuri Chornoivan
d7032bf945 Update Ukrainian translation 2025-05-14 13:03:27 +00:00
Kévin Commaille
e5f473d9b6
user-facing-error: Reduce the size of some strings that appear in toasts 2025-05-14 12:00:51 +02:00
Kévin Commaille
ec56f9471c
ci: Allow to interrupt most jobs 2025-05-13 15:15:34 +02:00
Yuri Chornoivan
65531c7870 Update Ukrainian translation 2025-05-13 12:47:33 +00:00
Kévin Commaille
ca387e3261
account-switcher: Make sure to unparent the popover when the button is disposed of
Avoids a warning that occurs sometimes when closing Fractal.
2025-05-13 12:18:54 +02:00
Kévin Commaille
4a5a4b4cde
room-history: Ignore empty inline elements when ellipsizing to a single line 2025-05-13 11:31:29 +02:00
Martin
94d2cdf81d Update Slovenian translation 2025-05-12 20:48:50 +00:00
Kévin Commaille
97e051235d
Upgrade matrix-sdk
And cargo update other crates.
2025-05-12 19:09:10 +02:00
Kévin Commaille
c85d6462b5
room-history: Update strings for creation event 2025-05-12 13:45:38 +02:00
Kévin Commaille
893f795228
room-history: Remove banner for tombstoned rooms
Instead we offer to join or view the new room instead of showing the
composer.

This also makes sure that the state of the Join/View button is updated
depending on the joining state of the successor.
2025-05-12 13:45:38 +02:00
Kévin Commaille
9f426e2c6d
message-toolbar: Fix style of text when user cannot send a message
Works better on narrow screens.
2025-05-12 13:45:38 +02:00
Kévin Commaille
8b3b816005
room-history: Do not show room tombstone event in history
There is already a banner for this so when both are visible it looks
weird to have a duplicate.
2025-05-12 13:45:38 +02:00
Kévin Commaille
41fb45cd90
explore: Fix and refactor
Use a GListStore for the list of rooms, and RemoteRoom to represent the
rooms.

Fix cleaning server popover when switching between sessions, and make
sure that triggering a search only happens when the view is mapped.
2025-05-12 12:28:46 +02:00
Kévin Commaille
793907383a room-preview-dialog: Update button according to current state of room
It was only updated depending on what happened in the dialog. Now it
also updates depending on what happens in the room list.
2025-05-11 09:35:27 +00:00
Kévin Commaille
76b3559dfe room-list: Rename room_list_metainfo file 2025-05-11 09:35:27 +00:00
Kévin Commaille
e51a8d73aa room-list: Rename pending rooms to joining rooms
"Pending" was not very clear about what it meant for a room to be in
that list.
2025-05-11 09:35:27 +00:00
Philipp Bartsch
8e2118dc67 media-viewer: halign the right-click context menu
Other right-click context menus are not centered on the cursor.
2025-05-10 14:25:58 +02:00
Kévin Commaille
cc1e231297
message-toolbar: Fix inserting mention before another mention 2025-05-09 10:19:55 +02:00
Kévin Commaille
7cf3823bea
room-history: Increase padding of SenderAvatar
Makes the hover effect around the avatar bigger, which makes it more
obvious that it behaves like a button.
2025-05-09 09:51:34 +02:00
Kévin Commaille
338c732e5f
event: Do not count unsent events as unread or as activity 2025-05-08 09:42:41 +02:00
Kévin Commaille
c646ca611b
account-settings: Fix renamed page name 2025-05-07 10:56:54 +02:00
Kévin Commaille
b79ddd453d
overlapping-avatars: Remove unnecessary debug logging 2025-05-07 10:28:51 +02:00
Kévin Commaille
5158e408d7
utils: Simplify truncate_end_whitespaces
Work with char_indices, it allows us to compute the index after the char
easily.
2025-05-07 10:25:34 +02:00
Kévin Commaille
a0aec0b176
room-history: Remove whitespaces before newlines in HTML messages 2025-05-07 10:25:00 +02:00
Kévin Commaille
0bf579e4b0
room-history: Fix jittery media during transition from loading to showing the media 2025-05-07 10:01:13 +02:00
Kévin Commaille
75d41ee146
overlapping-avatars: Use GtkSliceListModel to limit the number of avatars
That way we don't need our custom code to cap the number of avatars that
we present, which seems to have an error.
2025-05-06 18:03:19 +02:00
Kévin Commaille
d161a58424
ci: Don't build unnecessary Flatpak modules when they are not needed 2025-05-05 15:17:32 +02:00
Kévin Commaille
e76cf4097f utils: Re-enable event cache storage 2025-05-05 11:00:59 +00:00
Kévin Commaille
0092ae1e30 Upgrade matrix-sdk 2025-05-05 11:00:59 +00:00
Kévin Commaille
0ed68fd993 docs: Update Flathub instructions in RELEASING.md 2025-05-05 09:53:39 +00:00
Kévin Commaille
69dde233e4
ci: Allow failure of aarch64 jobs
There are issues currently with the only flatpak-arch64 CI runner that
prevents us from merging anything.

This means that the nightly aarch64 Flatpak will not be updated as long
as the problem is not fixed.
2025-05-05 11:25:10 +02:00
Kévin Commaille
7f3fe72503
camera: Fix crash in LinuxCamera::has_cameras()
`timeout` needs to be called in an async block to make the future "lazy",
so that it is executed on the tokio runtime.
2025-05-05 11:11:08 +02:00
Jiri Grönroos
0b5809b07d Update Finnish translation 2025-05-04 19:37:05 +00:00
Kévin Commaille
ebd7d029cf Release Fractal 11 2025-05-02 12:57:09 +00:00
Alexandre Franke
04c1df671d Update French translation 2025-05-01 09:04:40 +00:00
Kévin Commaille
862fc14744
room-history: Show focus ring around visual media 2025-04-28 15:53:20 +02:00
Kévin Commaille
eeff96e1db
room-history: Remove whitespaces at the beginning and end of HTML elements
To have the same behavior as in browsers.
2025-04-28 13:31:48 +02:00
Kévin Commaille
eea9e9122e
room-history: Be consistent about compact visual content activation
It was already not possible with the mouse, but there was still a hover
effect, and the key bindings where still working.
2025-04-28 12:27:23 +02:00
Kévin Commaille
537d31521b
utils: Replace remove_newlines with collapse_whitespace
In HTML, contiguous whitespaces must be replaced by a single space, not
removed.
2025-04-25 12:06:48 +02:00
Kévin Commaille
73989239b9
sidebar-data: Fix visibility 2025-04-25 10:30:08 +02:00
Kévin Commaille
67a12518bd
room-history: Add spaces instead of newlines in topic 2025-04-25 10:06:12 +02:00
Kévin Commaille
0cc9ed3ae9
user: Refactor and clean up 2025-04-25 09:50:46 +02:00
Kévin Commaille
72c44056b2
utils: Make data_dir_path a method of DataType
It reduces the necessary imports.
2025-04-25 09:20:44 +02:00
Kévin Commaille
5891f28548
utils: Remove timeout_future
Use the function provided by tokio instead.
2025-04-25 09:15:12 +02:00
Kévin Commaille
efe9189d76
session: Cache room and user profile in memory
Reduces the number of requests to the homeserver.
2025-04-24 15:31:00 +02:00
Kévin Commaille
108174e040
session: Sleep between failed sync attempts 2025-04-24 09:40:39 +02:00
Kévin Commaille
782889079f
room-history: Edit latest message when pressing the up key in an empty composer 2025-04-23 12:49:18 +02:00
Kévin Commaille
de4772bf1e
message-toolbar: Do not allow to send message with only whitespace 2025-04-23 12:49:18 +02:00
Kévin Commaille
30269e7dde
message-toolbar: Capture key presses even if CapsLock is enabled 2025-04-23 12:49:18 +02:00
Kévin Commaille
828fa2e91d window: Show button to open About dialog on error page 2025-04-23 08:30:28 +00:00
Artur S0
39cb8ca758 Update Russian translation 2025-04-22 15:20:15 +00:00
Kévin Commaille
d60117236f
resources: Update SVG to use Adwaita Sans font 2025-04-22 13:05:52 +02:00
Kévin Commaille
4b30e5f6f2
room-history: Add context menu action on invites to be able to revoke them 2025-04-22 12:44:20 +02:00
Kévin Commaille
22a6f63230
room-details: Refactor code for extra items in the list of joined members
Fixes bug where they would not appear anymore.
2025-04-22 11:43:16 +02:00
Kévin Commaille
b7b309f1d4
room-history: Only show timestamp when too much time has passed between events
Instead of the full header with name and avatar
2025-04-22 10:13:23 +02:00
Kévin Commaille
64bf58e2ea
timeline: Show event header again if too much time has passed since previous event 2025-04-21 14:17:10 +02:00
Kévin Commaille
5ca1b6a3e7
session-view: Do not center ScaleRevealer
It allows text to take as much space as it wants instead of its minimum
size.
2025-04-21 12:53:08 +02:00
Kévin Commaille
6813a4c98e
components: Reduce minimal height of PillSearchEntry
Since there have been measuring fixes in GTK and it doesn't grow
excessively anymore when we insert a pill.
2025-04-21 12:05:27 +02:00
Kévin Commaille
09e3ec218e
room-details: Rename invite-search-results class
Since it is not only used in the invite subpage.
2025-04-21 11:59:44 +02:00
Kévin Commaille
2122882f37
room-details: Make sure search entry is focused when opening subpage and it is the main widget 2025-04-21 11:55:01 +02:00
Kévin Commaille
21b5cd056e
room-history: Make sure there is enough space for overlays on small media 2025-04-21 10:04:48 +02:00
Kévin Commaille
97a528c5d3
account-settings: Always disconnect session via account management URL when it is available
A homeserver that supports the OAuth 2.0 API doesn't allow to disconnect
a session via the Matrix API, even if the session was connected before
the move to the OAuth 2.0 API.
2025-04-21 09:28:59 +02:00
Yuri Chornoivan
bca6fd7f67 Update Ukrainian translation 2025-04-20 12:53:57 +00:00
Kévin Commaille
5307cb1fe0
notifications: Truncate body if it is too long
This avoids performance issues with GNOME Shell.
2025-04-20 12:27:05 +02:00
Kévin Commaille
21b6e3b74b
room-history: Fix enabling and disabling copy-image action
We now track all the way down if there is currently a texture and
update whenever the texture is added/removed.

This prevents a race condition when the image is loaded before the child
is added to its parent and works with showing and hiding media previews
too.
2025-04-20 11:04:54 +02:00
Kévin Commaille
426b99ec73
utils: Add extension trait for reusing child widget
There would be less duplication if Rust allowed generic implementations
with different bounds. Oh well…
2025-04-20 09:18:58 +02:00
Ekaterine Papava
b5ef87f99f Update Georgian translation 2025-04-20 02:42:51 +00:00
Kévin Commaille
57941187dd
utils: Fix loading animated images in encrypted rooms 2025-04-19 15:03:32 +02:00
Kévin Commaille
10776c0f52
room-details: Respect media previews safety setting for media history viewer
Do not show the previews if they are not shown in the room history.

This also adds support for blurhashes.
2025-04-19 14:56:09 +02:00
Kévin Commaille
5ea7f82c2f
room-history: Add support for Blurhashes
It is displayed while the media is being downloaded, or instead of the
preview if the preview is hidden.
2025-04-19 13:13:15 +02:00
Kévin Commaille
5ef500e916
build: Disable grass submodules
It seems that they are only necessary for some tests, that we don't run.
2025-04-18 15:30:22 +02:00
Kévin Commaille
5c774ceccc
build: Properly clean up grass
This is the right way, removing all files generated by the module.
2025-04-18 13:32:47 +02:00
Kévin Commaille
16661287c3
utils: Don't send items-changed signal for new groups in GroupingListModel
Sending the items-changed signal for groups after signalling that the
group was added results in duplicates for APIs that only care about that
signal, not about the actual number of items.
2025-04-18 13:32:47 +02:00
Anders Jonsson
c8015d121d Update Swedish translation 2025-04-17 15:30:33 +00:00
Kévin Commaille
8a88b7fb07
build: Properly clean up grass 2025-04-17 16:31:30 +02:00
Daniel Rusek
cebd738569 Update Czech translation 2025-04-17 13:06:13 +00:00
Luming Zh
71e4f016dd Update Chinese (China) translation 2025-04-17 10:47:13 +00:00
Yuri Chornoivan
6616969582 Update Ukrainian translation 2025-04-17 10:14:18 +00:00
Kévin Commaille
c5325049f6
Release Fractal 11.rc 2025-04-17 10:59:31 +02:00
Kévin Commaille
b7c45229d0
flatpak: Properly clean up grass 2025-04-17 09:45:48 +02:00
Martin
8a7e0fe8ff Update Slovenian translation 2025-04-17 06:29:14 +00:00
Kévin Commaille
cb6c0ecffe room-history: Fix justification of text in media preview placeholder 2025-04-16 20:08:04 +00:00
Kévin Commaille
865733b151 Upgrade glycin 2025-04-16 20:08:04 +00:00
Álvaro Burns
67f6808f6d Update Brazilian Portuguese translation 2025-04-16 20:00:12 +00:00
Kévin Commaille
e0a7eb4cd1
room-history: Group contiguous state events
They are replaced by an item that shows the count of state rows that
are hidden. This item can be expanded to show all the hidden state rows.
2025-04-16 18:12:06 +02:00
Kévin Commaille
316e7296e4
misc: Fixes
Small unrelated fixes
2025-04-16 15:56:19 +02:00
Kévin Commaille
da2e81fbdb
timeline: Clean up TimelineItem API
Remove the `selectable` property which is not used, and move properties
about the header to Event, which is the only child type using it.
2025-04-16 15:33:00 +02:00
Kévin Commaille
4372f80a6b
room-history: Replace ItemRow by more specific widgets
It is now basically the new EventRow, since only events have a context
menu.

All the widgets that can be direct children of GtkListItem use the
`room-history-row` class for CSS styling.
2025-04-16 15:33:00 +02:00
Kévin Commaille
93ccda449f
utils: Rename DummyObject to PlaceholderObject
"dummy" can be viewed as offensive
2025-04-16 15:33:00 +02:00
Yuri Chornoivan
9396a8b036 Update Ukrainian translation 2025-04-15 17:38:20 +00:00
Kévin Commaille
213b5bd5dd account-settings: Add safety setting to choose which rooms should show media previews
It is a global choice between all rooms, only private rooms, or no
rooms.
2025-04-15 12:00:59 +00:00
Daniel Rusek
d29766fad5 Update Czech translation 2025-04-15 11:20:39 +00:00
Yuri Chornoivan
930ab34755 Update Ukrainian translation 2025-04-15 10:11:02 +00:00
Kévin Commaille
25c79797d1
account-settings: Reorganize
The main goal here is to move safety-related settings to a new tab so
we can add more in the future.

Since we do not want more tabs, we have to:

- Move the sessions to a subpage accessible with a button in the
"General" tab. While we are here, we reorder most of this tab.
- Move the settings that were in the "Privacy" section of the "Security"
tab to a new "Safety" tab.
- Rename the "Security" tab to "Encryption", to avoid confusion between
"Security" and "Safety".
2025-04-14 18:08:16 +02:00
Daniel Rusek
f07d350628 Update Czech translation 2025-04-13 11:14:37 +00:00
Kévin Commaille
5c9f9a2aff
Upgrade protobuf-c
Use new release.
2025-04-11 12:36:27 +02:00
Kévin Commaille
69da78094c
matrix: Disable event cache storage 2025-04-11 12:15:03 +02:00
Kévin Commaille
163fe968f2
Upgrade matrix-sdk
Use new release
2025-04-11 12:10:52 +02:00
Álvaro Burns
d702e0bb56 Update Brazilian Portuguese translation 2025-04-09 12:44:19 +00:00
Kévin Commaille
2c66f77be7
notifications: Use same algorithm as libadwaita to find initials
To avoid avatar discrepancies between the window and the notifications.
2025-04-08 17:30:30 +02:00
Kévin Commaille
15f21d1467
timeline: Filter timeline start item if we have room create event
The code was removed when the SDK was updated recently, because the SDK
now provides the timeline start item, so the logic had to change. This
re-adds the old code and adapts it to filter the SDK items.
2025-04-08 16:42:13 +02:00
Kévin Commaille
d870c1497d
misc: Use SingleItemListModel where possible
Instead of GListStore.
2025-04-08 16:03:37 +02:00
Ekaterine Papava
7a1d8ffa19 Update Georgian translation 2025-04-08 02:38:26 +00:00
Kévin Commaille
a2cc7999c3
verification: Refactor and clean up 2025-04-07 16:19:10 +02:00
Kévin Commaille
8e623c55c4
notifications: Refactor and clean up
Fixes a regression where clicking on notifications would not open the
app anymore.
2025-04-07 15:40:42 +02:00
Kévin Commaille
834a06612a
Upgrade crates
Gets rid of tokio advisory
2025-04-07 14:01:35 +02:00
Kévin Commaille
d63a96c509
utils: Allow to get the JoinHandle of the spawn! macro
That way the result of the task can be `.await`ed if wanted.
2025-04-06 12:10:11 +02:00
Kévin Commaille
3dc3333d99
Bump Rust version
To match the version from the matrix-sdk crates.
2025-04-06 12:10:10 +02:00
Kévin Commaille
c46404cbbf
utils: Refactor toast macro
Simplify the rules for using the macro:

- The message must always implement `AsRef<str>`,
- The variables values must implement `ToString`,
- Trailing commas are always optional.

Use functions for code that doesn't actually need to be in the macro,
it allows to have linting of the code.
2025-04-06 12:10:10 +02:00
Kévin Commaille
b2dd3acd08
system-settings: Refactor 2025-04-06 12:10:10 +02:00
Kévin Commaille
da8fb3b112
room-details: Refactor and clean up 2025-04-06 12:10:10 +02:00
Kévin Commaille
065e139126
utils: Refactor and clean up 2025-04-06 12:10:10 +02:00
Kévin Commaille
25b7b1603b
remote-room: Refactor and clean up 2025-04-06 12:10:10 +02:00
Kévin Commaille
3a6416f1b3
failed-session: Refactor 2025-04-06 12:10:10 +02:00
Kévin Commaille
194beff585
account-settings: Refactor and clean up 2025-04-06 12:10:10 +02:00
Yuri Chornoivan
3d0c9a78e7 Update Ukrainian translation 2025-04-06 06:52:04 +00:00
Martin
77d1c8a846 Update Slovenian translation 2025-04-06 06:45:42 +00:00
Luming Zh
b7eaa606bc Update Chinese (China) translation 2025-04-06 03:16:26 +00:00
Kévin Commaille
b577acb584
Add support for logging in with the OAuth 2.0 API 2025-04-05 20:28:26 +02:00
Kévin Commaille
9f9b0129f0
Upgrade crate dependencies
To get rid of the cargo-deny advisory.
2025-04-05 19:38:15 +02:00
Martin
c1a669a9a2 Update Slovenian translation 2025-04-05 16:30:42 +00:00
Yuri Chornoivan
14edc8d9fa Update Ukrainian translation 2025-04-05 14:42:18 +00:00
Titouan Real
41ab799c37 user-session-page: Fix toast string 2025-04-05 07:00:21 +00:00
Titouan Real
d7b79251e1 general: Remove debug repr in error log 2025-04-05 07:00:21 +00:00
Titouan Real
d427026b5b user-session-page: Allow the user to set the display name 2025-04-05 07:00:21 +00:00
Titouan Real
49f2f71e61 misc: Fix new clippy lint 2025-04-04 22:26:30 +02:00
Titouan Real
8af7a922e3 Address RUSTSEC-2025-0022
https://rustsec.org/advisories/RUSTSEC-2025-0022
2025-04-04 22:22:26 +02:00
Kévin Commaille
a263904386
explore: Adapt header if the window is too narrow
If the window is too narrow, the search entry moves below the servers
button.
2025-04-01 15:30:54 +02:00
Kévin Commaille
e0f8bd5c28
explore: Refactor and clean up 2025-04-01 12:35:39 +02:00
Kévin Commaille
8a78a7a3bf Revert "utils: Do not enable event cache storage"
This reverts commit 37fc796c9ce979cb0c23876be9425322df10024b.
2025-03-31 09:06:35 +00:00
Kévin Commaille
5c66a39c0c build: Clean up flatpak manifest 2025-03-31 09:06:35 +00:00
Kévin Commaille
48f569f327 account-settings: Use SDK's OAuth methods rather than implementing our own 2025-03-31 09:06:35 +00:00
Kévin Commaille
a137928496 Upgrade matrix-sdk 2025-03-31 09:06:35 +00:00
Artur S0
8285bc794b Update Russian translation 2025-03-30 08:40:46 +00:00
Brage Fuglseth
fa51da6393 Update Norwegian Bokmål translation 2025-03-29 17:24:31 +00:00
Daniel Rusek
e708570703 Update Czech translation 2025-03-28 23:02:44 +00:00
Álvaro Burns
d63d5c229b Update Brazilian Portuguese translation 2025-03-28 12:42:43 +00:00
Kévin Commaille
9566d14940
join-room-dialog: Rename to RoomPreviewDialog 2025-03-27 16:29:04 +01:00
Kévin Commaille
121219e539
create-dm-dialog: Rename to CreateDirectChatDialog, refactor and clean up 2025-03-27 16:29:04 +01:00
Kévin Commaille
2c84f96d46
room-creation: Rename to CreateRoomDialog, refactor and clean up 2025-03-27 16:29:04 +01:00
Kévin Commaille
a0fb433fd2
room-list: Refactor and clean up 2025-03-27 16:29:04 +01:00
Kévin Commaille
8eeb955746
window: Refactor and clean up 2025-03-27 16:29:04 +01:00
Kévin Commaille
fba0195977
application: Refactor 2025-03-27 16:29:04 +01:00
Kévin Commaille
d78a59dfed
application: Simplify intents 2025-03-27 16:29:04 +01:00
Kévin Commaille
e7727a4b82
session-view: Refactor and clean up 2025-03-27 11:04:26 +01:00
Kévin Commaille
f513aa5f8b
Release Fractal 11.beta 2025-03-27 09:05:25 +01:00
Kévin Commaille
ed66251c10
session-view: Fix focus behavior when selected item in sidebar changed
Make sure to always focus a widget in the visible page if possible.
2025-03-26 18:54:56 +01:00
Kévin Commaille
7b425eef0e
content: Refactor 2025-03-26 18:54:56 +01:00
Kévin Commaille
2a5da4b12e
event-details-dialog: Add button to open sender profile instead of copying the user ID 2025-03-26 18:54:55 +01:00
Kévin Commaille
2e1bfefde6
timeline: Show sender for unable to decrypt events 2025-03-26 15:44:27 +01:00
Kévin Commaille
cb921ac21e
window: Make sure offline banner is at the top of loading screen 2025-03-26 15:41:18 +01:00
Kévin Commaille
37fc796c9c utils: Do not enable event cache storage
It still has issues that we don't want to have in the beta
2025-03-26 10:36:53 +00:00
Kévin Commaille
384a80afbb Upgrade matrix-sdk 2025-03-26 10:36:53 +00:00
Luming Zh
72ea4095c9 Update Chinese (China) translation 2025-03-26 10:07:02 +00:00
Martin
eab4d059f1 Update Slovenian translation 2025-03-25 22:03:27 +00:00
Kévin Commaille
b57f072c22 session: Log the session ID 2025-03-25 21:21:56 +00:00
Kévin Commaille
b1050a555a session: Make sure a single network check per session is running at a time
If there are a lot of network state changes, we can have several
requests at once. The first will succeed but the other ones will timeout
and we will end up offline although there is nothing wrong with the
network.

To prevent that, we use a Mutex so only one requests is made at a time.

We also schedule another check if the network is fine but the server is
unreachable.
2025-03-25 21:21:56 +00:00
Yuri Chornoivan
73d9a142a8 Update Ukrainian translation 2025-03-25 21:05:23 +00:00
Kévin Commaille
be97fb5d03
identity-verification-view: Use AdwWrapBox
When there are 2 buttons to accept or cancel, use AdwWrapBox to show
them next to each other or one on top of the other, depending on the
available space.
2025-03-25 16:57:16 +01:00
Kévin Commaille
ad8d43667e
auth-dialog: Refactor to keep the dialog open until all stages are done
This is now an AdwDialog that look like an AlertDialog, but with a
GtkStack to switch between the different stages.

It also supports the OAuth 2.0 cross-signing reset stage provided by the
SDK.
2025-03-25 16:04:08 +01:00
Kévin Commaille
c55e39a640
Revert "Downgrade oo7"
This reverts commit 2f107332fd8e537284d9db0637be0c09e2aa6aa4.
2025-03-21 16:56:04 +01:00
Kévin Commaille
cd1b8419dc
Upgrade crate dependencies 2025-03-21 16:53:56 +01:00
Alexandre Franke
af780758e9 Port to libadwaita 1.7 2025-03-20 15:27:41 +01:00
Adrien Plazas
dea4ca177a window: Correctly center a label 2025-03-20 09:06:22 +01:00
Kévin Commaille
a7d41b9f99 ci: Bump GNOME stable version
Use GNOME 48
2025-03-19 17:18:52 +00:00
Harry Bond
aabae3d500 account-switcher: Make the account-switcher button circular 2025-03-19 15:59:14 +00:00
Kévin Commaille
499f9f9370
Upgrade dependencies 2025-03-19 13:19:43 +01:00
Artur S0
54b4540d32 Update Russian translation 2025-03-14 11:29:21 +00:00
Kévin Commaille
5a1cc6497e
Upgrade matrix-sdk 2025-03-14 10:07:15 +01:00
Álvaro Burns
03d27d222d Update Brazilian Portuguese translation 2025-03-11 23:02:32 +00:00
Kévin Commaille
694a07bfec
Upgrade matrix-sdk 2025-03-11 17:43:55 +01:00
Kévin Commaille
84b5d8f50e
ci: Ignore new advisory 2025-03-11 17:43:33 +01:00
Álvaro Burns
b509d80b9f Update Brazilian Portuguese translation 2025-03-11 12:05:56 +00:00
Kévin Commaille
2941169b80
timeline: Add TRACE level log for timeline initial items 2025-03-10 14:41:21 +01:00
Kévin Commaille
33edfe65cf
Upgrade matrix-sdk 2025-03-10 12:54:59 +01:00
Kévin Commaille
6b8c6db53d
Revert "ci: Use a previous commit of rust-nightly for building docs"
This reverts commit 8cc9b6c705f6d8908a2596ef617a0aedf569cc03.
2025-03-09 12:22:59 +01:00
Titouan Real
9ea87bd5a3 misc: Fix new clippy lint 2025-03-09 09:42:55 +00:00
Martin
5aefc3601e Update Slovenian translation 2025-03-09 09:12:49 +00:00
Ekaterine Papava
901690e77f Update Georgian translation 2025-03-09 03:46:50 +00:00
Luming Zh
c58781521d Update Chinese (China) translation 2025-03-09 03:35:33 +00:00
Yuri Chornoivan
32d4dfdaf8 Update Ukrainian translation 2025-03-08 20:31:07 +00:00
Jiri Grönroos
91d66c6654 Update Finnish translation 2025-03-08 20:29:47 +00:00
Titouan Real
10d3c7ec8d user-session: Fix last_seen_datetime_string doc 2025-03-08 18:08:12 +01:00
Titouan Real
4b846fd9d7 user-sessions-page: Redesign 2025-03-08 10:46:33 +00:00
Kévin Commaille
6d383f0a9b
ci: Silence new advisories 2025-03-08 11:10:36 +01:00
Alexandre Franke
126a5daa53 issues: features are better discussed before filing 2025-03-07 14:48:31 +01:00
Alexandre Franke
cc1062b423 issues: make it clear what is supported 2025-03-07 10:54:37 +00:00
Kévin Commaille
2f107332fd
Downgrade oo7
Until we find a solution for the current problem.
2025-03-07 11:05:28 +01:00
Kévin Commaille
cdeee6bffb
camera: Fix unimplemented module imports 2025-03-06 11:43:41 +01:00
Kévin Commaille
8126ce3a40
secret: Fix unimplemented module imports 2025-03-06 11:42:56 +01:00
Kévin Commaille
41efd8b809
location: Use a trait for API implementations instead of GObject subclasses 2025-03-06 11:38:01 +01:00
Kévin Commaille
c2253f2507
Upgrade crate dependencies
In particular upgrade oo7 to 0.4.1 to have an extra log for the current
error.
2025-03-05 14:35:37 +01:00
Kévin Commaille
5564609c99 Upgrade matrix-sdk 2025-03-05 12:00:51 +00:00
Andika Triwidada
be8c021c7f Update Indonesian translation 2025-03-05 11:17:58 +00:00
Artur S0
e3e5a2bf33 Update Russian translation 2025-03-05 09:16:01 +00:00
Kévin Commaille
8cc9b6c705
ci: Use a previous commit of rust-nightly for building docs
There is a regression in the latest commit that prevents the
dependencies from building.
2025-03-02 20:31:18 +01:00
Kévin Commaille
d8cc3eed82
account-settings: Update the items in UserSessionsList rather than replacing them 2025-03-02 18:23:44 +01:00
Brage Fuglseth
95a37306ff Update Norwegian Bokmål translation 2025-03-02 16:23:03 +00:00
Kévin Commaille
d5cbeeef99
Upgrade glycin 2025-03-01 11:49:06 +01:00
Álvaro Burns
d726cbc5a9 Update Brazilian Portuguese translation 2025-02-28 15:21:18 +00:00
Kévin Commaille
c51971f37c
Upgrade matrix-sdk 2025-02-28 13:51:59 +01:00
Kévin Commaille
7c8e4b2577
room: Count our own user's membership changes as activity
That way freshly joined or newly created rooms are at the top of the
list.
2025-02-28 13:34:25 +01:00
Kévin Commaille
0fb493674a timeline: Add TRACE level logs for item changes
To debug an issue with missing items
2025-02-27 14:36:41 +00:00
Kévin Commaille
2cafa29b92 Upgrade matrix-sdk 2025-02-27 14:36:41 +00:00
Titouan Real
7911dd2134 user-sessions-page: React to device disconnections
When a device is disconnected, the server sends us an empty
`DeviceUpdates`. In this case, we need to reload the sessions list.
2025-02-24 16:14:29 +01:00
Kévin Commaille
2b8276c416
secret: Create data directory before storing tokens 2025-02-23 13:48:43 +01:00
Andika Triwidada
b4224653c9 Update Indonesian translation 2025-02-22 11:32:22 +00:00
Martin
6b04bbcf93 Update Slovenian translation 2025-02-22 10:10:54 +00:00
Luming Zh
c0620fbafb Update Chinese (China) translation 2025-02-22 00:09:24 +00:00
Yuri Chornoivan
986491fcaa Update Ukrainian translation 2025-02-21 18:53:13 +00:00
Kévin Commaille
67362776c6
misc: Fix new clippy lints 2025-02-21 11:08:43 +01:00
Kévin Commaille
5fff035bff
session: Handle refreshing tokens 2025-02-20 14:38:21 +01:00
Kévin Commaille
8a6b71e496
secret: Store tokens in a separate file
When we switch to supporting OAuth 2.0, the tokens will need to be
refreshed often. To avoid issues where the secret backend might stop
responding, we store them encrypted in a separate file. The secret
backend now only stores the passphrase.
2025-02-20 13:37:16 +01:00
Kévin Commaille
1d69e8282b
secret: Add the SecretExt trait to implement by backends 2025-02-19 17:27:38 +01:00
Kévin Commaille
3736e2782d
secret: Use SampleString trait
The code looks cleaner like that.
2025-02-19 16:50:56 +01:00
Kévin Commaille
a37e63aecc
Upgrade crate dependencies 2025-02-19 15:19:06 +01:00
Artur S0
8471160d23 Update Russian translation 2025-02-17 13:06:16 +00:00
Aefgh Threenine
2f9908fd07 Update Thai translation 2025-02-17 04:47:56 +00:00
Sabri Ünal
8dc5668ff6 Update Turkish translation 2025-02-16 18:19:07 +00:00
Rafael Fontenelle
df23a0ec3a Update Brazilian Portuguese translation 2025-02-14 01:36:51 +00:00
Ekaterine Papava
49f2ab6677 Update Georgian translation 2025-02-13 04:25:24 +00:00
Kévin Commaille
5f48f0f973
session: Set up periodic media cache cleanups
Avoids to have it grow indefinitely and gets rid of old media.
2025-02-11 12:18:43 +01:00
Kévin Commaille
a005dfea72
chore: Upgrade matrix-sdk 2025-02-11 12:18:43 +01:00
Kévin Commaille
30a764b4e3 room: Rename timeline property to live-timeline 2025-02-10 16:25:14 +00:00
Kévin Commaille
14ec802dfd room-history: Use Timeline as source of data rather than room 2025-02-10 16:25:14 +00:00
Kévin Commaille
ca18d920c1 timeline-item: Add a property to access the Timeline of the item 2025-02-10 16:25:14 +00:00
Kévin Commaille
229a5a1d31 timeline-diff-minimizer: Rename and use a custom trait for timeline items 2025-02-10 16:25:14 +00:00
Kévin Commaille
56d395581b timeline: Prepare support for forward paginating
Until now we assumed that loading events always loaded older events.
If we want to support opening the room history at an arbitrary event,
we need to be able to load newer events too.

This refactors code to clarify that we are currently loading older
events.
2025-02-10 16:25:14 +00:00
Kévin Commaille
b67d763dea
Release Fractal 10.1
This version backports the fixes to the regressions introduced in
Fractal 10.
2025-02-10 17:19:07 +01:00
Kévin Commaille
e9b4ffa5b0 ci: Check Rust dependencies with cargo-deny 2025-02-10 12:12:56 +00:00
Luming Zh
cedc6fc539 Update Chinese (China) translation 2025-02-10 10:57:40 +00:00
Rafael Fontenelle
6246535d5b Update Brazilian Portuguese translation 2025-02-09 05:03:34 +00:00
Martin
a22d09af91 Update Slovenian translation 2025-02-08 10:49:11 +00:00
Yuri Chornoivan
42c8bd045a Update Ukrainian translation 2025-02-07 16:38:55 +00:00
Daniel Rusek
929c12836c Update Czech translation 2025-02-07 13:46:34 +00:00
Alexandre Franke
42b5fddadb about: drop years from copyright 2025-02-07 13:10:56 +01:00
Andika Triwidada
cfbf9ffa61 Update Indonesian translation 2025-02-07 11:30:21 +00:00
Kévin Commaille
3618573f83
build: Require at least OpenSSL 3.0.0
Versions older than that are not supported anymore
2025-02-07 09:31:39 +01:00
Daniel Rusek
e8f4b641b9 Update Czech translation 2025-02-06 22:04:30 +00:00
Yuri Chornoivan
38b6523235 Update Ukrainian translation 2025-02-06 15:19:52 +00:00
Martin
2187ca7146 Update Slovenian translation 2025-02-06 15:12:53 +00:00
Alexandre Franke
53cec746df ui: add ellipses for buttons that open dialogs 2025-02-06 12:19:29 +01:00
Kévin Commaille
be682d69b0 chore: Upgrade matrix-sdk and ruma 2025-02-04 17:31:31 +00:00
Sabri Ünal
81181b3dad Update Turkish translation 2025-02-04 17:31:23 +00:00
Rafael Fontenelle
e5683ed537 Update Brazilian Portuguese translation 2025-02-04 16:19:02 +00:00
Artur S0
7ba8a2d98e Update Russian translation 2025-02-04 13:06:47 +00:00
Luming Zh
85c63d9a62 Update Chinese (China) translation 2025-02-04 02:08:34 +00:00
Daniel Rusek
a3df283fa3 Update Czech translation 2025-02-03 11:38:59 +00:00
Kévin Commaille
f8ce19f33b
room: Construct timeline right away
A recent change made us wait for the category to be loaded before
constructing the Timeline, to know if we should preload it.

However the timeline property of Room assumes that there is always a
timeline available after the construction, which was not true anymore.

So we construct the Timeline during construction again, and use a
property to preload it when both the category and the matrix timeline
are ready.
2025-02-01 12:19:31 +01:00
Martin
9280b05b9f Update Slovenian translation 2025-02-01 08:41:41 +00:00
Rafael Fontenelle
0a105f5b83 Update Brazilian Portuguese translation 2025-02-01 02:23:08 +00:00
Yuri Chornoivan
b882606bf8 Update Ukrainian translation 2025-01-31 15:47:37 +00:00
twlvnn kraftwerk
5af9cf7e9b Update Bulgarian translation 2025-01-31 13:44:00 +00:00
Alexandre Franke
e1c9658d34 RELEASING: add process to add branch on DL 2025-01-31 12:00:05 +01:00
Maximiliano Sandoval
11b42442aa application: Add accel to close window via ctrl+w 2025-01-31 10:02:47 +00:00
Maximiliano Sandoval
129b841c47
app: Chain up activate
All vfuncs should chain up to prevent undefined behavior.
2025-01-30 20:21:27 +01:00
Maximiliano Sandoval
407fbba876
app: Set default icon name
This is used in x11 by certain DEs.
2025-01-30 20:21:13 +01:00
Daniel Rusek
94c333f8a0 Update Czech translation 2025-01-30 18:32:36 +00:00
Alexandre Franke
a04dc4cd69 style: adjust border radii
Following GNOME/libadwaita change d450cb30c59694f604d4396993281797035bc51c

Fixes #1538
2025-01-30 16:20:11 +01:00
Guillaume Girol
f50c06b5fe add keyboard shortcuts to navigate between rooms
They were previously added in https://gitlab.gnome.org/World/fractal/-/merge_requests/424
but lost in a rewrite.

These keybindings conflict with the default ones of TextView so a
ShortcutController with propagation phase capture is needed.
2025-01-30 13:47:25 +00:00
Kévin Commaille
c5955bbc74
Release Fractal 10 2025-01-30 10:20:48 +01:00
Kévin Commaille
55ce058dc5
docs: Improve release docs for screenshots 2025-01-30 09:44:24 +01:00
Kévin Commaille
1250725930
sidebar: Bundle icon for direct chats 2025-01-28 15:15:32 +01:00
Kévin Commaille
3a22a65549
room: Make sure to preload timeline only after it was initialized
This avoids a possible race condition where we try to load the timeline
before it is initialized, which is a noop.
2025-01-28 14:59:44 +01:00
Kévin Commaille
fcb4b80194
timeline: Fixes
Fix the position when removing the last item, and when truncating the
list.

Also add a check that we are removing the proper event from the map, in
case we have created the same event several times.
2025-01-28 02:57:42 +01:00
Kévin Commaille
edb65a3d14
room-details: Remove context for "_Edit" string
With the context, the string change breaks the string freeze, and it is
not necessary since it has the same meaning as the other string with the
mnemonic.
2025-01-27 12:26:11 +01:00
Artur S0
6f699fa949 Update Russian translation 2025-01-27 09:14:04 +00:00
Ekaterine Papava
98d0113460 Update Georgian translation 2025-01-27 01:53:22 +00:00
Rafael Fontenelle
86237c09ff Update Brazilian Portuguese translation 2025-01-25 16:58:32 +00:00
Yuri Chornoivan
274c0cc1a6 Update Ukrainian translation 2025-01-25 13:22:56 +00:00
Martin
5357575947 Update Slovenian translation 2025-01-25 13:09:20 +00:00
Maximiliano Sandoval
61d5e1bd13
room_details: Use AdwButtonContent on edit button 2025-01-24 20:09:04 +01:00
Kévin Commaille
46f6a77a6c
auth-dialog: Build UIAA fallback URL according to supported Matrix versions 2025-01-24 18:20:35 +01:00
Kévin Commaille
7cd95632de
utils: Log auth_issuer error at warn level
Unless it is not found, which can be expected.
2025-01-24 18:07:46 +01:00
Kévin Commaille
f480a232a8
utils: Rename most mentions of OIDC to OAuth 2.0
Since the MSCs have been updated to be based solely on OAuth 2.0
2025-01-24 18:02:43 +01:00
Kévin Commaille
63b4fe073b
chore: Upgrade matrix-sdk 2025-01-24 17:36:49 +01:00
Ekaterine Papava
5bd51cf27d Update Georgian translation 2025-01-21 03:32:00 +00:00
Kévin Commaille
07f36e2184
room-history: Refactor MessageContent
Reduce duplication to avoir errors, and group the functions to build
the content under a trait to make it look nicer.
2025-01-19 18:41:46 +01:00
Kévin Commaille
a4dec0503c
sidebar: Refactor and fix visibility 2025-01-18 16:00:18 +01:00
Kévin Commaille
2ff346f3fd
account-switcher: Refactor and fix visibility 2025-01-18 15:10:10 +01:00
Kévin Commaille
c23ded9f55
account-switcher: Allow labels to ellipsize
Should allow the popover to have a smaller minimum size if necessary.
2025-01-18 14:34:21 +01:00
Daniel Rusek
b64ad3bbec Update Czech translation 2025-01-18 00:46:23 +00:00
Kévin Commaille
7d3ea11331
event-details: Do not show edit section if we do not know anything about the edit
In general it shouldn't be the case, but it seems there is a regression
in the SDK and we cannot see the details about edits that were just
sent.
2025-01-17 20:18:09 +01:00
Kévin Commaille
5cec99f599
room-history: Proceed to auto-scrolling when main loop is idle
It seems that sometimes the GtkListView does nothing when we are
notified that its size has changed and we request to focus its last
child.

It might be because the size is allocated before the child is ready, so
we delay the request.
2025-01-17 14:55:35 +01:00
Kévin Commaille
80255955c7
room-history: Add has-popup a11y property to read receipts list 2025-01-17 11:58:24 +01:00
Kévin Commaille
7e40957a5e
room-history: Add key bindings to open context menu of reactions 2025-01-17 11:58:24 +01:00
Kévin Commaille
e59d99e344
utils: Create key_bindings module and move into it and rename add_activate_binding_action 2025-01-17 11:58:24 +01:00
Kévin Commaille
68f9c46559 room-history: Fix behaviour on scroll
Try to be smarter about what we are doing when we get signals from the
vadjustment.

We can ignore the upper and page-size signals when we are already
auto-scrolling, since trying to scroll more will just result in even
more signals later.

Only focus the last child once, then rely on scrolling to the end to
make sure that we are at the bottom.
2025-01-17 10:14:57 +00:00
Martin
54a8eabf64 Update Slovenian translation 2025-01-17 10:03:08 +00:00
Kévin Commaille
97c6c46b18 room: Reduce log noise for invited and knocked rooms
It is expected that we will not be able to access most of the room state
so do not try to load everything and reduce the logging level when a
permission error happens in those states.
2025-01-16 19:18:14 +00:00
Kévin Commaille
f11c57ed5e room: Only preload history for the main categories
Those are the categories that the user is most likely to visit.
Also we should not preload the timeline for categories where we do not
offer to view it.
2025-01-16 19:18:14 +00:00
Kévin Commaille
734c6d6d8c room: Wait for category to be loaded before initializing timeline
Since we do not preload the timeline for all categories
2025-01-16 19:18:14 +00:00
Kévin Commaille
0b6cc2019f room: Rename Room::set_category to change_category
To differentiate change_category which sends data to the homeserver,
with set_category from the private API that only changes the local
category.
2025-01-16 19:18:14 +00:00
Kévin Commaille
706c842d56 room: Introduce TargetRoomCategory for categories that can be targetted by the user
This makes the API more correct as we can't encounter categories that
are dependent of the state of the room.
2025-01-16 19:18:14 +00:00
Kévin Commaille
40af0116fb video-player: Fix visibility of duration
There are two conditions for the visibility so we always need to check
both before changing it.
2025-01-16 15:20:52 +00:00
Kévin Commaille
a5c71dec29 room-history: Return the proper minimum size when measuring visual media messages
It was always returning 0, which would trigger GTK warnings.
2025-01-16 15:20:52 +00:00
Anders Jonsson
8bccf661d4 Update Swedish translation 2025-01-16 13:33:55 +00:00
Brage Fuglseth
3eb5f9b99b Update Norwegian Bokmål translation 2025-01-16 11:30:45 +00:00
Kévin Commaille
37fbb89a26
docs: Update list of runtime dependencies 2025-01-15 18:04:01 +01:00
Kévin Commaille
6508f7411a
docs: Build docs for ruma-events 2025-01-15 18:04:01 +01:00
Kévin Commaille
0ba4b655c0
docs: Use the basic-deploy-docs CI template 2025-01-15 18:04:01 +01:00
Kévin Commaille
2835b999f8 camera: Use aperture library for scanning QR codes
That way we can benefit from improvements upstream.

This also simplifies the camera API in the process by using a trait
instead of a subclassable GObject.
2025-01-15 15:54:29 +00:00
Artur S0
10be4b5a6e Update Russian translation 2025-01-15 14:16:30 +00:00
Yuri Chornoivan
321232e005 Update Ukrainian translation 2025-01-14 19:23:02 +00:00
Alexandre Franke
a57e25c304 Update French translation 2025-01-14 13:06:32 +00:00
Kévin Commaille
a849341e3a Release Fractal 10.rc 2025-01-14 09:25:52 +00:00
Luming Zh
7d64667c90 Update Chinese (China) translation 2025-01-14 04:56:02 +00:00
Rafael Fontenelle
7407ce97ae Update Brazilian Portuguese translation 2025-01-14 01:34:27 +00:00
Kévin Commaille
ebd5fbc1cf
image: Set and use the is_animated flag
If the image is marked as animated we download the original instead of a
thumbnail to be able to play it in the room history.
2025-01-13 16:30:01 +01:00
Kévin Commaille
06471e66b9
chore: Upgrade matrix-sdk
Stop using a private branch.
2025-01-13 15:26:08 +01:00
Kévin Commaille
47d47b290e
auth-dialog: Fix crash and rename button to open browser to "Continue"
That way we are consistent with the login screen.
2025-01-13 14:52:24 +01:00
Kévin Commaille
ff12986452
login: Move away from SSO term and add "Continue" button
Moving away from the SSO term allows us to transition seemlessly towards
OIDC.

Adding a "Continue" button avoids to surprise the user by opening a URL
without warning.

Fixes SSO identity provider login in the process.
2025-01-13 14:52:24 +01:00
Danial Behzadi
d6388dfc97 Update Persian translation 2025-01-13 12:45:25 +00:00
Kévin Commaille
ffed9ac679
message-row: Always allocate space for messsage state
It avoids reflows in the UI when the state changes.
2025-01-13 10:33:00 +01:00
Ekaterine Papava
42f7dba972 Update Georgian translation 2025-01-12 19:57:24 +00:00
Kévin Commaille
d1b1f4ad3f timeline: Refactor code to minimize diff and add tests 2025-01-12 15:05:50 +00:00
Alexandre Franke
5116bb49d8 Update French translation 2025-01-12 09:31:23 +00:00
Martin
e6f2e59fe5 Update Slovenian translation 2025-01-11 18:33:09 +00:00
Sabri Ünal
0f5d6e9831 Update Turkish translation 2025-01-11 12:43:55 +00:00
Yuri Chornoivan
e744adbe32 Update Ukrainian translation 2025-01-11 11:00:25 +00:00
Kévin Commaille
0ee4286ff2
timeline: Refactor to reduce duplicate code
And hopefully avoid code duplication errors.
2025-01-10 19:03:25 +01:00
Kévin Commaille
f8bde01838
chore: Fix new clippy lint 2025-01-10 12:42:43 +01:00
Kévin Commaille
f98f3a046b
build: Remove meson subprojects
They are not necessary when building the Flatpak and we don't even keep
them up to date.
2025-01-10 12:42:42 +01:00
Kévin Commaille
f293b5ef60
chore: Upgrade matrix-sdk (ter)
Adds a patch to fix decryption errors.
2025-01-09 19:19:37 +01:00
Kévin Commaille
b2b48e7a64
chore: Upgrade matrix-sdk (bis)
This time with a real fix for the timeline start issue.
2025-01-09 17:52:54 +01:00
Kévin Commaille
8123065122
timeline: Fix code to optimize diff (bis)
When changing the code we forgot to copy the code to update the headers
so no header would show up.
2025-01-09 16:52:13 +01:00
Kévin Commaille
01a3835641
chore: Upgrade matrix-sdk
Should fix issue with erroneous "This is the start of the visibile
timeline" in the room history.
2025-01-09 16:02:13 +01:00
Kévin Commaille
50430263c9
timeline: Fix code to optimize diff
The previous code wrongly assumed that only updated items could be
inserted in the optimized diff.

Now instead of rebuilding `VectorDiffs` we update items as we process
the diff and only handle removals or insertions after that.
2025-01-09 15:03:30 +01:00
Kévin Commaille
fd48e88fcc
Add oidc-aware compatibility
It requires a few changes during login to only offer SSO when OIDC
compatability is detected,
and most actions that require UIAA in account details must now occur
in the account management UI of MAS.
2025-01-08 17:24:52 +01:00
Kévin Commaille
c32ba2efad
recovery-setup-view: Fix resetting cross-signing keys
Calling bootstrap_cross_signing seemed to work but doesn't actually
upload new keys.
2025-01-08 17:23:09 +01:00
Kévin Commaille
0c144bcfb5
login: Refactor and fix visibility 2025-01-08 17:22:05 +01:00
Kévin Commaille
ea1a12763b
video-player: Use gstgtk4 library installed on system
We do not need to compile it as part of our binary since it is available
in the GNOME platform runtime.
2025-01-07 22:59:49 +01:00
Kévin Commaille
f0cb618fd7
message-toolbar: Use send queue to send attachments
Allows to benefit from its built-in features: local echos, sending
messages in the right order, stopping the queue when an error occurs…
2025-01-07 11:47:12 +01:00
Kévin Commaille
2d0552b74d
timeline: Attempt to minimize the diff batches from the SDK
A recent change in the SDK made them less optimized than before,
it creates jumps in the room history when sending a message.

We try to work around that by optimizing the batch ourselves.
2025-01-07 11:45:39 +01:00
Kévin Commaille
cb784482b7
chore: Upgrade matrix-sdk 2025-01-07 11:45:39 +01:00
Yuri Chornoivan
44c387f74c Update Ukrainian translation 2025-01-07 06:32:11 +00:00
Martin
cccc676bdd Update Slovenian translation 2025-01-06 14:05:50 +00:00
Alexandre Franke
87f5205c8e Update French translation 2025-01-06 13:38:29 +00:00
Brage Fuglseth
de8ccf8007 Update Norwegian Bokmål translation 2025-01-05 22:06:55 +00:00
Kévin Commaille
aee4319640
room-history: Add quick reaction chooser dynamically
Avoids to have duplicate menus just to add or remove it. It will avoid
possible duplication errors when changing the menu.
2025-01-05 16:56:40 +01:00
Kévin Commaille
c8345ac4b1
room-history: Refactor and fix message actions
Make sure that we use the same rules everywhere to decide if an action
is possible on a message.
2025-01-05 12:56:53 +01:00
Kévin Commaille
a81dd8400e
pill: Fix action when clicking on an activatable pill
This is a recent regression after refactoring.
2025-01-05 10:48:22 +01:00
Kévin Commaille
0298b69f12
room-history: Do not switch copy-image action if media is compact
When it is the preview of a replied to message, the media does not have
action of its own so it should not affect the actions the row.
2025-01-03 14:14:48 +01:00
Kévin Commaille
8a463486c9
components: Only disable vhomogeneous for LoadingRow
For other uses of LoadingBin, vhomogeneous is actually better.
2025-01-02 10:38:13 +01:00
Kévin Commaille
63e3562bea
sender-avatar: Do not show action to open direct chat when in direct chat 2024-12-30 15:13:40 +01:00
Kévin Commaille
28e17f4379
user-page: Show button to open direct chat except if opened from a direct chat 2024-12-30 15:12:47 +01:00
Kévin Commaille
3ea780bfe1
room-history: Remove unnecessary debug level log. 2024-12-30 12:47:22 +01:00
Kévin Commaille
49d04959d2
room-details: Separate stable and experimental room versions in sections
Appending "(unstable)" to the room version does not work well because it
might be ellipsized, especially considering that unstable room versions
usually have a long name.
2024-12-30 12:45:22 +01:00
Brage Fuglseth
4461c28d0a Update Norwegian Bokmål translation 2024-12-29 22:27:59 +00:00
Kévin Commaille
aab3a13c35
room-history: Do not offer to copy the thumbnail until it is loaded 2024-12-29 10:39:34 +01:00
Kévin Commaille
04bc8c6aef
room-history: Do not show scroll button when context menu is open 2024-12-29 09:55:39 +01:00
Kévin Commaille
573e15d8a7
room-history: Refactor and fix visibility 2024-12-28 15:32:39 +01:00
Kévin Commaille
9627e8e862
item-row: Refactor and fix visibility 2024-12-28 15:17:43 +01:00
Kévin Commaille
b4efcb049a
state-row: Refactor and fix visibility 2024-12-28 15:17:09 +01:00
Kévin Commaille
24dddb3043
sender-avatar: Refactor and fix visibility 2024-12-28 14:24:55 +01:00
Kévin Commaille
e7bf640b21
read-receipt-list: Refactor and fix visibility 2024-12-28 14:24:24 +01:00
Kévin Commaille
5f8ca2e66a
member-timestamp: Refactor and fix visibility 2024-12-28 13:38:33 +01:00
Kévin Commaille
076298a71b
chore: Fix gettext comment
It should be on the lines right above the string to be picked up by
xgettext.
2024-12-28 13:33:36 +01:00
Kévin Commaille
e577d1c1b6
label-with-widgets: Simplify API
Remove unused properties, and force label and widgets to be set together
to reduce the number of calls to invalidate_widgets.

We also make sure to set use-markup before the label and widgets to
avoid a potentially expensive reallocation.
2024-12-28 11:44:36 +01:00
Evan Paterakis
b6c074b768
label-with-widgets: invalidate widgets on use-markup change 2024-12-28 06:09:15 +02:00
Kévin Commaille
332fcefbe0
Release Fractal 10.beta 2024-12-26 11:02:20 +01:00
Alexandre Franke
a65ffc1b08 window: Add fetching text on startup 2024-12-26 08:29:08 +00:00
twlvnn kraftwerk
e0b528125b Add Bulgarian translation 2024-12-25 17:34:45 +00:00
Alexandre Franke
2cface3adb window: Add About button on startup screen 2024-12-24 11:04:52 +00:00
Kévin Commaille
daf6a01d1f
build: Remove sandboxed-build meson option
Since we only need this to use vendored dependencies for Flathub,
we can just modify the Cargo config file in Flathub's flatpak manifest
for that.
2024-12-23 15:46:44 +01:00
Kévin Commaille
33f46ac49f
chore: Upgrade glycin-loaders 2024-12-23 15:43:48 +01:00
Guillaume Girol
7ce6d404e8 hooks: do not assume location of bash
On NixOS (and BSD) bash is not at /bin/bash.
Change the shebang to use bash from PATH.
2024-12-23 12:00:00 +00:00
Kévin Commaille
efc6565076
message-row: Refactor and clean up 2024-12-22 14:15:02 +01:00
Kévin Commaille
15902b31d9
message-toolbar: Refactor and cleanup 2024-12-21 15:42:18 +01:00
Kévin Commaille
4d820c01f0
notifications: Do not (un)realize the renderer since we did not construct it 2024-12-20 17:36:28 +01:00
Lukáš Tyrychtr
2a5157b1df sender-avatar: Add the has-popup property for it
In Orca commit 6105519dc837 Orca started ignoring buttons with the has popup
 state when reading list items during navigation.
Use that behavior to make reading a chat room history less verbose.
2024-12-20 13:13:17 +00:00
Kévin Commaille
07bc3302fc
image: Request only 2 different sizes for avatars
Allows to avoid to fill the media cache with almost a different size for
every view,
and to optimize the cache hits.

Should also fix blurry or missing avatars in notifications.
2024-12-20 13:11:30 +01:00
Kévin Commaille
1741a99b93
image: Generate a thumbnail at the same size as we will download later
It should optimize the cache hits when the media is cached upon sending.
2024-12-19 11:25:46 +01:00
Kévin Commaille
9048261ccd
chore: Upgrade crate dependencies 2024-12-18 16:37:26 +01:00
Kévin Commaille
9c330d3114
qr-code-detector: Do not use image crate
It is not needed, we can just construct another type that rqrr accepts
as input for its API.

Gets rid of the image crate in the dependency tree.
2024-12-17 18:20:33 +01:00
Kévin Commaille
37be41c8ca
qr-code-detector: Fix visibility and formatting 2024-12-17 17:44:47 +01:00
Kévin Commaille
023494813a
image: Use GTK APIs instead of image crate to generate thumbnails 2024-12-17 17:36:44 +01:00
Alexandre Franke
8d9093c70b doap: add useful fields 2024-12-15 15:41:58 +01:00
Kévin Commaille
1fd5ec42c7
components: Refactor and clean up 2024-12-14 16:38:05 +01:00
Kévin Commaille
c58cb065d2
rows: Refactor and fix visibility 2024-12-14 16:38:04 +01:00
Kévin Commaille
3d0dbf5319
power-level-selection: Refactor and fix visibility 2024-12-14 16:38:04 +01:00
Kévin Commaille
87bc3dc4fd
pill: Refactor and fix visibility 2024-12-14 16:38:04 +01:00
Kévin Commaille
076119eda7
media: Refactor and fix visibility 2024-12-14 16:38:04 +01:00
Kévin Commaille
5f176df711
loading: Fix visibility 2024-12-14 16:38:03 +01:00
Kévin Commaille
2de11e9cae
recovery-setup-view: Refactor and fix visibility 2024-12-14 16:38:03 +01:00
Kévin Commaille
b11baa03d1
identity-setup-view: Fix visibility and refactor 2024-12-14 16:38:03 +01:00
Kévin Commaille
c795f87c2f
avatar: Fix visibility 2024-12-14 16:38:03 +01:00
Kévin Commaille
28a3d36052
ci: Take metainfo from flatpak repo
Avoids issues with build artifacts.
2024-12-14 15:43:00 +01:00
Kévin Commaille
eaf1220d36
user-profile-dialog: Refactor 2024-12-14 11:00:31 +01:00
Kévin Commaille
5e95a23b76
toastable-dialog: Refactor 2024-12-14 11:00:31 +01:00
Kévin Commaille
5aee42ce1c
message-dialogs: Fix visibility 2024-12-14 11:00:30 +01:00
Kévin Commaille
a8cf08531f
join-room-dialog: Refactor and clean up 2024-12-12 03:09:47 +01:00
Kévin Commaille
16020e849a
auth-dialog: Refactor and clean up 2024-12-12 02:47:54 +01:00
Kévin Commaille
8c7e12ee0a
chore: Fix new clippy warnings 2024-12-09 12:13:54 +01:00
Kévin Commaille
bf631bc323
session-list: Refactor and clean up 2024-11-26 01:38:05 +01:00
Kévin Commaille
c0d0ce935b
session: Refactor and clean up 2024-11-26 01:25:41 +01:00
Kévin Commaille
eabf884352
typing-list: Refactor 2024-11-25 03:44:04 +01:00
Kévin Commaille
e2e12bfb8f
permissions: Refactor and clean up 2024-11-25 03:43:40 +01:00
Kévin Commaille
560f1e7a64
member: Refactor and clean up 2024-11-25 03:35:06 +01:00
Kévin Commaille
f35a5c96cc
member-list: Refactor and clean up 2024-11-25 04:51:44 +01:00
Kévin Commaille
10e854f782
join-rule: Fix visibility 2024-11-25 04:38:10 +01:00
Kévin Commaille
79010ba8b3
room-category: Fix visibility 2024-11-25 04:26:17 +01:00
Kévin Commaille
3dfc710c30
room-aliases: Fix visibility 2024-11-25 04:23:55 +01:00
Kévin Commaille
7bf6b52c56
reaction-list: Refactor and clean up 2024-11-25 04:18:43 +01:00
Kévin Commaille
130dfee8a1
reaction-group: Refactor and clean up 2024-11-25 04:02:13 +01:00
Kévin Commaille
2e0060effa
event: Simplify try_update_with 2024-11-25 03:48:37 +01:00
Kévin Commaille
bfd6aa9008
item-row: Log errors when activating actions 2024-11-24 17:37:56 +01:00
Kévin Commaille
43cd8b5052
room-history: Log errors when activating actions 2024-11-24 17:37:26 +01:00
Kévin Commaille
09d8a1b1b5
timeline: Always try to find an Event with its two possible identifiers
Given that the identifier changes after an Event has been sent, we need
to match both possibilities, depending on the identifier we get.
2024-11-24 17:15:10 +01:00
Kévin Commaille
162ce7dacb
docs: Remove mention of old version of KWallet 2024-11-24 14:55:45 +01:00
Kévin Commaille
405c308552
docs: Add KWallet as backend for secret portal 2024-11-24 14:37:58 +01:00
Kévin Commaille
805c6adf44
build: Update build and runtime dependencies 2024-11-24 14:25:44 +01:00
Kévin Commaille
760e5e0b40 virtual-timeline-item: Fix visibility 2024-11-23 11:43:41 +00:00
Kévin Commaille
89162d4ac1 timeline-item: Fix visibility and clean up 2024-11-23 11:43:41 +00:00
Kévin Commaille
fd570510ae room: Fix methods visibility and clean up 2024-11-23 11:43:41 +00:00
Kévin Commaille
ae1ca01f97 event: Refactor and clean up 2024-11-23 11:43:41 +00:00
Kévin Commaille
752f8941c0 chore: Upgrade matrix-sdk and ruma
And run `cargo update`.
2024-11-23 11:43:41 +00:00
Kévin Commaille
a7aa573373
Add help file for making a new release 2024-11-21 11:08:12 +01:00
Kévin Commaille
df8a020776
room-details: Refactor PermissionsMembersSubpage 2024-11-13 18:04:15 +01:00
Kévin Commaille
c7b29cd8ac
room-details: Fix focus chain of PermissionsMembersSubpage 2024-11-13 17:23:36 +01:00
Kévin Commaille
fcbdb5da1c
components: Rename ReactionChooser to QuickReactionChooser and refactor 2024-11-13 15:51:13 +01:00
Kévin Commaille
65a5db9166
utils: Refactor OverlappingAvatars 2024-11-13 14:16:31 +01:00
Kévin Commaille
a1957981ee
components: Fix measuring of OverlappingAvatars 2024-11-13 14:16:10 +01:00
Kévin Commaille
9e5f1f4a4a
utils: Remove trace level logs for ImageQueue 2024-11-13 12:06:24 +01:00
Kévin Commaille
55724695ce
style: Use SASS to organize styles
We now require a SASS compiler at build time.
2024-11-12 18:57:28 +01:00
Jiri Grönroos
34af3e2a0d Update Finnish translation 2024-11-11 18:54:07 +00:00
Artur S0
2b5b537f9e Update Russian translation 2024-11-11 15:46:23 +00:00
Kévin Commaille
55e0d13615
room-history: Fix untranslatable error message for video events
Even if in theory this error should never happen.
2024-11-11 15:16:08 +01:00
Kévin Commaille
23d0960389
utils: Use $XDG_RUNTIME_DIR for temporary files and remove them after use
Using $XDG_RUNTIME_DIR instead of $TMPDIR means that the temporary files
are scoped to the user.
And since those folders are usually backed by a tmpfs in memory, we need
to remove the files as soon as possible to release space.
2024-11-10 15:07:29 +01:00
Kévin Commaille
efeb245066
media-viewer: Use the type of the event as the content type of the media 2024-11-05 15:09:51 +01:00
Kévin Commaille
53cb04cdc7
media-content-viewer: Refactor and document 2024-11-05 14:57:23 +01:00
Kévin Commaille
0fea602ec9
media-viewer: Refactor and document 2024-11-05 14:18:17 +01:00
Kévin Commaille
73745fe94e
room-history: Display errors for videos
Also fix the sizing of visual media by preferring their intrinsic size
over the size declared in the event.
2024-11-05 11:46:07 +01:00
Kévin Commaille
a911a13eed
video-player: Fix video not playing automatically 2024-11-04 14:44:12 +01:00
Kévin Commaille
68af0e23c5
video-player: Refactoring 2024-11-04 14:43:43 +01:00
Kévin Commaille
1f2dd7a8cf
chore: Rename ImageDimensions to FrameDimensions and other refactoring 2024-11-04 13:19:05 +01:00
Kévin Commaille
72bee09a8c
visual-media: Refactoring 2024-11-04 10:48:44 +01:00
Rafael Fontenelle
0446069a3f Update Brazilian Portuguese translation 2024-11-04 01:35:02 +00:00
Kévin Commaille
b97530a327
chore: Enable most of Clippy's pedantic lints 2024-11-03 15:47:19 +01:00
Ali Galal
94d531602b room-history: Fix message-reactions alignment in RTL 2024-11-03 13:32:16 +00:00
Ali Galal
a0df0592cb room-history: Fix Pill content alignment in RTL 2024-11-03 13:32:16 +00:00
Martin
3c5eadb988 Update Slovenian translation 2024-11-03 09:43:41 +00:00
Luming Zh
c6327c6a74 Update Chinese (China) translation 2024-11-03 01:35:08 +00:00
Yuri Chornoivan
e739c979ce Update Ukrainian translation 2024-11-02 16:07:20 +00:00
Daniel Rusek
e19ef66d11 Update Czech translation 2024-11-02 12:48:21 +00:00
Kévin Commaille
44311dfbe1
chore: Replace "OK" and "Dismiss" strings with "Done" 2024-11-02 12:00:13 +01:00
Kévin Commaille
efebc94ecf
chore: Remove once_cell dependency
Use the types in std instead. Bumps the MSRV to 1.80.
2024-11-02 11:35:54 +01:00
Filipe Motta
e9f581e450 Update Brazilian Portuguese translation 2024-10-31 11:19:51 +00:00
Kévin Commaille
cb26488cc1
Release Fractal 9 2024-10-30 11:49:09 +01:00
Kévin Commaille
8891505584
Revert "cause: Set accent color to pink for Breast Cancer Awareness Month"
This reverts commit f3fcfdbd7f7bcbef9dc36869f82d0cf68fff849f.
2024-10-30 10:07:19 +01:00
Yaron Shahrabani
f4664ce701 Update Hebrew translation 2024-10-29 07:43:50 +00:00
Aefgh Threenine
e190a20be7 Update Thai translation 2024-10-28 18:42:33 +00:00
Artur S0
58fad0a138 Update Russian translation 2024-10-28 13:15:23 +00:00
Kévin Commaille
6deef7148f
utils: Remove ImageError::None
It is only here to be able to use it as a GEnum for simplicity in a few
types, but is doesn't make sense.
2024-10-23 19:15:26 +02:00
Kévin Commaille
b3b59c555c
utils: Add a queue for image requests
Allows to limit the number of concurrent requests and keep track of slow
requests.
2024-10-22 18:33:04 +02:00
Kévin Commaille
933d74ec81
chore: Ignore Zed IDE config directory 2024-10-22 17:27:37 +02:00
Quentin PAGÈS
0ad6656b34 Update Occitan translation 2024-10-21 19:46:25 +00:00
Tim Sabsch
b847a13f77 Update German translation 2024-10-20 18:30:40 +00:00
Aefgh Threenine
cabb46ccdc Update Thai translation 2024-10-19 02:53:46 +00:00
Anders Jonsson
6aacd5c1b9 Update Swedish translation 2024-10-18 11:14:58 +00:00
Aefgh Threenine
17bbf1a6a5 Update Thai translation 2024-10-18 09:40:28 +00:00
Aefgh Threenine
ddcc69dd55 Add Thai translation 2024-10-18 09:39:18 +00:00
Ekaterine Papava
e38140adb8 Update Georgian translation 2024-10-18 04:25:32 +00:00
Kévin Commaille
8b7aa4f429
Release Fractal 9.rc 2024-10-17 11:13:30 +02:00
Kévin Commaille
f3fcfdbd7f
cause: Set accent color to pink for Breast Cancer Awareness Month 2024-10-17 11:02:58 +02:00
Alexandre Franke
63fca01cfc Update French translation 2024-10-17 07:29:48 +00:00
Brage Fuglseth
aa0a8be796 Update Norwegian Bokmål translation 2024-10-16 18:39:33 +00:00
Kévin Commaille
f751d58ec5
chore: Upgrade matrix-sdk, ruma and rqrr 2024-10-15 17:47:08 +02:00
Kévin Commaille
f3d8673913
timeline: Remove unused method
To detect unused code, pass all methods as pub(crate).
2024-10-15 14:56:02 +02:00
Luming Zh
4e2f271038 Update Chinese (China) translation 2024-10-15 10:22:24 +00:00
Yuri Chornoivan
5665f77a99 Update Ukrainian translation 2024-10-14 19:25:35 +00:00
Martin
0c08892570 Update Slovenian translation 2024-10-14 14:09:13 +00:00
Kévin Commaille
d349ce4983 components: Do not allocate height of child in LoadingBin
It can look weird with a lot of extra space if the child is a lot bigger
than the spinner.
2024-10-13 11:55:13 +00:00
Kévin Commaille
20b5ded557 room-details: Fix members count of left rooms
We must remove ourself from the server-provided members count.
2024-10-13 11:55:13 +00:00
Kévin Commaille
c3242b1080 room-details: Handle all states of room members list 2024-10-13 11:55:13 +00:00
Rafael Fontenelle
c4b2420bd8 Update Brazilian Portuguese translation 2024-10-13 01:26:26 +00:00
Kévin Commaille
1fdcd73be2
room-title: Fix height of button
When there is no subtitle, use the default button padding an use
gtk::Align::Center for valign.
When there is a subtitle, remove the button padding, reduce the space
taken by the labels and use gtk::Align::Fill for valign.

Co-authored-by: Alexandre Franke <afranke@gnome.org>
2024-10-11 13:02:40 +02:00
Kévin Commaille
9859e4c800
build: Remove NO_POINTER_VIEWPORT environment variable
It doesn't do anything anymore.
2024-10-10 09:53:36 +02:00
Kévin Commaille
c96609ff8a
remote-room: Downgrade errors to the WARN level
Since RemoteRoom is used for unknown room mentions, it does not make
sense to have errors in the logs for those.
2024-10-09 11:40:26 +02:00
Kévin Commaille
473c5d53bf
room: Do not log about state change during initialization 2024-10-09 11:37:04 +02:00
Kévin Commaille
78cd7b057d
room: Use RoomInfo to watch whether a room is direct 2024-10-09 11:31:30 +02:00
Artur S0
dd5b1c9335 Update Russian translation 2024-10-08 09:23:14 +00:00
Kévin Commaille
0b044491a1
chore: Upgrade matrix-sdk crate
Should get rid of unwanted verbose warnings in the SDK.
2024-10-07 14:50:54 +02:00
Luming Zh
0fed338255 Update Chinese (China) translation 2024-10-07 02:43:14 +00:00
Anders Jonsson
9ddbf96e2a Update Swedish translation 2024-10-06 19:27:53 +00:00
Yuri Chornoivan
4650c2d22c Update Ukrainian translation 2024-10-06 15:52:45 +00:00
Martin
bf7cb9024e Update Slovenian translation 2024-10-06 14:57:54 +00:00
Kévin Commaille
4a8625b5fe
room-history: Do not offer to invite members in direct chat 2024-10-06 13:33:04 +02:00
Kévin Commaille
113c97d5f2
room-details: Present members directly in general page for direct chats 2024-10-06 13:33:04 +02:00
Kévin Commaille
b4118978df
room-details: Hide some sections and actions for direct chats 2024-10-06 13:33:04 +02:00
Kévin Commaille
f535b931a8
crypto-recovery-setup-view: Fix resetting recovery when backup exists on homeserver
We force the API to delete the backup instead of disabling recovery.
2024-10-05 13:06:16 +02:00
Kévin Commaille
25e7ee4cb7
session: Split security API in a separate type 2024-10-05 11:57:56 +02:00
Kévin Commaille
f94357ebe8
account-settings: Fix user sessions page
AdwPreferencesPage only allows AdwPreferencesGroup as children so only
provide that.
We only use the GtkStack for the other active sessions by initializing
the current session early.

Includes other refactoring around user sessions.
2024-10-05 10:55:54 +02:00
Luming Zh
4f4085ada4 Update Chinese (China) translation 2024-10-05 00:23:34 +00:00
Kévin Commaille
857cf0d75c timeline: Ignore room member events where the content has not changed 2024-10-04 16:08:15 +00:00
Yuri Chornoivan
52d6b66329 Update Ukrainian translation 2024-10-04 16:05:03 +00:00
Kévin Commaille
478dab3ecd
room-history: Fix style of new messages divider 2024-10-04 14:54:49 +02:00
Kévin Commaille
8e38f554e3
chore: Upgrade matrix-sdk 2024-10-04 13:09:32 +02:00
Martin
cae850afd2 Update Slovenian translation 2024-10-04 10:34:29 +00:00
Kévin Commaille
3400931fb3
session-list: Only restore sessions with a data directory on the system
This is necessary to avoid issues for users sharing their secrets
between devices.
2024-10-04 11:33:36 +02:00
Kévin Commaille
a58b71f15a
room-history: Do not use italics for typing row
Use dim-label instead.
2024-10-04 10:19:32 +02:00
Kévin Commaille
7f99225953
room: Fix typing list sometimes not showing 2024-10-04 10:06:53 +02:00
Kévin Commaille
662b590a0b
room-history: Make sure that we scroll to the end in scroll_down
Previously me only made sure that we were scrolling to the last item and
focusing it,
but sometimes when the item is partly into view, it does not scroll to
the bottom.
2024-10-03 17:36:28 +02:00
Kévin Commaille
7e2f334d41
room-history: Make sure history loading does not stop until view is filled, when possible
And other refactoring.
2024-10-03 17:25:18 +02:00
Kévin Commaille
098a03ef81
room-details: Fix loading state of media history viewers
Show the loading stack page if there are no other items than the loading
row.
Keep the timeline state to Loading until we have enough items according
to the viewer.
2024-10-03 14:18:57 +02:00
Danial Behzadi
488ed24fe9 Update Persian translation 2024-10-03 10:44:58 +00:00
Kévin Commaille
71d492ea6f
media-viewer: Remove arrow of context menu 2024-10-03 11:01:57 +02:00
Kévin Commaille
f1d2fce121
message-toolbar: Add a send guard
To prevent sending the same message several times.
2024-10-02 15:32:54 +02:00
Juliano de Souza Camargo
bd248f9df7 Update Brazilian Portuguese translation 2024-10-02 00:50:14 +00:00
Satrujit Behera
e9d9ae44da notifications: Set im.received category for notifications 2024-10-01 15:15:06 +00:00
Brage Fuglseth
2a86f44038 Update Norwegian Bokmål translation 2024-09-30 21:53:50 +00:00
Yuri Chornoivan
5795a59547 Update Ukrainian translation 2024-09-30 20:02:54 +00:00
Martin
e112fa3d96 Update Slovenian translation 2024-09-30 13:20:50 +00:00
Luming Zh
92fc80f90a Update Chinese (China) translation 2024-09-30 12:54:47 +00:00
Kévin Commaille
16ade07284 misc: Remove "Try again later" from toast messages 2024-09-30 09:58:39 +00:00
Kévin Commaille
63404476b5 sidebar-row: Use better toast messages for failed room actions 2024-09-30 09:58:39 +00:00
Kévin Commaille
5fe52ce014 sidebar: Use "decline" instead of "reject"
We already changed it in the Invite view, but not in the context menu.
2024-09-30 09:58:39 +00:00
Kévin Commaille
b0356547ef room: Remove (accept/decline)_invite methods
They are only used by the Invite view, other places do the same thing
with set_category.
2024-09-30 09:58:39 +00:00
Juliano de Souza Camargo
553881fcc7 Update Brazilian Portuguese translation 2024-09-29 17:06:53 +00:00
Daniel Rusek
74a2a1fe26 Update Czech translation 2024-09-29 15:22:17 +00:00
Artur S0
f19552dbb6 Update Russian translation 2024-09-29 12:53:46 +00:00
Kévin Commaille
7cbdedfabd
room: Rely more on RoomInfo for updating room data
Removes update_for_events and related methods.
2024-09-28 16:40:41 +02:00
Kévin Commaille
1a144e4b58
sidebar: Rename Category to SidebarSection
Rename CategoryType to SidebarSectionName and remove unused variants.
Rename CategoryFilter to RoomCategoryFilter.
Use Option<RoomCategory> instead of CategoryType for drag-n-drop
operations, preventing us from using GObject properties.
2024-09-28 16:40:41 +02:00
Kévin Commaille
1f123518dc
room: Rename RoomType to RoomCategory
There is already a meaning for room types in the Matrix spec.
Besides the property is named `category`, so stick with it.
2024-09-28 16:40:41 +02:00
Kévin Commaille
3e303b7910
room: Refactoring
Put private methods on the imp type and try to group fields and methods
sensibly.
2024-09-28 16:40:41 +02:00
Alexandre Franke
091b55fc8a hook: check for unused deps with machete 2024-09-28 08:53:01 +00:00
Kévin Commaille
18f863d70a
room: Set bold highlight even if there are no notifications
New regression.
2024-09-27 20:22:06 +02:00
Kévin Commaille
ba47397def
room-history: Fix size of spinners and error icons for visual media messages and location 2024-09-27 11:03:13 +02:00
Kévin Commaille
4ec71c2541
sidebar: Do not show notification count if the room is read
Workaround a bug in Synapse that sends a non-zero unread notifications
count sometimes even if our user was the last one to send a message.
2024-09-27 09:44:39 +02:00
Brage Fuglseth
0f509a20be Update Norwegian Bokmål translation 2024-09-26 19:33:18 +00:00
Brage Fuglseth
39c7d8b1c7 Update Norwegian Bokmål translation 2024-09-26 19:30:42 +00:00
Brage Fuglseth
8e6edd2793 Update Norwegian Bokmål translation 2024-09-26 19:27:16 +00:00
Kévin Commaille
467e40b6c9 metainfo: Use "snapshot" type for development releases
"development" is more for beta releases.
2024-09-26 13:42:36 +00:00
Juliano de Souza Camargo
c1c9f7a587 Update Brazilian Portuguese translation 2024-09-26 12:40:28 +00:00
Martin
b397ae55e7 Update Slovenian translation 2024-09-26 09:42:54 +00:00
Kévin Commaille
7e672a7bab
Release Fractal 9.beta 2024-09-26 09:47:25 +02:00
Yuri Chornoivan
3e82e98057 Update Ukrainian translation 2024-09-25 16:37:28 +00:00
Tim Sabsch
50a5852df8 Update German translation 2024-09-25 14:50:06 +00:00
Kévin Commaille
a8faf271b9 metainfo: Link to stable branch for screenshots 2024-09-25 13:46:28 +00:00
Luming Zh
be2b2906b0 Update Chinese (China) translation 2024-09-25 13:16:51 +00:00
Kévin Commaille
ae8fed98cf
ci: Use GNOME 47 Flatpak runtime for the build test job 2024-09-25 12:34:32 +02:00
Kévin Commaille
919d1ae985
room: Add trace-level logs for debugging notification count 2024-09-25 12:19:49 +02:00
Kévin Commaille
1f19619df0
room: Remove trace-level logs to debug unread status 2024-09-25 12:09:29 +02:00
Kévin Commaille
3f7a98c4c1
room-history: Use local time for day dividers
They used UTC time, which is why sometimes the date that they show was
wrong.
2024-09-25 12:00:36 +02:00
Kévin Commaille
6fbc12cddd
chore: Upgrade matrix-sdk and ruma crates 2024-09-25 11:21:11 +02:00
Kévin Commaille
8d25e9c4ef
application: Log for network changes in a single place
And only log when the network state has actually changed.
To reduce the noise in the logs.
2024-09-25 10:03:56 +02:00
Kévin Commaille
82ea97945a room-history: Spawn event cancellation on tokio runtime
The methods called need by Timeline::redact need access to a tokio
runtime.
2024-09-25 07:50:26 +00:00
Guillaume Girol
a58016e64e sidebar: scroll to the selected room when switching room
it might be invisible when switching with ctrl+*
2024-09-25 08:42:59 +02:00
Guillaume Girol
bfafa8c1f3 session: add a keyboard shortcut to go to an unread room
Pressing ctrl+* switches to a room with
- a mention (actually a notification count)
- or any unread message (a room in bold)
- and distinct from the current one

In case rooms with mentions and unread messages are both present,
mentions are preferred.

Favorites sections are also chosen preferentially.

this enables the following workflow:
repeatedly pressing ctrl+* visits all channels with something to be read,
starting with mentions and favorite rooms.

This feature is present in weechat and nheko (bound to alt+A)
2024-09-25 08:42:49 +02:00
Luming Zh
e6cad63983 Update Chinese (China) translation 2024-09-25 01:16:05 +00:00
Martin
7514c4ff66 Update Slovenian translation 2024-09-24 19:35:45 +00:00
Yuri Chornoivan
5be38a3b02 Update Ukrainian translation 2024-09-24 16:24:59 +00:00
Kévin Commaille
90354ff788 misc: Change "unknown" to "unexpected" in error messages
It is not true that the errors are unknown. We just don't handle them
because they are not expected to occur.
2024-09-24 14:26:01 +00:00
Martin
e79e408baa Update Slovenian translation 2024-09-24 13:36:29 +00:00
Kévin Commaille
8969c51976
account-settings: Do not offer to edit avatar or display name when disabled on homeserver 2024-09-24 12:55:54 +02:00
Kévin Commaille
a06e5c6e61
editable-avatar: Show an error if avatar could not be loaded 2024-09-24 12:55:54 +02:00
Kévin Commaille
2090a8b59e
completion-popover: Use the correct count for the number of rows 2024-09-24 12:46:56 +02:00
Kévin Commaille
acd319da16
media-viewer: Add a context menu to copy or save the media 2024-09-24 12:07:40 +02:00
Kévin Commaille
4e145419e7 offline-banner: Log when network is not available 2024-09-24 09:55:46 +00:00
Kévin Commaille
a28744f34b session: Log when network is not available 2024-09-24 09:55:46 +00:00
Alexandre Franke
bca4665e36 style: add padding below room filter bar
Fixes #1499+
2024-09-24 09:29:46 +02:00
Alexandre Franke
28a9c8855b style: remove leftover from popover 2024-09-24 09:29:45 +02:00
Luming Zh
3f4948eb39 Update Chinese (China) translation 2024-09-21 12:11:35 +00:00
Asier Sarasua Garmendia
7ac839fad6 Update Basque translation 2024-09-21 08:09:12 +00:00
Rafael Fontenelle
d38272e67a Update Brazilian Portuguese translation 2024-09-21 02:42:00 +00:00
Yuri Chornoivan
904a6da4df Update Ukrainian translation 2024-09-20 18:57:05 +00:00
Martin
a66e5bb100 Update Slovenian translation 2024-09-20 17:19:24 +00:00
Kévin Commaille
cbc84a25d4
auth-dialog: Shorten string 2024-09-20 11:06:47 +02:00
Kévin Commaille
e661afc1cf
session: Offer to reset backup instead of enabling it if it exists on the server
Because enabling it will fail if it already exists.
2024-09-20 10:28:28 +02:00
Alexandre Franke
f7109daa59 gitlab: add bug label to issue template 2024-09-18 19:51:17 +02:00
Kévin Commaille
cc5a737f21
components: Rename ButtonRow to LoadingButtonRow and prefer AdwButtonRow where possible 2024-09-18 18:20:09 +02:00
Kévin Commaille
4a26fca3b7
components: Replace Spinner with AdwSpinner 2024-09-18 15:31:57 +02:00
Kévin Commaille
09cb50ce4b
misc: Enable libadwaita 1.6 cargo feature 2024-09-18 14:58:29 +02:00
Kévin Commaille
b4bbba2d37
style: Use CSS variables and functions
That were added in GTK 4.16 and libadwaita 1.6.
2024-09-18 12:18:13 +02:00
Kévin Commaille
25d861f7e0
build: Use ffmpeg-full extension instead of building libheif manually
It already includes libheif.
2024-09-17 18:17:36 +02:00
Kévin Commaille
62fa87e272
chore: Upgrade libshumate and glycin 2024-09-17 17:56:16 +02:00
Kévin Commaille
2003b7bfae
ci: Do not duplicate Flatpak manifest for CI
Instead use commands to modify the manifest before using it.
2024-09-17 16:22:02 +02:00
Kévin Commaille
6c67393d88
chore: Upgrade matrix-sdk and ruma crates 2024-09-17 16:22:02 +02:00
Kévin Commaille
7e64373340
ci: Use mold from rust-nightly extension in docs job 2024-09-17 13:11:44 +02:00
Kévin Commaille
17890b5d8e
chore: Fix new clippy warnings 2024-09-17 13:11:43 +02:00
Kévin Commaille
2aec255fcd
chore: Use 24.08 branch of freedesktop.org Flatpak extensions 2024-09-17 11:44:49 +02:00
Yuri Chornoivan
ffae75bc34 Update Ukrainian translation 2024-09-15 16:40:32 +00:00
Juliano de Souza Camargo
d4b36a7d4c Update Brazilian Portuguese translation 2024-09-11 11:58:59 +00:00
Jürgen Benvenuti
ba5901168d Update German translation 2024-09-11 09:25:05 +00:00
Daniel Rusek
05898dc06c Update Czech translation 2024-09-10 16:18:09 +00:00
Artur S0
12492b7084 Update Russian translation 2024-09-10 14:03:54 +00:00
Kévin Commaille
acb74e6ace
chore: Upgrade matrix-sdk and ruma 2024-09-10 10:12:35 +02:00
Yaron Shahrabani
ff890596c7 Update Hebrew translation 2024-09-08 18:36:47 +00:00
Jiri Grönroos
0a59e3581b Update Finnish translation 2024-09-08 10:45:32 +00:00
Danial Behzadi
71b843464b Update Persian translation 2024-09-07 12:10:41 +00:00
Luming Zh
298e933373 Update Chinese (China) translation 2024-09-06 11:54:35 +00:00
Yuri Chornoivan
b232414407 Update Ukrainian translation 2024-09-05 18:54:37 +00:00
Martin
049d66a936 Update Slovenian translation 2024-09-05 15:39:26 +00:00
Veronika Bušová
dbbc5f457d sidebar: Add a 'Mark as Read' button to the context menu for rooms 2024-09-05 13:03:09 +00:00
Kévin Commaille
b04471e693
room: Use timeline to watch read status change triggers
Should avoid a race condition where the data in the timeline is
not updated yet when we check if receipts have changed.
2024-09-03 12:47:43 +02:00
Kévin Commaille
cb5b350b66
secret: Avoid some allocations 2024-09-03 11:59:47 +02:00
Kévin Commaille
419d0f036c
secret: Use constants for keys
To avoid errors in strings
2024-09-03 11:43:12 +02:00
Kévin Commaille
f6abd0cb55
secret: Do not translate strings that are not presented in the UI 2024-09-03 11:32:12 +02:00
Kévin Commaille
f543ba5477
window: Truncate current session ID to be compatible with StoredSession migration 2024-09-03 11:19:09 +02:00
Luming Zh
79f85e92b0 Update Chinese (China) translation 2024-09-03 00:17:35 +00:00
Martin
42041f3663 Update Slovenian translation 2024-09-02 19:23:02 +00:00
Yuri Chornoivan
1c9754f02f Update Ukrainian translation 2024-09-02 18:40:55 +00:00
Kévin Commaille
7c34c27d3e
session: Use a different path for the media cache
Since this requires a migration of the secret module,
we also truncate the session IDs that are needlessly long,
to be able to log them without adding too much noise.
2024-09-02 18:29:16 +02:00
Kévin Commaille
97fb610569
secret: Do not support secret versions from before Fractal 5 anymore
These would only have been for users of the nightly version so
it should be fine to drop support for them.
2024-09-02 18:29:15 +02:00
Kévin Commaille
59a62b8552
chore: Upgrade matrix-sdk crate
And run `cargo update`.
2024-09-02 18:29:05 +02:00
Tobias Kuendig
20a2342de1 room-history: Minor UI tweaks
Center the send message icon visually and increase the right margin of sender avatars.
2024-09-02 10:20:03 +00:00
Feliks Weber
006aa1196c Update German translation 2024-08-30 16:10:41 +00:00
Alexandre Franke
b05d19ebda Update French translation 2024-08-30 09:40:30 +00:00
Kévin Commaille
12b9dc6cc3
utils: Remove unnecessary debug logging 2024-08-27 11:34:10 +02:00
Kévin Commaille
1abe1cfef1
readme: Improve alt text and set dimensions of screenshot 2024-08-25 12:27:06 +02:00
Kévin Commaille
2b3b0403fe
cargo: Disable image default features
We do not need to encode or decode to specific formats so we do not
need those features.
2024-08-22 16:36:20 +02:00
Kévin Commaille
e5e172b69a
misc: Only animate animated paintables when they are displayed
Relies on whether the widgets that show the paintable are mapped.
2024-08-22 16:22:28 +02:00
Kévin Commaille
acc625cd20
utils: Allow to provide the requested size when loading an image
Useful for SVGs, so the renderer can render it at the size we want,
instead of returning the texture at the default size which we resize
later and that might result in a blurry image, defeating the purpose
of using a vector image.
2024-08-21 12:07:50 +02:00
Kévin Commaille
7ac70efecd
utils: Refactor image module
Try to avoid duplication of logic
2024-08-21 11:02:42 +02:00
Kévin Commaille
7d000f97f2
utils: Generate thumbnails for videos 2024-08-18 14:30:09 +02:00
Kévin Commaille
23d903e0eb
utils: Rename methods with load prefix rather than get 2024-08-18 10:09:43 +02:00
Kévin Commaille
e862909a1b
gitlab: Add environment variable to enable line wrapping in journalctl for logs 2024-08-17 11:22:47 +02:00
Kévin Commaille
f3ea74df83
avatar-image: Be smarter when downloading thumbnail
Use the same logic as other thumbnails, but prefer to get a thumbnail
rather than the original when dimesions are unknown.
Fixes SVG avatars not working.
2024-08-17 11:05:54 +02:00
Kévin Commaille
598544e422
media: Be smarter when downloading thumbnails
Prefer the original if it's not too big.
Also prefer thumbnails of the original rather than thumbnails of the
thumbnail.
2024-08-14 12:59:44 +02:00
Kévin Commaille
95eab61130
utils: Split image methods into a separate module 2024-08-14 10:39:51 +02:00
Kévin Commaille
d0ec5dacaf
message-toolbar: Be smarter about generated thumbnail
Always use WebP to generate thumbnails, as it is known to be widely
supported and have a good compression ratio.
Only generate thumbnails when the bandwith savings make sense.
2024-08-14 10:10:58 +02:00
Kévin Commaille
9ff06b8a2f
media: Use glycin to load images
It is sandboxed so loading unknown media is safer.
It also supports more formats than image-rs.
2024-08-12 12:25:02 +02:00
Kévin Commaille
96d55e3ffb
utils: Create VisualMediaMessage to refactor image and video message codes
And other refactoring.
2024-08-11 13:00:03 +02:00
Kévin Commaille
dd9539e93f
utils: Create MediaMessage to simplify interactions with media messages 2024-08-10 17:20:33 +02:00
Kévin Commaille
996590deeb
room-details: Rename MediaHistroyViewer to VisualMediaHistoryViewer
This is more correct as audio and file are also media messages.
2024-08-10 16:10:19 +02:00
Kévin Commaille
05c24c418e
message-row: Rename MessageMedia to MessageVisualMedia
This is more correct as audio and file are also media messages.
2024-08-10 15:43:37 +02:00
Kévin Commaille
95bd26d6cd
message-row: Replace MediaState with LoadingState 2024-08-10 15:33:15 +02:00
Juliano de Souza Camargo
2b211360a6 Update Brazilian Portuguese translation 2024-08-09 17:38:28 +00:00
Johannes Zellner
b697a2dd7e room-history: Hide reaction count label if it is 1 2024-08-08 10:18:51 +00:00
Martin
e96c1301d3 Update Slovenian translation 2024-08-04 09:53:04 +00:00
Martin
90c1f1125d Update Slovenian translation 2024-08-03 10:44:36 +00:00
Kévin Commaille
4782f43007
room: Improved debugging details for read receipts 2024-08-03 10:58:09 +02:00
Martin
f99d65b8d3 Update Slovenian translation 2024-08-02 17:46:19 +00:00
Martin
278a8eace5 Update Slovenian translation 2024-08-02 17:31:24 +00:00
Martin
9e011c16b1 Update Slovenian translation 2024-08-02 16:59:54 +00:00
Alexandre Franke
f9c48e5e1f Update French translation 2024-08-02 12:12:15 +00:00
Kévin Commaille
60fdd7fa78
chore: Fix new clippy warnings 2024-08-02 11:08:21 +02:00
Kévin Commaille
012d01f5c7
build: Rename sandboxed option to sandboxed-build
To make its purpose clearer
2024-08-02 10:33:28 +02:00
Martin
10f614e4a3 Update Slovenian translation 2024-08-01 22:23:40 +00:00
Martin
2b430e15dd Update Slovenian translation 2024-08-01 17:00:15 +00:00
Kévin Commaille
787260bae6
room-history: Make read receipts button round when there is a single user 2024-08-01 12:18:36 +02:00
Kévin Commaille
d3377424ce
room-history: Add trace logs to debug sticky fails 2024-08-01 11:36:15 +02:00
Kévin Commaille
d447bfb875
sidebar: Add trace logs to debug wrongly unread rooms 2024-08-01 11:35:22 +02:00
Kévin Commaille
10611e379e
Release Fractal 8 2024-08-01 09:49:42 +02:00
Alexandre Franke
a815ce84d2 Update French translation 2024-07-31 09:12:42 +00:00
Scrambled 777
10e5f914d7 Update Hindi translation 2024-07-29 17:46:37 +00:00
Martin
62edebc451 Update Slovenian translation 2024-07-28 11:09:34 +00:00
Kévin Commaille
bf370d4102
account-details: Add translator comments about deactivation 2024-07-27 15:13:28 +02:00
Martin
e8b18dddae Update Slovenian translation 2024-07-27 10:01:51 +00:00
Kévin Commaille
e4acd03c02
docs: Simplify fenv instructions 2024-07-26 12:42:13 +02:00
Daniel Rusek
29f0c3dcf9 Update Czech translation 2024-07-24 17:56:12 +00:00
Yosef Or Boczko
6b243592c6 Update Hebrew translation 2024-07-24 08:51:42 +00:00
Brage Fuglseth
f66af4b9f8 Update Norwegian Bokmål translation 2024-07-22 16:15:09 +00:00
Artur S0
4138d08227 Update Russian translation 2024-07-22 12:40:57 +00:00
Martin
6a82e60dc2 Update Slovenian translation 2024-07-22 05:40:03 +00:00
Ekaterine Papava
63e16cf7e3 Update Georgian translation 2024-07-22 04:36:36 +00:00
Martin
8fdfc5beaf Update Slovenian translation 2024-07-21 10:29:23 +00:00
Yuri Chornoivan
9c686151c1 Update Ukrainian translation 2024-07-20 13:22:06 +00:00
Anders Jonsson
7cf8ec8f96 Update Swedish translation 2024-07-20 11:23:39 +00:00
Luming Zh
4af5d94c52 Update Chinese (China) translation 2024-07-20 10:26:08 +00:00
Lukáš Tyrychtr
11f36a6b71 sidebar: Add number of notifications to room a11y label 2024-07-20 09:31:19 +00:00
Kévin Commaille
e96a8532d4
misc: Intercept activation of Matrix URIs in room descriptions 2024-07-19 16:11:21 +02:00
Kévin Commaille
ff64385e0d
utils: Detect Matrix identifiers with the linkifier 2024-07-19 16:11:21 +02:00
Scrambled 777
022fba49d2 Update Hindi translation 2024-07-19 10:30:59 +00:00
Brage Fuglseth
8ecaee041d Update Norwegian Bokmål translation 2024-07-18 17:17:02 +00:00
Luming Zh
ebb42f0227 Update Chinese (China) translation 2024-07-18 11:22:38 +00:00
Kévin Commaille
d87059b16f
chore: Release Fractal 8.rc 2024-07-18 11:02:34 +02:00
Kévin Commaille
a9d360b1bd chore: Upgrade matrix-sdk 2024-07-18 08:36:54 +00:00
Maximiliano Sandoval
566c9f0d02 icon_item_row: Align icon
Fixes: https://gitlab.gnome.org/World/fractal/-/issues/1319
2024-07-17 18:27:14 +00:00
Yuri Chornoivan
90bf7ca1ce Update Ukrainian translation 2024-07-17 17:58:33 +00:00
Kévin Commaille
62d0c54d03
room-details: Remove title popover 2024-07-17 17:32:11 +02:00
Kévin Commaille
7ba4b0b980
ci: Run Rust tests in a separate job 2024-07-17 17:31:25 +02:00
Kévin Commaille
84c3e6df70
ci: Rename pages.yaml to docs.yml 2024-07-17 17:31:25 +02:00
Kévin Commaille
099dcc9ccf
ci: Rename Flatpak manifest for build-stable jobs
And convert to YAML
2024-07-17 17:31:25 +02:00
Kévin Commaille
038682b6b0 join-room: Replace "permalink" with "link" in UI string 2024-07-17 15:01:51 +00:00
Yuri Chornoivan
65089be0a6 Update Ukrainian translation 2024-07-17 11:07:47 +00:00
Luming Zh
456d22bf6a Update Chinese (China) translation 2024-07-17 10:23:00 +00:00
Kévin Commaille
b9e4a5da60
room-creation: Change "topic" to "description" and use a text view for the field 2024-07-17 10:17:16 +02:00
Kévin Commaille
0cc17d8c85
room-details: Replace "topic" with "description" in UI string 2024-07-17 10:03:14 +02:00
Kévin Commaille
a8f40acb9a
misc: Linkify room topics in more places 2024-07-17 09:58:04 +02:00
Yuri Chornoivan
f2d30fd573 Update Ukrainian translation 2024-07-17 06:39:28 +00:00
Kévin Commaille
aec018d627
ci: Fix pages job 2024-07-16 22:36:34 +02:00
Kévin Commaille
5acfd1305f
ci: Depend on rust nightly for docs generation again
Also add a job to test docs generation for MRs
2024-07-16 22:06:39 +02:00
Kévin Commaille
93f16b945c
room-details: Edit main room details in a subpage 2024-07-16 20:26:28 +02:00
Kévin Commaille
c375b29602
room-details: Move files 2024-07-16 20:19:47 +02:00
Kévin Commaille
a4c4dcf1fa
chore: Upgrade gtk-rs crates and dependants 2024-07-16 18:56:54 +02:00
Kévin Commaille
7bf868c498 sidebar: Allow to change whether a room is a direct chat 2024-07-16 13:54:59 +00:00
Luming Zh
b06104ecf6 Update Chinese (China) translation 2024-07-16 11:13:58 +00:00
Kévin Commaille
0d45fb6204 chore: Upgrade crate dependencies 2024-07-16 10:46:09 +00:00
Anders Jonsson
a9ecc9b88e Update Swedish translation 2024-07-16 10:44:39 +00:00
Yuri Chornoivan
0bb4cc20b5 Update Ukrainian translation 2024-07-16 06:01:20 +00:00
Kévin Commaille
3d24258692 login: Show more info during initial sync 2024-07-15 15:36:15 +00:00
Kévin Commaille
c066d4efe7
misc: Remove "to clipboard" for tooltips for copy actions
A tooltip is supposed to be short and this part should be obvious.
2024-07-15 16:27:44 +02:00
Ekaterine Papava
4ed24aa859 Update Georgian translation 2024-07-15 03:52:41 +00:00
Kévin Commaille
be6e8516b4
user-profile: Fix size, spacing and duplicate title 2024-07-14 16:58:14 +02:00
Kévin Commaille
354668568e
ci: Do not run tests for CiTest builds
Given that they are built in release mode, they already take longer to
compile.
If we run cargo test, they will be compiled again in debug mode and are
very likely to reach the timeout.
2024-07-13 23:09:48 +02:00
Kévin Commaille
479005909c
ci: Disable building protoc-c in CiTest flatpak too 2024-07-13 16:54:44 +02:00
Kévin Commaille
64d514cfc7
room-history: Visual fixes to the title 2024-07-13 16:20:56 +02:00
Kévin Commaille
a11204394f build: Do not build protoc-c with protobuf-c
It is not needed to build or use libshumate.
2024-07-13 13:29:27 +00:00
Luming Zh
134d0e96dc Update Chinese (China) translation 2024-07-13 12:43:36 +00:00
Yuri Chornoivan
a42fe6344f Update Ukrainian translation 2024-07-13 06:21:38 +00:00
Kévin Commaille
411774bd5b
misc: Change wording around permalinks 2024-07-12 16:43:25 +02:00
Kévin Commaille
773623a6b8
room-history: Reactions and receipts UI fixes
Remove the hover effect on the reaction container due to a change in
libawaita.
Make receipts button rounded and center avatars vertically.
2024-07-12 15:55:32 +02:00
Kévin Commaille
bbc0d9ba17
room-history: Move menu entry to copy room permalink to room details 2024-07-12 12:48:08 +02:00
Kévin Commaille
76872115fd
sidebar: Fix room filter 2024-07-12 12:14:08 +02:00
Kévin Commaille
711a1ba259 sidebar: Restore the expanded state of categories
Requires to replace GtkTreeListModel, as it doesn't allow us to set
the initial expanded state per item.
2024-07-12 09:16:11 +00:00
Kévin Commaille
c236c91de1 sidebar: Rename ItemList to SidebarItemList 2024-07-12 09:16:11 +00:00
Luming Zh
7b6b360357 Update Chinese (China) translation 2024-07-11 10:57:07 +00:00
Kévin Commaille
51fe880533
build: Add cargo tests 2024-07-11 09:57:34 +02:00
Kévin Commaille
fb1f4b3c96
completion-popover: Show autocompletion when hashtag is entered 2024-07-10 17:14:01 +02:00
Kévin Commaille
dfc4a052de
linkifier: Detect also URLs that do not have a scheme and matrix: URIs 2024-07-10 16:10:55 +02:00
Yuri Chornoivan
4856854e17 Update Ukrainian translation 2024-07-10 03:50:44 +00:00
Brage Fuglseth
979aa38318 Update Norwegian Bokmål translation 2024-07-09 22:39:40 +00:00
Kévin Commaille
9f796716f3
room-details: Support more states for the media history viewers
Show when the list is loading more items, when there is an error, and
show a different state when the list is empty.
2024-07-09 18:37:12 +02:00
Kévin Commaille
d29f86c7ba
room-title: Deactivate markup in header bar
There is not supposed to be markup in a room name or topic so don't
enable it otherwise Pango complains about characters like `&`.
2024-07-09 17:24:18 +02:00
Luming Zh
5f71d65914 Update Chinese (China) translation 2024-07-09 11:23:05 +00:00
Yuri Chornoivan
b33352a426 Update Ukrainian translation 2024-07-09 04:47:29 +00:00
Kévin Commaille
40c9ec24ad
room: Fix setting ignored category
Since the method did not return early, the category would always be
overwritten.
2024-07-08 12:42:40 +02:00
Kévin Commaille
2089a3c929
invite: Allow to ignore the user when declining an invite 2024-07-08 12:42:30 +02:00
Kévin Commaille
0073b0da44
invite: Show more details about room and inviter
So the user can make a more informed choice.
2024-07-08 12:13:52 +02:00
Kévin Commaille
8893e9bbaa
session: Make sure that send queues have access to a tokio executor on construction
They might need it.
2024-07-08 10:49:11 +02:00
Yuri Chornoivan
f0d0b75753 Update Ukrainian translation 2024-07-07 15:14:22 +00:00
Kévin Commaille
28e8395182
room: Restart the send queue regularly when an error that disabled it is encountered 2024-07-07 15:14:26 +02:00
Kévin Commaille
3d511e9ef0
session: Restart send queues when session is not offline anymore 2024-07-07 14:30:18 +02:00
Kévin Commaille
fd95fe304c
session: Respawn tasks of send queue during session initialization 2024-07-07 14:18:56 +02:00
Kévin Commaille
36aa3a25eb
session: Mark session as offline when sync fails 2024-07-07 14:18:09 +02:00
Kévin Commaille
4d0f22f36e
room-history: Allow to view full room title and description in a popover
Also allows to click any link.
2024-07-07 11:05:53 +02:00
Kévin Commaille
d147ab0e28
identity-verification-view: Make sure all buttons have can-shrink set
Avoids sizing issues on small screens
2024-07-06 10:34:03 +02:00
Kévin Commaille
3d5c16d284
message-toolbar: Refactor buffer anchor creation
Centralize the creation in ComposerState::add_widget to reduce code
duplication.
2024-07-05 17:39:31 +02:00
Kévin Commaille
285ae92852
message-toolbar: Persist drafts in the database 2024-07-05 16:38:41 +02:00
Kévin Commaille
ed3dca6cb0
message-toolbar: Ensure ComposerStates are unique per room and per session 2024-07-05 15:12:36 +02:00
Kévin Commaille
3244d34c57
message-toolbar: Make sure we don't reinsert widgets that have been removed 2024-07-05 15:11:39 +02:00
Kévin Commaille
fd05688c97
message-toolbar: Refactor message buffer iterator 2024-07-05 15:06:00 +02:00
Kévin Commaille
41a7038be1
room: Only expose room aliases with the RoomAliases object 2024-07-05 14:45:36 +02:00
Kévin Commaille
7e6c3a1798
utils: Get rid of MatrixRoomId
It turns out we can do everything with OwnedRoomOrAliasId
2024-07-05 14:39:36 +02:00
Brage Fuglseth
dfdaadcf05 Update Norwegian Bokmål translation 2024-07-03 20:02:46 +00:00
Kévin Commaille
c0ffcbd407
chore: Release Fractal 8.beta 2024-07-03 15:16:10 +02:00
Kévin Commaille
213eca3074
ci: Do not depend on rust nightly for docs generation
The rust-nightly Flatpak SDK extension is deprecated, and my attempts
to bundle it in a Flatpak manifest have failed.

This removes a few nice features like the index page, or types linking
to their docs in the corresponding crate's docs.
2024-07-03 12:34:45 +02:00
Kévin Commaille
de02f09465
user: Clean up debug logs
They should not have been merged.
2024-07-02 18:36:13 +02:00
Kévin Commaille
59e4555215
message-toolbar: Keep track of the composer state between room switches 2024-07-02 18:33:50 +02:00
Scrambled 777
a0a2b8ae9d Update Hindi translation 2024-07-02 07:49:29 +00:00
Yuri Chornoivan
abc3d9aaf6 Update Ukrainian translation 2024-07-01 19:16:10 +00:00
Kévin Commaille
48e1867aa3
ci: Add manual job to test Flatpak build against stable runtime 2024-07-01 14:19:44 +02:00
Kévin Commaille
dbfbef8684 chore: Update gnome-nightly runtime extensions to 24.08beta 2024-07-01 11:39:38 +00:00
Luming Zh
bccf5c1330 Update Chinese (China) translation 2024-07-01 11:05:00 +00:00
Kévin Commaille
d2c7639d3c
verification: Get user crypto identity remotely if we do not have it locally 2024-06-30 12:27:36 +02:00
Kévin Commaille
cfcadaaf7f
chore: Upgrade matrix-sdk crate 2024-06-29 10:50:37 +02:00
Kévin Commaille
fd759155b3
chore: Use new glib::clone! macro syntax 2024-06-26 13:09:47 +02:00
Kévin Commaille
0a3f59b0f6
chore: Upgrade crate dependencies 2024-06-26 09:25:31 +02:00
Alexandre Franke
1548cc5c2f Add translator comments 2024-06-22 18:56:09 +02:00
Luming Zh
29af084d11 Update Chinese (China) translation 2024-06-18 12:11:40 +00:00
Yuri Chornoivan
0a74a89f38 Update Ukrainian translation 2024-06-17 16:47:29 +00:00
Kévin Commaille
cb2c72b7bb
notifications: Show notifications for new identity verification requests
Also makes sure that clicking on a notification for an in-room
verification
opens the verification rather than the room.
2024-06-17 15:10:50 +02:00
Kévin Commaille
b43dd41cc2
chore: Fix clippy warning 2024-06-17 11:44:23 +02:00
Kévin Commaille
3fc350abc5
verification: Allow to dismiss verification when room was left 2024-06-17 11:44:23 +02:00
Scrambled 777
a14a92b017 Add Hindi translation 2024-06-15 14:12:15 +00:00
Kévin Commaille
19f1c54856
chore: Upgrade libshumate and protobuf-c dependencies 2024-06-10 15:13:36 +02:00
Brage Fuglseth
9982260c51 Update Norwegian Bokmål translation 2024-06-04 17:38:05 +00:00
Brage Fuglseth
b4f551b49c Update Norwegian Bokmål translation 2024-06-04 17:32:46 +00:00
Ekaterine Papava
75240c6686 Update Georgian translation 2024-06-02 21:26:31 +00:00
Luming Zh
dc25cbf0ee Update Chinese (China) translation 2024-05-30 10:52:20 +00:00
Yuri Chornoivan
9dd278aa98 Update Ukrainian translation 2024-05-29 16:38:07 +00:00
Kévin Commaille
59b06567fc account-settings: Allow to force the logout of the session 2024-05-29 14:17:57 +00:00
Luming Zh
53c2017538 Update Chinese (China) translation 2024-05-29 12:36:44 +00:00
Kévin Commaille
a70a12db15
account-settings: Allow to reset completely account recovery to fix any issue with it 2024-05-29 11:14:01 +02:00
Jiri Grönroos
9a417e54dc Update Finnish translation 2024-05-25 16:48:55 +00:00
Boyuan Yang
c30320111e Update Chinese (China) translation 2024-05-25 16:32:56 +00:00
Luming Zh
54a35e162f Update Chinese (China) translation 2024-05-24 12:28:42 +00:00
Kévin Commaille
9dfb90c94e
components: Remove Components prefix in widget classes 2024-05-23 15:23:12 +02:00
Kévin Commaille
105f0745b7
components: Group media components 2024-05-23 15:20:51 +02:00
Kévin Commaille
362d4f5a7c
components: Group dialog components 2024-05-23 15:05:35 +02:00
Kévin Commaille
ae553500c3
components: Rename loading property of LoadingButton to is-loading 2024-05-23 13:05:02 +02:00
Kévin Commaille
31cb11d152
components: Rename SpinnerButton to LoadingButton 2024-05-23 12:20:25 +02:00
Kévin Commaille
8f7c7de8d4
components: Group loading components 2024-05-23 12:17:30 +02:00
Kévin Commaille
a03924ea0e
components: Group avatar components 2024-05-23 12:17:14 +02:00
Kévin Commaille
246082803d
room-details: Watch expressions so members list gets updated correctly 2024-05-22 13:05:32 +02:00
Kévin Commaille
488362bd6d
utils: Take an impl IsA<gio::ListModel> for ExpressionListModel
Then we only need to upcast in one place.
2024-05-22 13:05:32 +02:00
Kévin Commaille
8ad56b88e7
room-details: Pop proper navigation view when user page is closed, 2024-05-22 13:05:32 +02:00
Kévin Commaille
69022e9b09
room-history: Allow to copy and open media with caption 2024-05-22 12:12:21 +02:00
Yuri Chornoivan
19e90e210f Update Ukrainian translation 2024-05-22 06:45:17 +00:00
Kévin Commaille
f4e6a887f9
error: Improve secret portal error instructions 2024-05-21 17:04:18 +02:00
Kévin Commaille
764ccb5946
chore: Upgrade crates
Less syn 1 dependencies!
2024-05-21 15:31:02 +02:00
Luming Zh
f5a690a5fc Update Chinese (China) translation 2024-05-20 12:04:35 +00:00
Boyuan Yang
ecfada11ef Update Chinese (China) translation 2024-05-19 15:56:17 +00:00
Kévin Commaille
01432f796d
message-toolbar: Refactoring 2024-05-15 14:46:04 +02:00
Kévin Commaille
223724c043
message-toolbar: Use intentional mentions for text messages 2024-05-15 14:46:04 +02:00
Kévin Commaille
1b0a746fbb
chore: Upgrade matrix-sdk and ruma crates 2024-05-15 14:46:04 +02:00
Kévin Commaille
664cc0c58f
room-history: Fix plain text emotes updates
The name of the sender was not passed when the emote was updated.
2024-05-13 11:30:02 +02:00
Yuri Chornoivan
fdd55f4af4 Update Ukrainian translation 2024-05-12 14:55:08 +00:00
Kévin Commaille
5e4efe2de8
room-history: Display @room mentions as pills
Only works if the user should be able to trigger the notification.
2024-05-11 16:06:45 +02:00
Kévin Commaille
18050acb14
message-toolbar: Detect @room mentions for editing a message 2024-05-11 16:06:45 +02:00
Kévin Commaille
08284e53e6
message-toolbar: Add @room auto-completion 2024-05-11 16:06:45 +02:00
Kévin Commaille
80a5a0dfc4
chore: Upgrade matrix-sdk crate 2024-05-11 16:06:45 +02:00
Rodrigo Lledó
3755d4edfb Update Spanish translation 2024-05-10 18:37:25 +00:00
Rodrigo Lledó
7fddffb94b Update Spanish translation 2024-05-10 18:32:42 +00:00
Yuri Chornoivan
2b4fe1b19e Update Ukrainian translation 2024-05-10 16:36:29 +00:00
Kévin Commaille
247b802109
explore: Avoid unnecessary clone 2024-05-10 18:00:05 +02:00
Kévin Commaille
3405ed347e
room-history: Add support for HTML details element 2024-05-10 15:58:30 +02:00
Kévin Commaille
7f438ac104
misc: Use ruma-html to sanitize and render HTML instead of html2pango 2024-05-09 20:25:00 +02:00
Kévin Commaille
5f81203659 chore: Upgrade crate deps (again) 2024-05-09 16:49:50 +00:00
Yuri Chornoivan
c3fa5c6a98 Update Ukrainian translation 2024-05-09 16:38:37 +00:00
Kévin Commaille
704213557d room-details: Refactor InviteSubpage 2024-05-09 14:56:41 +00:00
Alexandre Franke
b209eb6841 Update French translation 2024-05-09 14:18:08 +00:00
Danial Behzadi
fb00ec7f37 Update Persian translation 2024-05-08 14:06:34 +00:00
Kévin Commaille
3da6f5822a
room-history: Try routing via room ID's server when joining successor 2024-05-08 12:29:59 +02:00
Kévin Commaille
e4ecc68b4e
about: Open support room in Fractal if a session is connected 2024-05-07 11:15:17 +02:00
Kévin Commaille
a16f0cb060
message-toolbar: Properly send emote replies 2024-05-07 10:33:01 +02:00
Kévin Commaille
32fe805c19
secret: Remove unused error type 2024-05-06 17:43:39 +02:00
Kévin Commaille
e14269a7e8
label-with-widgets: Declare DEFAULT_PLACEHOLDER as an associated const
It doesn't really make sense on its own.
2024-05-06 17:38:02 +02:00
Kévin Commaille
d66a7689c2
chore: Upgrade crate dependencies 2024-05-06 17:34:48 +02:00
Kévin Commaille
3bf069f84c
build: Use id instead of app-id in Flatpak manifest
Even though I couldn't find any information about it,
`app-id` is marked as deprecated in the JSON schema of
Flatpak manifests, so it triggers a warning in my IDE.

Since `id` seems to be supported everywhere, let's just use it.
2024-05-04 19:40:09 +02:00
Kévin Commaille
d472ff1375
docs: Simplify instructions to install fenv 2024-05-04 19:36:11 +02:00
Kévin Commaille
714ef36829
secret: Improve error logs
Log the original error instead of the user-facing error.
2024-05-04 19:19:51 +02:00
Hugo Carvalho
60d1222bca Update Portuguese translation 2024-05-03 21:51:45 +00:00
Martin
192c0ddfdf Update Slovenian translation 2024-05-03 17:17:03 +00:00
Kévin Commaille
48a0c9261e
chore: Upgrade crate dependencies 2024-05-03 13:12:24 +02:00
Martin
d3b0592298 Update Slovenian translation 2024-05-03 06:05:52 +00:00
Alexandre Franke
dec825bbf4 Release Fractal 7 2024-05-02 13:59:55 +00:00
Hari Rana
451ba42638 user-page: Port ID elements to GtkCenterBox
This ports the user ID label and copy user ID button from GtkBox
to GtkCenterBox. While the GtkBox approach worked, it required us
to use magic numbers (in this case `46`) to center the label.
GtkCenterBox addresses that with a proper mechanism to center
the label, and place the copy user ID button to the end of the
widget, with a margin-start of 6. Visually, both implementations
should look nearly identical.
2024-05-02 11:21:21 +00:00
Hari Rana
7c05c71fa3
user-page: Center display name 2024-05-01 23:20:18 -04:00
Alexandre Franke
84357b6fc3 Update French translation 2024-05-01 13:03:09 +00:00
Martin
ba2bdd9e4e Update Slovenian translation 2024-04-29 15:02:09 +00:00
Artur S0
ff7dec6d78 Update Russian translation 2024-04-29 11:57:38 +00:00
Anders Jonsson
e2e44ff425 Update Swedish translation 2024-04-28 13:39:08 +00:00
Martin
481d7f9cca Update Slovenian translation 2024-04-27 22:36:49 +00:00
Philipp Kiemle
4d84923f64 Update German translation 2024-04-22 17:21:13 +00:00
Bart Piotrowski
3f79768ef6 doap: Fix syntax error, re-order maintainers 2024-04-19 07:09:08 +00:00
Andi Chandler
bbbb2cfbd7 Update British English translation 2024-04-18 20:05:10 +00:00
Kévin Commaille
5b38895ca7
Release Fractal 7.rc 2024-04-18 14:11:45 +02:00
Yuri Chornoivan
6273a3efc3 Update Ukrainian translation 2024-04-16 17:10:46 +00:00
Kévin Commaille
ee8628b1f5
utils: Avoid possible panic for notifications 2024-04-15 19:01:57 +02:00
Kévin Commaille
403d147118
identity-verification-view: Add sentence about having a secure verification 2024-04-15 18:59:23 +02:00
Kévin Commaille
6acc5d4498
room-history: Do not show verification requests in the timeline
The banner should be enough.
2024-04-15 18:09:58 +02:00
Kévin Commaille
207d1fa22f
room-history: Fix VerificationInfoBar
It would not show up anymore. Also more fixes around removal and visual
feedback.
2024-04-15 18:04:46 +02:00
Kévin Commaille
5404e92058
sidebar: Fix styling of verification row dot 2024-04-15 15:47:27 +02:00
Kévin Commaille
1a279e0b8e
typing-row: Move formatting outside of translatable string 2024-04-15 15:38:15 +02:00
Kévin Commaille
5e0e34e7da
room-history: Reduce number of avatars in typing indicator
There is the risk that a high number of avatars will make the indicator
take too much space in narrow screens.
2024-04-15 15:23:31 +02:00
Kévin Commaille
881cd55424
room-history: Reduce number of avatars for read receipts
Makes the interface a little less busy and reduces resources
consumption.
2024-04-15 15:22:19 +02:00
Kévin Commaille
3568cf2028
overlapping-avatars: Crop avatars instead of using borders
Avoids issues when the background color behind the avatars changes.
2024-04-15 13:28:06 +02:00
Kévin Commaille
a39c34bbde
components: Pill does not subclass AdwBin anymore 2024-04-15 12:07:13 +02:00
Yuri Chornoivan
25b4b05f77 Update Ukrainian translation 2024-04-14 15:15:22 +00:00
Kévin Commaille
2450c440a8 recovery-setup-view: Add screen to explain how to solve incomplete recovery 2024-04-14 09:12:19 +00:00
Kévin Commaille
46b2854004
message-toolbar: Show location dialog after obtaining permission
When the location services are disabled, a kind of race condition seems
to happen where the error is returned immediately and calling close on
the dialog does nothing.
The permission request should appear quickly, if it appears, so let's
show the dialog after that.
2024-04-13 17:32:31 +02:00
Kévin Commaille
404910dd67
sender-avatar: Do not subclass AdwBin to fix focus 2024-04-13 17:11:05 +02:00
Kévin Commaille
732678303d
pill: Fix activatable behavior, focus and add hover effect 2024-04-13 17:03:21 +02:00
Kévin Commaille
2254a505d5
read-receipts-list: Do not subclass AdwBin to fix keyboard focus 2024-04-13 16:20:46 +02:00
Kévin Commaille
5799c32120
context-menu-bin: Do not subclass AdwBin to fix keyboard focus
AdwBin overrides the GtkWidget::focus virtual method by only checking
if the children can be focused.
Not allowing the bin itself to be focused with tab navigation.
2024-04-13 16:16:48 +02:00
Kévin Commaille
eed598113e
build: Enable NO_POINTER_VIEWPORT workaround for nightly 2024-04-12 20:23:39 +02:00
Tobias Bernard
ced1a80c19 metaindo: update brand colors 2024-04-12 12:38:28 +02:00
Kévin Commaille
fe75a3f639
chore: Upgrade image rqrr and qrcode dependencies
Requires to upgrade matrix-sdk too.
And run cargo update.
2024-04-11 12:26:41 +02:00
Kévin Commaille
e81e65a8c2
session: Cache session profile to load it faster at startup
Avoids to have the fallback avatar and name for a while in certain cases
2024-04-11 11:45:04 +02:00
Sabri Ünal
04f7e8bf92 Update Turkish translation 2024-04-09 09:40:44 +00:00
Kévin Commaille
756fab832a account-settings: Do not send display name when entry is activated if it has not changed 2024-04-08 10:57:03 +00:00
Kévin Commaille
cafe822c1a account-settings: Refactoring 2024-04-08 10:57:03 +00:00
Alexandre Franke
2dfe996cf6 Update French translation 2024-04-08 10:47:48 +00:00
Bruce Cowan
752125a479 Update British English translation 2024-04-07 17:34:58 +00:00
Kévin Commaille
b6c719e920
ci: Move scripts/checks.sh to hooks
Avoids having 2 folders with a single file in it.
2024-04-05 17:34:36 +02:00
Kévin Commaille
cb392256bf
build: Add support for when the build is sandboxed
When using flatpak-cargo-generator, the crates cannot be placed in the
build dir before the build happens, so we must change the CARGO_HOME env
variable.
2024-04-05 17:25:07 +02:00
Kévin Commaille
26d7b2cb34
build: Target meson 1.1
It has been released almost a year ago so it should be fine
2024-04-05 17:21:15 +02:00
Kévin Commaille
01b49bffe5
ci: Do not create tarball for releases
Instead we will use the flatpak-cargo-generator script from
flatpak-builder-tools for Flathub builds.
This is not a problem for reproducible builds since everything has a
hash (commit or Cargo.lock).
2024-04-05 17:16:23 +02:00
Artur S0
b3a1b29aa9 Update Russian translation 2024-04-04 15:25:28 +00:00
Hugo Carvalho
c3c558a150 Update Portuguese translation 2024-04-03 19:56:09 +00:00
Nathan Follens
6458f99cf5 Update Dutch translation 2024-04-02 18:26:05 +00:00
Asier Sarasua Garmendia
ef97c6e160 Update Basque translation 2024-04-02 10:14:37 +00:00
Yuri Chornoivan
7c448ca64e Update Ukrainian translation 2024-03-28 19:48:51 +00:00
Alexandre Franke
c7c640aa22 string: disambiguate wording 2024-03-28 20:20:34 +01:00
591 changed files with 184688 additions and 89735 deletions

3
.gitignore vendored
View File

@ -11,4 +11,5 @@ src/config.rs
subprojects/libadwaita
subprojects/gtksourceview
.vscode
.fenv
.fenv
.zed

View File

@ -11,24 +11,15 @@ variables:
workflow:
rules:
- if: $CI_COMMIT_BRANCH || $CI_COMMIT_TAG
- if: $CI_COMMIT_BRANCH
include:
- local: .gitlab-ci/run_checks.yml
rules:
- if: $CI_COMMIT_TAG == null
- local: .gitlab-ci/build.yml
rules:
- if: $CI_COMMIT_TAG == null
- local: .gitlab-ci/test.yml
rules:
- if: $CI_COMMIT_TAG == null
- local: .gitlab-ci/publish_docs.yml
rules:
- if: $CI_COMMIT_BRANCH == "main"
- component: "gitlab.gnome.org/GNOME/citemplates/basic-deploy-docs@master"
inputs:
docs-job-name: "build-docs"
- local: .gitlab-ci/publish_nightly.yml
rules:
- if: $CI_COMMIT_BRANCH == "main"
- local: .gitlab-ci/create_release.yml
rules:
- if: $CI_COMMIT_TAG

View File

@ -1,6 +1,9 @@
# Build the Flatpak
include: 'https://gitlab.gnome.org/GNOME/citemplates/-/raw/master/flatpak/flatpak_ci_initiative.yml'
include:
- project: "GNOME/citemplates"
file: "flatpak/flatpak_ci_initiative.yml"
- local: '.gitlab-ci/utils.yml'
variables:
RUNTIME_REPO: "https://nightly.gnome.org/gnome-nightly.flatpakrepo"
@ -10,16 +13,41 @@ build@x86_64:
extends:
- .flatpak@x86_64
stage: build
after_script:
# Copy the metainfo file to the current directory.
- cp flatpak_app/files/share/metainfo/*.metainfo.xml .
artifacts:
paths:
- $BUNDLE
- 'repo.tar'
- '.flatpak-builder/build/${FLATPAK_MODULE}/_flatpak_build/meson-logs/meson-log.txt'
- '.flatpak-builder/build/${FLATPAK_MODULE}/_flatpak_build/meson-logs/testlog.txt'
- '.flatpak-builder/build/${FLATPAK_MODULE}/_flatpak_build/meson-logs/'
# Add the metainfo file for the corresponding test.
- '.flatpak-builder/build/${FLATPAK_MODULE}/_flatpak_build/data/${APP_ID}.metainfo.xml'
- '${APP_ID}.metainfo.xml'
build@aarch64:
extends:
- .flatpak@aarch64
stage: build
# Test builds with the stable runtime to make sure that the Flatpak will build on Flathub.
# Should be run manually before tagging a new release.
.build_stable:
extends:
- .stable_runtime
variables:
RUNTIME_REPO: "https://flathub.org/repo/flathub.flatpakrepo"
RUN_TESTS: 0
build-stable@x86_64:
extends:
- .flatpak@x86_64
- .build_stable
stage: build
when: manual
build-stable@aarch64:
extends:
- .flatpak@aarch64
- .build_stable
stage: build
when: manual

View File

@ -1,72 +0,0 @@
# Generate a tarball, test it, then publish it to the package registry and create a release
variables:
PACKAGE_REGISTRY_URL: "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/release-tarballs/${CI_COMMIT_TAG}"
RELEASE_TARBALL: "fractal-${CI_COMMIT_TAG}.tar.xz"
RELEASE_TARBALL_SHA: "fractal-${CI_COMMIT_TAG}.tar.xz.sha256sum"
METAINFO_PATH: "data/org.gnome.Fractal.metainfo.xml.in.in"
TARBALL_TEST_MANIFEST_PATH: ".gitlab-ci/org.gnome.Fractal.CiTest.json"
release-tarball:
stage: build
image: 'quay.io/gnome_infrastructure/gnome-runtime-images:gnome-master'
variables:
LANG: "C.UTF-8"
tags:
- flatpak
script:
# Create tarball with vendored rust dependencies
- flatpak-builder --keep-build-dirs --user --disable-rofiles-fuse --stop-at=${FLATPAK_MODULE} flatpak_app --repo=repo ${BRANCH:+--default-branch=$BRANCH} ${MANIFEST_PATH}
- echo "meson dist --no-test --allow-dirty" | flatpak-builder --disable-rofiles-fuse --build-shell=${FLATPAK_MODULE} flatpak_app ${MANIFEST_PATH}
- mv .flatpak-builder/build/${FLATPAK_MODULE}/_flatpak_build/meson-dist tarball
# Extract release notes of latest version from appstream
- appstreamcli metainfo-to-news --format markdown ${METAINFO_PATH} - |
awk '{ x[NR] = $0 } END { for ( i=5 ; i<=NR ; i++ ) { if (x[i] ~ /^$/ && x[i+1] ~ /^Version/ && x[i+2] ~ /^-/ && x[i+3] ~ /^Released:/) exit; else print x[i]; }}' >
release_notes.md
artifacts:
paths:
- tarball
- release_notes.md
test-tarball:
stage: test
image: 'quay.io/gnome_infrastructure/gnome-runtime-images:gnome-46'
tags:
- flatpak
script:
- TARBALL_SHA=$(cut -f 1 -d " " tarball/${RELEASE_TARBALL_SHA})
- sed -i "s|%%TARBALL_PATH%%|${PWD}/tarball/${RELEASE_TARBALL}|g" ${TARBALL_TEST_MANIFEST_PATH}
- sed -i "s|%%TARBALL_SHA%%|${TARBALL_SHA}|g" ${TARBALL_TEST_MANIFEST_PATH}
- flatpak-builder --user --disable-rofiles-fuse --sandbox flatpak_app --repo=repo ${BRANCH:+--default-branch=$BRANCH} ${TARBALL_TEST_MANIFEST_PATH}
# https://gitlab.com/gitlab-org/gitlab/-/issues/271534 The default URL needs authentication right now, which is less than optimal...
# Get the package_files ID instead and use that as download URL in the "release" step.
create-release:
stage: deploy
image: registry.gitlab.com/gitlab-org/release-cli:latest
script:
- apk add curl jq
# Upload tarball to package registry
- |
curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --upload-file tarball/${RELEASE_TARBALL} "${PACKAGE_REGISTRY_URL}/${RELEASE_TARBALL}"
- |
curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --upload-file tarball/${RELEASE_TARBALL_SHA} "${PACKAGE_REGISTRY_URL}/${RELEASE_TARBALL_SHA}"
# Get package IDs and build URLs
- |
export PACKAGE_ID=$(curl "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages?sort=desc" | jq -c .[0].id)
- |
export RELEASE_TARBALL_DOWNLOAD_ID=$(curl "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/${PACKAGE_ID}/package_files" | jq -c .[0].id)
export RELEASE_TARBALL_SHA_DOWNLOAD_ID=$(curl "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/${PACKAGE_ID}/package_files" | jq -c .[1].id)
- export RELEASE_TARBALL_URL="${CI_PROJECT_URL}/-/package_files/$RELEASE_TARBALL_DOWNLOAD_ID/download"
- export RELEASE_TARBALL_SHA_URL="${CI_PROJECT_URL}/-/package_files/$RELEASE_TARBALL_SHA_DOWNLOAD_ID/download"
- cat release_notes.md
# Create release
- |
release-cli create --name "$CI_COMMIT_TAG" --tag-name $CI_COMMIT_TAG \
--assets-link "{\"name\":\"Tarball for ${CI_COMMIT_TAG}\",\"url\":\"${RELEASE_TARBALL_URL}\", \"filepath\": \"/tarball/${RELEASE_TARBALL}\"}" \
--assets-link "{\"name\":\"Checksum for ${CI_COMMIT_TAG}\",\"url\":\"${RELEASE_TARBALL_SHA_URL}\", \"filepath\": \"/tarball/${RELEASE_TARBALL_SHA}\"}" \
--description release_notes.md

View File

@ -0,0 +1,17 @@
{
"name": "cargo-nextest",
"buildsystem": "simple",
"sources": [
{
"type": "archive",
"url": "https://github.com/nextest-rs/nextest/releases/download/cargo-nextest-0.9.100/cargo-nextest-0.9.100-x86_64-unknown-linux-gnu.tar.gz",
"sha256": "de8843f9d4cd72ba7ff3995679536b8a5638ebc8f94848cb988c7549d9dc4e7d",
"dest": "cargo-nextest",
"strip-components": 0
}
],
"build-commands": [
"mkdir /app/bin",
"mv cargo-nextest/cargo-nextest /app/bin/"
]
}

5
.gitlab-ci/nextest.toml Normal file
View File

@ -0,0 +1,5 @@
[profile.default]
fail-fast = false
[profile.default.junit]
path = "junit.xml"

View File

@ -1,82 +0,0 @@
{
"app-id": "org.gnome.Fractal",
"runtime": "org.gnome.Platform",
"runtime-version": "46",
"sdk": "org.gnome.Sdk",
"sdk-extensions": [
"org.freedesktop.Sdk.Extension.rust-stable",
"org.freedesktop.Sdk.Extension.llvm16"
],
"command": "fractal",
"finish-args": [
"--share=network",
"--share=ipc",
"--socket=fallback-x11",
"--socket=wayland",
"--socket=pulseaudio",
"--device=dri",
"--env=RUST_LOG=fractal=info,warn"
],
"build-options": {
"append-ld-library-path": "/usr/lib/sdk/llvm16/lib",
"append-path": "/usr/lib/sdk/llvm16/bin:/usr/lib/sdk/rust-stable/bin"
},
"modules": [
{
"name" : "protobuf",
"buildsystem" : "autotools",
"config-opts": [ "DIST_LANG=cpp" ],
"cleanup" : [
"/bin/protoc*",
"/lib/libprotoc*",
"/lib/libprotobuf-lite*"
],
"sources" : [
{
"type" : "archive",
"url" : "https://github.com/protocolbuffers/protobuf/releases/download/v3.17.3/protobuf-all-3.17.3.tar.gz",
"sha256" : "77ad26d3f65222fd96ccc18b055632b0bfedf295cb748b712a98ba1ac0b704b2"
}
]
},
{
"name" : "protobuf-c",
"buildsystem" : "autotools",
"sources" : [
{
"type" : "archive",
"url" : "https://github.com/protobuf-c/protobuf-c/releases/download/v1.4.0/protobuf-c-1.4.0.tar.gz",
"sha256" : "26d98ee9bf18a6eba0d3f855ddec31dbe857667d269bc0b6017335572f85bbcb"
}
]
},
{
"name": "libshumate",
"buildsystem": "meson",
"config-opts": [
"-Dgir=false",
"-Dvapi=false",
"-Dgtk_doc=false",
"-Dvector_renderer=true"
],
"sources": [
{
"type": "archive",
"url": "https://download.gnome.org/sources/libshumate/1.2/libshumate-1.2.0.tar.xz",
"sha256": "4f8413a707cd00f84cee39ca49f58c48fc436f008ea80d6532ac37dafd0ba96b"
}
]
},
{
"name": "fractal",
"buildsystem": "meson",
"sources": [
{
"type": "archive",
"path": "%%TARBALL_PATH%%",
"sha256": "%%TARBALL_SHA%%"
}
]
}
]
}

View File

@ -1,28 +0,0 @@
# Build and publish the docs
pages:
stage: deploy
image: 'quay.io/gnome_infrastructure/gnome-runtime-images:gnome-master'
tags:
- flatpak
script:
- flatpak install --user --noninteractive org.freedesktop.Sdk.Extension.rust-nightly//23.08
# We want to use rust-nightly to build the app, but mold is in rust-stable
- sed -i 's|"org.freedesktop.Sdk.Extension.rust-stable"|"org.freedesktop.Sdk.Extension.rust-stable","org.freedesktop.Sdk.Extension.rust-nightly"|g' ${MANIFEST_PATH}
- sed -i 's|:/usr/lib/sdk/rust-stable/bin|:/usr/lib/sdk/rust-nightly/bin|g' ${MANIFEST_PATH}
- flatpak-builder --keep-build-dirs --user --disable-rofiles-fuse --stop-at=${FLATPAK_MODULE} flatpak_app --repo=repo ${BRANCH:+--default-branch=$BRANCH} ${MANIFEST_PATH}
- echo "ninja src/doc" | flatpak-builder --disable-rofiles-fuse --build-shell=${FLATPAK_MODULE} flatpak_app ${MANIFEST_PATH}
- mv .flatpak-builder/build/${FLATPAK_MODULE}/_flatpak_build/src/doc public
- chmod -R a=rwx public
dependencies: []
artifacts:
paths:
- 'public'
rules:
- changes:
- src/**/*
- Cargo.lock
- Cargo.toml
when: always
- when: manual
allow_failure: true

View File

@ -1,6 +1,8 @@
# Publish the nightly (Devel) version
include: 'https://gitlab.gnome.org/GNOME/citemplates/-/raw/master/flatpak/flatpak_ci_initiative.yml'
include:
- project: "GNOME/citemplates"
file: "flatpak/flatpak_ci_initiative.yml"
publish_nightly@x86_64:
extends: .publish_nightly

View File

@ -1,18 +1,24 @@
# Configure and run code checks
include: '.gitlab-ci/utils.yml'
# Custom checks and lints
checks:
stage: check
image: "rustlang/rust:nightly-slim"
interruptible: true
script:
- scripts/checks.sh --verbose --force-install
- hooks/checks.sh --verbose --force-install
# Lint the code
cargo-clippy:
extends:
- .remove_build_only_modules
stage: check
image: 'quay.io/gnome_infrastructure/gnome-runtime-images:gnome-master'
tags:
- flatpak
interruptible: true
script:
- flatpak-builder --keep-build-dirs --user --disable-rofiles-fuse --stop-at=${FLATPAK_MODULE} flatpak_app --repo=repo ${BRANCH:+--default-branch=$BRANCH} ${MANIFEST_PATH}
- echo "cargo clippy -- -D warnings" | flatpak-builder --disable-rofiles-fuse --build-shell=${FLATPAK_MODULE} flatpak_app ${MANIFEST_PATH}

View File

@ -1,16 +1,69 @@
# Tests after the app is built.
include: '.gitlab-ci/utils.yml'
# Validate the metainfo with Flathub's tool.
metainfo:
lint-metainfo:
stage: test
image:
name: "ghcr.io/flathub/flatpak-builder-lint:latest"
entrypoint: [""]
variables:
METAINFO: ".flatpak-builder/build/${FLATPAK_MODULE}/_flatpak_build/data/${APP_ID}.metainfo.xml"
METAINFO: "${APP_ID}.metainfo.xml"
interruptible: true
script:
# This tool has extra tests on top of appstreamcli and is required to pass for Flathub.
- flatpak-builder-lint appstream ${METAINFO}
# Test also with the pedantic and strict flags.
- appstreamcli validate --pedantic --explain --strict ${METAINFO}
needs: ["build@x86_64"]
# Run the Rust tests.
rust-tests:
extends:
- .remove_build_only_modules
stage: test
image: 'quay.io/gnome_infrastructure/gnome-runtime-images:gnome-master'
tags:
- flatpak
interruptible: true
script:
# Create a temporary file.
- TMP_FILE=$(mktemp)
# Add a module for nextest to the Flatpak manifest and write it to the temporary file.
- jq --slurpfile nextest .gitlab-ci/nextest.module.json '.modules = [$nextest[], .modules[]]' ${MANIFEST_PATH} > ${TMP_FILE}
# Replace the manifest with the temporary file.
- mv $TMP_FILE ${MANIFEST_PATH}
# Initialize the Flatpak sandbox.
- flatpak-builder --keep-build-dirs --user --disable-rofiles-fuse --stop-at=${FLATPAK_MODULE} flatpak_app --repo=repo ${BRANCH:+--default-branch=$BRANCH} ${MANIFEST_PATH}
# Run the tests.
- echo "cargo-nextest nextest run --config-file ../.gitlab-ci/nextest.toml" | flatpak-builder --disable-rofiles-fuse --build-shell=${FLATPAK_MODULE} flatpak_app ${MANIFEST_PATH}
dependencies: []
artifacts:
reports:
junit: '.flatpak-builder/build/${FLATPAK_MODULE}/target/nextest/default/junit.xml'
# Test that there are no errors in the docs.
build-docs:
extends:
- .remove_build_only_modules
- .stable_runtime
stage: test
tags:
- flatpak
interruptible: true
before_script:
- !reference [.remove_build_only_modules, before_script]
- !reference [.stable_runtime, before_script]
script:
- flatpak install --user --noninteractive org.freedesktop.Sdk.Extension.rust-nightly//${FREEDESKTOP_RUNTIME_BRANCH}
# We want to use the nightly toolchain inside the build terminal.
- sed -i 's|"org.freedesktop.Sdk.Extension.rust-stable"|"org.freedesktop.Sdk.Extension.rust-nightly"|g' ${MANIFEST_PATH}
- sed -i 's|/rust-stable/bin|/rust-nightly/extra/sdk/rust-nightly/bin|g' ${MANIFEST_PATH}
- flatpak-builder --keep-build-dirs --user --disable-rofiles-fuse --stop-at=${FLATPAK_MODULE} flatpak_app --repo=repo ${BRANCH:+--default-branch=$BRANCH} ${MANIFEST_PATH}
- echo "ninja src/doc" | flatpak-builder --disable-rofiles-fuse --build-shell=${FLATPAK_MODULE} flatpak_app ${MANIFEST_PATH}
- tar --auto-compress --create --file "${CI_PROJECT_DIR}/${CI_PROJECT_NAME}-docs.tar.gz" --directory ".flatpak-builder/build/${FLATPAK_MODULE}/_flatpak_build/src/doc" .
dependencies: []
artifacts:
paths:
- ${CI_PROJECT_NAME}-docs.tar.gz

34
.gitlab-ci/utils.yml Normal file
View File

@ -0,0 +1,34 @@
# Utilities to include in other jobs.
# Remove the Flatpak modules that are only necessary when building the app with meson.
.remove_build_only_modules:
variables:
# JSON array of the names of the Flatpak modules to remove.
MODULES_TO_REMOVE: '["grass", "glycin-loaders"]'
before_script:
# Create a temporary file.
- TMP_FILE=$(mktemp)
# Remove the modules in the manifest and write the output to the temporary file.
- jq --argjson modules_to_remove "${MODULES_TO_REMOVE}" 'del(.modules[] | select(IN(.name; $modules_to_remove | .[])))' ${MANIFEST_PATH} > $TMP_FILE
# Replace the manifest with the temporary file.
- mv $TMP_FILE ${MANIFEST_PATH}
# Use meson's build-env profile.
- sed -i "s|-Dprofile=development|-Dprofile=build-env|g" ${MANIFEST_PATH}
# Update the Flatpak manifest to use the latest stable GNOME runtime and use the corresponding
# container image.
#
# To get a list of available GNOME and LLVM versions, see:
# https://gitlab.gnome.org/GNOME/gnome-runtime-images/-/blob/master/.gitlab-ci.yml
.stable_runtime:
image: 'quay.io/gnome_infrastructure/gnome-runtime-images:gnome-${GNOME_STABLE_VERSION}'
variables:
GNOME_STABLE_VERSION: "48"
FREEDESKTOP_RUNTIME_BRANCH: "24.08"
LLVM_NIGHTLY_VERSION: "20"
LLVM_STABLE_VERSION: "20"
before_script:
# We want to use the latest stable GNOME runtime instead of the nightly runtime.
- sed -i "s|master|${GNOME_STABLE_VERSION}|g" ${MANIFEST_PATH}
# We want to use the latest LLVM extension for the stable runtime.
- sed -i "s|llvm${LLVM_NIGHTLY_VERSION}|llvm${LLVM_STABLE_VERSION}|g" ${MANIFEST_PATH}

View File

@ -12,14 +12,15 @@ or videos showing the issue.
## Information
* [ ] This bug is reproducible from the latest nightly build <!-- Check this box if the bug happens on Fractal's development version -->
* [ ] This bug is reproducible with an [officially supported flatpak](https://gitlab.gnome.org/World/fractal#installation-instructions)
<!-- ⚠️ Issue with third party packages (distribution repository, AUR, snap, Fedora flatpak…) should be reported to your distributor -->
* **Fractal Version**: <!-- The version of Fractal you were using when the bug occurred. Check the "About Fractal" dialog for this information -->
* **OS Version**: <!-- Operating system version, e.g. Fedora 36 -->
* **Installation Source**: <!-- Where you installed Fractal from, e.g. Flathub, GNOME Apps Nightly, AUR, or distro repositories -->
* **Homeserver**: <!-- The homeserver for your matrix account, e.g. matrix.org, gnome.org, … You can mention several of them if this is reproducible on multiple ones. -->
<!-- If you have error logs or a crash report, use the "Attach A File" button in the issue editor to attach it, or paste it in a code block below.
To access the logs, you can run `journalctl -e -o cat _COMM=fractal`
To access the logs, you can run `SYSTEMD_LESS=FRXMK journalctl -e -o cat _COMM=fractal`
To generate a stack trace in case of a crash, you can follow this guide: https://handbook.gnome.org/issues/stack-traces.html
@ -30,3 +31,5 @@ code goes here
```
-->
/label ~"1. Bug"

View File

@ -1,7 +1,10 @@
<!-- Please note that some features missing in the stable release are already available in the
development version. To avoid duplicates and unnecessary issues, please check that your request is
for something that is not yet implemented, and doesnt have an existing issue that is open or that
was closed as out of scope. -->
was closed as out of scope.
We also recommend talking to us in the #fractal:gnome.org Matrix room first. We do not intend to
implement everything and dont want our issue tracker to become a giant wishlist, but rather a
curated list of known problems and planned features. -->
Detailed description of the feature. Provide as much information as you can.

View File

@ -1,6 +1,8 @@
[default.extend-words]
gir = "gir"
inout = "inout"
numer = "numer" # Short for numerator in GStreamer
ue = "ue" # End of word after mnemonic
[type.po]
extend-glob = ["*.po"]

View File

@ -22,7 +22,7 @@ can also provide general help about using Rust in GNOME.
### Prerequisites
Fractal is written in Rust, so you will need to have at least Rust 1.76 and Cargo available on your
Fractal is written in Rust, so you will need to have at least Rust 1.80 and Cargo available on your
system. You will also need to install the Rust nightly toolchain to be able to run our
[pre-commit hook](#pre-commit), which can be done with:
@ -35,21 +35,21 @@ manually add the necessary remotes and install the required freedesktop.org exte
```sh
# Add Flathub and the gnome-nightly repo
flatpak remote-add --user --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
flatpak remote-add --user --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
flatpak remote-add --user --if-not-exists gnome-nightly https://nightly.gnome.org/gnome-nightly.flatpakrepo
# Install the gnome-nightly Sdk and Platform runtime
flatpak install --user gnome-nightly org.gnome.Sdk//master org.gnome.Platform//master
# Install the required rust-stable extension from Flathub
flatpak install --user flathub org.freedesktop.Sdk.Extension.rust-stable//23.08
flatpak install --user flathub org.freedesktop.Sdk.Extension.rust-stable//25.08beta
# Install the required llvm extension from Flathub
flatpak install --user flathub org.freedesktop.Sdk.Extension.llvm16//23.08
flatpak install --user flathub org.freedesktop.Sdk.Extension.llvm20//25.08beta
```
If you are building the flatpak manually you will also need flatpak-builder on your system, or the
`org.flatpak.Builder` flatpak.
`org.flatpak.Builder` flatpak from Flathub.
### GNOME Builder
@ -66,42 +66,29 @@ environment from the command line and execute commands in that environment.
First, install fenv:
```sh
# Clone the project somewhere on your system
git clone https://gitlab.gnome.org/ZanderBrown/fenv.git
# Move into the folder
cd fenv
# Install fenv with Cargo
cargo install --path .
cargo install --git https://gitlab.gnome.org/ZanderBrown/fenv fenv
```
You can now discard the `fenv` directory if you want.
After that, move into the directory where you cloned Fractal and setup the project:
After that, setup the project:
```sh
# Setup the flatpak environment
# Set up the flatpak environment
fenv gen build-aux/org.gnome.Fractal.Devel.json
# Initialize the build system
fenv exec -- meson setup -Dprofile=development --prefix=/app _build
```
Finally, build and run the application:
```sh
# Build the project
fenv exec -- ninja -C _build
# Install the application in the flatpak environment
fenv exec -- ninja -C _build install
fenv build
# Launch Fractal
fenv exec ./_build/src/fractal
fenv run
```
To test changes you make to the code, re-run these three last commands.
_Note that fenv will use `_build` as build directory._
To test changes you make to the code, re-run these two last commands.
### Install the flatpak
@ -113,7 +100,7 @@ GNOME Builder can export a flatpak of the app after it has been successfully bui
Fractal can then be installed with:
```sh
flatpak install --user --bundle path/to/org.gnome.Fractal.Devel.flatpak
flatpak install --user --bundle path/to/org.gnome.Fractal.Devel.flatpak
```
Alternatively, it can be built and installed with flatpak-builder:
@ -144,7 +131,7 @@ sudo ninja -C _build install
## Pre-commit
We expect all code contributions to be correctly formatted. To help with that, a pre-commit hook
should get installed as part of the building process. It runs the `scripts/checks.sh` script. It's a
should get installed as part of the building process. It runs the `hooks/checks.sh` script. It's a
quick script that makes sure that the code is correctly formatted with `rustfmt`, among other
things. Make sure that this script is effectively run before submitting your merge request,
otherwise CI will probably fail right away.
@ -156,7 +143,7 @@ submissions and is once again checked by our CI.
Please follow the [GNOME commit message guidelines](https://handbook.gnome.org/development/commit-messages.html).
We enforce the use of a tag as a prefix for the summary line. It should be the area of the app that
is changed.
is changed.
## Merge Request

4714
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,11 +1,14 @@
[package]
name = "fractal"
version = "7.0.0-beta"
version = "12.0.0"
authors = ["Julian Sparber <julian@sparber.net>"]
edition = "2021"
rust-version = "1.76"
edition = "2024"
rust-version = "1.85"
publish = false
[package.metadata.cargo-machete]
ignored = ["serde_bytes"] # Used by the SecretFile API.
[profile.release]
debug = true
lto = "thin"
@ -21,91 +24,110 @@ codegen-units = 16
# Please keep dependencies sorted.
[dependencies]
blurhash = "0.2"
cfg-if = "1"
diff = "0.1"
djb_hash = "0.1"
eyeball-im = "0.4"
futures-channel = "0.3"
futures-util = "0.3"
geo-uri = "0.2"
gettext-rs = { version = "0.7", features = ["gettext-system"] }
html-escape = "0.2"
html2pango = "0.6"
html5gum = "0.5"
image = "0.24"
indexmap = "2"
linkify = "0.10.0"
mime = "0.3"
mime_guess = "2"
once_cell = "1"
pulldown-cmark = "0.10"
qrcode = "0.13"
rand = "0.8"
numeric-sort = "0.1"
pulldown-cmark = "0.13"
qrcode = { version = "0.14", default-features = false }
rand = "0.9"
regex = "1"
rmp-serde = "1"
rqrr = "0.6"
secular = { version = "1", features = ["bmp", "normalization"] }
serde = "1"
serde_bytes = "0.11"
serde_json = "1"
strum = { version = "0.26", features = ["derive"] }
thiserror = "1"
strum = { version = "0.27.1", features = ["derive"] }
tempfile = "3"
thiserror = "2"
tld = "2"
tokio = { version = "1", features = ["rt", "rt-multi-thread", "sync"] }
tokio-stream = { version = "0.1", features = ["sync"] }
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
url = "2"
webp = { version = "0.3", default-features = false }
wtinylfu = "0.2"
zeroize = "1"
# gtk-rs project and dependents. These usually need to be updated together.
adw = { package = "libadwaita", version = "0.6", features = ["v1_5"] }
gst = { version = "0.22", package = "gstreamer" }
gst_base = { version = "0.22", package = "gstreamer-base" }
gst_gtk = { version = "0.12", package = "gst-plugin-gtk4" }
gst_pbutils = { version = "0.22", package = "gstreamer-pbutils" }
gst_play = { version = "0.22", package = "gstreamer-play" }
gst_video = { version = "0.22", package = "gstreamer-video" }
gtk = { package = "gtk4", version = "0.8", features = ["gnome_45"] }
shumate = { package = "libshumate", version = "0.5" }
sourceview = { package = "sourceview5", version = "0.8" }
adw = { package = "libadwaita", version = "0.7", features = ["v1_7"] }
glycin = { version = "3.0.0-beta.1", default-features = false, features = ["tokio", "gdk4"] }
gst = { version = "0.23", package = "gstreamer" }
gst_app = { version = "0.23", package = "gstreamer-app" }
gst_pbutils = { version = "0.23", package = "gstreamer-pbutils" }
gst_play = { version = "0.23", package = "gstreamer-play" }
gst_video = { version = "0.23", package = "gstreamer-video" }
gtk = { package = "gtk4", version = "0.9", features = ["gnome_47"] }
shumate = { package = "libshumate", version = "0.6" }
sourceview = { package = "sourceview5", version = "0.9" }
[dependencies.matrix-sdk]
# version = "0.13"
git = "https://github.com/matrix-org/matrix-rust-sdk.git"
rev = "ab9e4f73b1b43e0779080b714e0916496a052cc3"
features = [
"socks",
"sso-login",
"markdown",
"qrcode",
"image-rayon",
]
rev = "a9ce1c6e5822b8eb8411c5bc257049d9a9d15884"
features = ["socks", "sso-login", "markdown", "qrcode"]
[dependencies.matrix-sdk-store-encryption]
# version = "0.13"
git = "https://github.com/matrix-org/matrix-rust-sdk.git"
rev = "a9ce1c6e5822b8eb8411c5bc257049d9a9d15884"
[dependencies.matrix-sdk-ui]
# version = "0.13"
git = "https://github.com/matrix-org/matrix-rust-sdk.git"
rev = "ab9e4f73b1b43e0779080b714e0916496a052cc3"
default-features = false
features = ["e2e-encryption", "native-tls"]
rev = "a9ce1c6e5822b8eb8411c5bc257049d9a9d15884"
[dependencies.ruma]
# version = "0.9.4"
# version = "0.12.5"
git = "https://github.com/ruma/ruma.git"
rev = "4c00bd010dbdca6005bd599b52e90a0b7015d056"
rev = "a2fe858133ba932b4bda730dc7472c9c985739a0"
features = [
"unstable-unspecified",
"client-api-c",
"compat-key-id",
"compat-user-id",
"markdown",
"html-matrix",
"compat-arbitrary-length-ids",
"compat-server-signing-key-version",
"compat-empty-string-null",
"compat-null",
"compat-optional",
"compat-unset-avatar",
"compat-get-3pids",
"html",
"compat-lax-room-create-deser",
"compat-lax-room-topic-deser",
]
# Linux-only dependencies.
[target.'cfg(target_os = "linux")'.dependencies]
ashpd = { version = "0.8", default-features = false, features = [
"pipewire",
aperture = "0.9"
ashpd = { version = "0.11", default-features = false, features = [
"tracing",
"tokio",
] }
oo7 = { version = "0.3", default-features = false, features = [
oo7 = { version = "0.4", default-features = false, features = [
"openssl_crypto",
"tokio",
"tracing",
] }
[dev-dependencies]
assert_matches2 = "0.1"
[lints.clippy]
pedantic = { level = "warn", priority = -1 }
cast_possible_truncation = "allow"
cast_precision_loss = "allow"
default_trait_access = "allow"
module_name_repetitions = "allow"
new_without_default = "allow"
struct_field_names = "allow"
unsafe_derive_deserialize = "allow"
wildcard_imports = "allow"

View File

@ -8,7 +8,12 @@
Fractal is a Matrix messaging app for GNOME written in Rust. Its interface is optimized for
collaboration in large groups, such as free software projects, and will fit all screens, big or small.
![screenshot](https://gitlab.gnome.org/World/fractal/raw/main/screenshots/main.png)
<img
src="https://gitlab.gnome.org/World/fractal/raw/main/screenshots/main.png"
alt="Fractals main window"
width="882"
height="672"
/>
Highlights:
@ -33,7 +38,7 @@ development version while keeping the stable release around for daily use.
### Stable version
The current stable version is 6 (released January 18th 2024).
The current stable version is 12 (released August 11th 2025).
You can get the official Fractal Flatpak from Flathub.
@ -48,7 +53,7 @@ You can get the official Fractal Flatpak from Flathub.
### Beta version
The current beta version is 6, same as the stable version (released January 18th 2024).
The current beta version is 12 (same as stable).
It is available as a Flatpak on Flathub Beta.
@ -140,6 +145,24 @@ flatpak install --user gnome-nightly org.gnome.Fractal.Devel
### Runtime Dependencies
On top of the dependencies required at build time and checked by Meson, Fractal depends on the
following dependencies at runtime:
* xdg-desktop-portal and its backends: some functionalities are dependant on the following portals,
and a permission will be asked when necessary, but Fractal should work without them:
* Secret: this portal or a Secret Service is required, see [storing secrets](#storing-secrets).
* Camera: scan QR codes during verification.
* Location: send the users location in a conversation.
* Settings: get the 12h/24h time format system preference.
* GStreamer plugins:
* gst-plugin-gtk4 (gstgtk4): required to preview videos in the timeline and to present the output
of the camera.
* libgstpipewire with the `pipewiredeviceprovider`: used to list and access the cameras.
* glycin: all images are loaded with this library so loaders for the different image formats need to
be installed.
#### Storing secrets
Fractal doesnt store your **password**, but it stores your **access token** and the **passphrase**
used to encrypt the database and the local cache.
@ -147,12 +170,12 @@ The Fractal Flatpaks use the [Secret **Portal**](https://docs.flatpak.org/en/lat
to store those secrets. If you are using GNOME this should just work. If you are using a different
desktop environment or are facing issues, make sure `xdg-desktop-portal` is installed along with a
service that provides the [Secret portal backend interface](https://docs.flatpak.org/en/latest/portal-api-reference.html#gdbus-org.freedesktop.impl.portal.Secret),
which is currently only implemented by gnome-keyring.
like gnome-keyring or KWallet (since version 6.2).
Any version that is not sandboxed relies on software that implements the [Secret **Service** API](https://www.freedesktop.org/wiki/Specifications/secret-storage-spec/)
to store those secrets. Therefore, you need to have software providing that service on your system,
like gnome-keyring, KeepassXC ([setup guide](https://avaldes.co/2020/01/28/secret-service-keepassxc.html)),
or KWallet (since version 5.97). Once again, if you are using GNOME this should just work.
or KWallet. Once again, if you are using GNOME this should just work.
If you prefer to use software that only implements the Secret Service API while using the Flatpaks,
you need to make sure that no service implementing the Secret portal backend interface is running,

115
RELEASING.md Normal file
View File

@ -0,0 +1,115 @@
# Releasing Fractal
## Before making a new release
- Update the dependencies (crates or system libraries) and migrate from deprecated APIs.
- Make the `build-stable` CI jobs use the latest stable GNOME runtime.
## Making a new stable release
1. If this is a new major version, create a new `fractal-M` branch, where `M` is the major version
number.
2. Create a [release merge request](#release-merge-request-content) against the major version
branch.
3. After the MR is merged, [create a tag](#creating-a-signed-tag) on the last commit of the major
version branch.
4. Create a release on GitLab for that tag.
5. Make a fast-forward merge of the major version branch to `main`.
6. [Publish the new version on Flathub and Flathub beta](#publishing-a-version-on-flathub).
7. [Get the stable branch added to Damned Lies](#getting-a-branch-added-to-damned-lies).
## Making a new beta release
1. Create a [release merge request](#release-merge-request-content) against `main`.
2. After the MR is merged, [create a tag](#creating-a-signed-tag) on the last commit of `main`.
3. Create a release on GitLab for that tag.
4. [Publish the new version on Flathub beta](#publishing-a-version-on-flathub).
## Release merge request content
_To represent conditional list items, this section will start items with "**stable.**" to mean "if
this is a stable release"._
Make a single release commit containing the following changes:
- Update `/meson.build`:
- Change the version on L3, it must look the same as it would in the app, with a
`major_version.pre_release_version` format.
- Change the `major_version` and `pre_release_version` on L13-14. For stable versions,
`pre_release_version` should be an empty string.
- Update `/Cargo.toml`: change the `version`, using a semver format.
- Update `/README.md`:
- **stable.** update the current stable version and its release date.
- Update the current beta version. For stable versions, put `(same as stable)` instead of the
release date.
- Update `/data/org.gnome.Fractal.metainfo.xml.in.in`:
- Add a new `release` entry at the top of the `releases`:
- Its `version` should use the `major_version~pre_release_version` format.
- For stable versions, its `type` should be `stable`, otherwise it should be `development`.
- **stable.** remove all the `development` entries.
- **stable.** update the paths of the screenshots to point to the major version branch.
- **stable.** If there were visible changes in the UI, update the screenshots in `/screenshots`.
They should follow [Flathub's quality guidelines](https://docs.flathub.org/docs/for-app-authors/metainfo-guidelines/quality-guidelines#screenshots),
with the following window sizes:
- `main.png`: 760×550.
- `adaptive.png`: 360×600.
- `media-history.png`: 500×540.
A good practice in this merge request is to launch the `build-stable` CI jobs to make sure that
Fractal builds with the stable Flatpak runtime.
## Creating a signed tag
Creating a signed tag is not mandatory but is good practice. To do so, use this command:
```sh
git tag -s V
```
With `V` being the version to tag, in the format `major_version.pre_release_version`.
You will be prompted for a tag message. This message doesn't really matter so something like
`Release Fractal V` should suffice.
## Publishing a version on Flathub
Publishing a version of Fractal on Flathub is done via its [Flathub repository on GitHub](https://github.com/flathub/org.gnome.Fractal/).
A permission from the Flathub team granted to your GitHub account is necessary to merge PRs on this
repository, but anyone can open a PR.
1. Open a PR against the correct branch. For a stable build, work against the `master` branch, for a
beta build, work against the `beta` branch.
It must contain a commit that updates the manifest to:
- Use the latest GNOME runtime.
- Make sure that the Flatpak dependencies are the same as in the nightly manifest, and using the
same version.
- Build the latest version of Fractal, identified by its tag _and_ commit hash.
If the list of Rust modules to build changes, the `MODULES` variable in the
`update-cargo-sources.sh` script must also be updated.
2. When the PR is opened, a CI job will update the `*-cargo-sources.json` files with the latest
dependencies for the Rust modules and add a commit to the PR if necessary.
3. Trigger a test build by posting a comment saying `bot, build`.
If the build succeeds, test the generated Flatpak as instructed and watch for obvious errors. If
there are no issues, merge the PR.
4. Merging the PR will trigger an "official" build that will then be published on Flathub or Flathub
beta within 1 to 2 hours. If this build fails, an issue will be opened on the GitHub repository.
The Flathub admins need to be contacted to launch it again.
More details about these steps can be found in the Flathub docs about [maintenance](https://docs.flathub.org/docs/for-app-authors/maintenance)
and [updates](https://docs.flathub.org/docs/for-app-authors/updates).
## Getting a branch added to Damned Lies
Damned Lies is the GNOME translation management platform. It provides translation workflows, but
also statistics. Even though we dont publish any release from stable branches after the initial
one, we add them there so we can keep track of the evolution of translation coverage.
1. Go to https://l10n.gnome.org/module/fractal/ and log in.
2. Click on the pencil icon next to the branch list.
3. In the entry at the bottom, type in the name of the new branch, then click on the Save button.
4. Assign the newly added branch to the “Other Apps (stable)” Release, unassign the previous one.
5. Hit Save again for the assignments to take effect.

View File

@ -1,9 +0,0 @@
#!/bin/bash
export DIST="$1"
export SOURCE_ROOT="$2"
cd "$SOURCE_ROOT"
mkdir "$DIST"/.cargo
cargo vendor | sed 's/^directory = ".*"/directory = "vendor"/g' >> $DIST/.cargo/config.toml
# Move vendor into dist tarball directory
mv vendor "$DIST"

View File

@ -1,11 +1,11 @@
{
"app-id": "org.gnome.Fractal.Devel",
"id": "org.gnome.Fractal.Devel",
"runtime": "org.gnome.Platform",
"runtime-version": "master",
"sdk": "org.gnome.Sdk",
"sdk-extensions": [
"org.freedesktop.Sdk.Extension.rust-stable",
"org.freedesktop.Sdk.Extension.llvm16"
"org.freedesktop.Sdk.Extension.llvm20"
],
"command": "fractal",
"finish-args": [
@ -20,9 +20,10 @@
"--env=RUST_BACKTRACE=1"
],
"build-options": {
"append-ld-library-path": "/usr/lib/sdk/llvm16/lib",
"append-path": "/usr/lib/sdk/llvm16/bin:/usr/lib/sdk/rust-stable/bin",
"append-ld-library-path": "/usr/lib/sdk/llvm20/lib",
"append-path": "/usr/lib/sdk/llvm20/bin:/usr/lib/sdk/rust-stable/bin",
"env": {
"RUSTFLAGS": "-C force-frame-pointers=yes",
"CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER": "clang",
"CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUSTFLAGS": "-C link-arg=-fuse-ld=/usr/lib/sdk/rust-stable/bin/mold --cfg=ruma_identifiers_storage=\"Arc\"",
"CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER": "clang",
@ -38,30 +39,41 @@
},
"modules": [
{
"name" : "protobuf",
"buildsystem" : "autotools",
"config-opts": [ "DIST_LANG=cpp" ],
"cleanup" : [
"/bin/protoc*",
"/lib/libprotoc*",
"/lib/libprotobuf-lite*"
"name": "grass",
"buildsystem": "simple",
"build-options": {
"env": {
"CARGO_HOME": "/run/build/grass/cargo"
}
},
"build-commands": [
"cargo build --release --locked",
"mkdir -p /app/bin",
"install -D ./target/release/grass /app/bin/"
],
"sources" : [
"cleanup": ["*"],
"sources": [
{
"type" : "archive",
"url" : "https://github.com/protocolbuffers/protobuf/releases/download/v3.17.3/protobuf-all-3.17.3.tar.gz",
"sha256" : "77ad26d3f65222fd96ccc18b055632b0bfedf295cb748b712a98ba1ac0b704b2"
"type": "git",
"url": "https://github.com/connorskees/grass",
"tag": "0.13.4",
"commit": "e0bb9e2eabfc3a58e42b03089cd7b22c68d09d0b",
"disable-submodules": true
}
]
},
{
"name" : "protobuf-c",
"buildsystem" : "autotools",
"sources" : [
"name": "protobuf-c",
"buildsystem": "autotools",
"config-opts": [
"--disable-protoc"
],
"sources": [
{
"type" : "archive",
"url" : "https://github.com/protobuf-c/protobuf-c/releases/download/v1.4.0/protobuf-c-1.4.0.tar.gz",
"sha256" : "26d98ee9bf18a6eba0d3f855ddec31dbe857667d269bc0b6017335572f85bbcb"
"type": "git",
"url": "https://github.com/protobuf-c/protobuf-c.git",
"tag": "v1.5.2",
"commit": "4719fdd7760624388c2c5b9d6759eb6a47490626"
}
]
},
@ -76,9 +88,10 @@
],
"sources": [
{
"type": "archive",
"url": "https://download.gnome.org/sources/libshumate/1.2/libshumate-1.2.0.tar.xz",
"sha256": "4f8413a707cd00f84cee39ca49f58c48fc436f008ea80d6532ac37dafd0ba96b"
"type": "git",
"url": "https://gitlab.gnome.org/GNOME/libshumate.git",
"tag": "1.4.0",
"commit": "06021e35f0d479612fb1a3af91a73ba562175e03"
}
]
},

View File

@ -35,7 +35,7 @@ if profile == 'Devel'
appstream_version += '-' + devel_version
development_release = '''
<release version="@0@" type="development" date="@1@">
<release version="@0@" type="snapshot" date="@1@">
<description>
<p>Development release.</p>
</description>

View File

@ -22,8 +22,8 @@
</ul>
</description>
<branding>
<color type="primary" scheme_preference="light">#a5c8f2</color>
<color type="primary" scheme_preference="dark">#1b549b</color>
<color type="primary" scheme_preference="light">#bdfbff</color>
<color type="primary" scheme_preference="dark">#1a5fb4</color>
</branding>
<metadata_license>CC0-1.0</metadata_license>
<project_license>GPL-3.0+</project_license>
@ -35,15 +35,15 @@
<screenshots>
<screenshot type="default">
<image type="source">https://gitlab.gnome.org/World/fractal/raw/main/screenshots/main.png</image>
<image type="source">https://gitlab.gnome.org/World/fractal/raw/fractal-12/screenshots/main.png</image>
<caption>Fractals main window</caption>
</screenshot>
<screenshot>
<image type="source">https://gitlab.gnome.org/World/fractal/raw/main/screenshots/media-history.png</image>
<image type="source">https://gitlab.gnome.org/World/fractal/raw/fractal-12/screenshots/media-history.png</image>
<caption>View the media history of a Matrix room</caption>
</screenshot>
<screenshot>
<image type="source">https://gitlab.gnome.org/World/fractal/raw/main/screenshots/adaptive.png</image>
<image type="source">https://gitlab.gnome.org/World/fractal/raw/fractal-12/screenshots/adaptive.png</image>
<caption>Fractals interface adapts to small screens</caption>
</screenshot>
</screenshots>
@ -71,19 +71,275 @@
</content_rating>
<releases>@development-release@
<release version="7~beta" type="development" date="2024-03-28">
<release version="12" type="stable" date="2025-08-11">
<description>
<p>
Spring is here in Fractal land. Birds chirping, flowers blooming, and a new beta for you
to try!
</p>
<p>
Staffs picks:
Knock, knock, knock… on rooms, baby 🎵 Ooh ooh ooh ooh ooh ooh 🎶 That's right, Fractal 12
adds support for knocking, among other things. Read all about the improvements since 11.2:
</p>
<ul>
<li>
Encryption support has been extended, with server-side key backup and account recovery.
Requesting invites to rooms (aka knocking) is now possible, as is enabling such requests
for room admins.
</li>
<li>
The upcoming room version 12 is supported, with the special power level of room
creators.
</li>
<li>
A room can be marked as unread via the context menu in the sidebar.
</li>
<li>
You can now see if a section in the sidebar has any notifications or activity when it is
collapsed.
</li>
<li>
Clicking on the name of the sender of a message adds a mention to them in the composer.
</li>
<li>
The safety setting to hide media previews in rooms is now synced between Matrix clients
and we added another safety setting (which is also synced) to hide avatars in invites.
</li>
</ul>
<p>
As usual, this release includes other improvements, fixes and new translations thanks to
all our contributors, and our upstream projects.
</p>
<p>
We want to address special thanks to the translators who worked on this version. We know
this is a huge undertaking and have a deep appreciation for what youve done. If you want
to help with this effort, head over to Damned Lies.
</p>
</description>
</release>
<release version="11.2" type="stable" date="2025-06-10">
<description>
<p>
This version updates the matrix-sdk-crypto dependency to include a fix for a high severity
security issue.
</p>
</description>
</release>
<release version="11.1" type="stable" date="2025-05-15">
<description>
<p>
Due to a pesky bug that makes Fractal crash when our users attempt to start a
verification, we are releasing Fractal 11.1 only 2 weeks after Fractal 11. And while were
at it we also backported a few fixes for smaller paper cuts!
</p>
</description>
</release>
<release version="11" type="stable" date="2025-05-01">
<description>
<p>
A new version of Fractal numbered Eleven? Stranger things have happened… Features come
running up that hill:
</p>
<ul>
<li>
Support for login using the OAuth 2.0 API (as used by matrix.org, which recently made
the switch to Matrix Authentication Service)
</li>
<li>
Overhaul of the page that lists user sessions, with details moved to subpages, for a
less cluttered feel, and allowing to rename sessions!
</li>
<li>
Rearranged account settings, with a new Safety tab that includes a setting to toggle
media preview visibility
</li>
<li>
BlurHashes for images and videos, that are used as placeholders while the media is
loading or if the preview is disabled
</li>
<li>
Contiguous state events are grouped behind a single item
</li>
</ul>
<p>
As usual, this release includes other improvements and fixes thanks to all our
contributors, and our upstream projects.
</p>
<p>
We want to address special thanks to the translators who worked on this version. We know
this is a huge undertaking and have a deep appreciation for what youve done. If you want
to help with this effort, head over to l10n.gnome.org.
</p>
</description>
</release>
<release version="10.1" type="stable" date="2025-02-10">
<description>
<p>
Due to a couple of unfortunate but important regressions in Fractal 10, we are releasing
Fractal 10.1 so our users dont have to wait too long for them to be addressed. This minor
version fixes the following issues:
</p>
<ul>
<li>
Some rooms were stuck in an unread state, even after reading them or marking them as
read.
</li>
<li>
Joining or creating a room would crash the app.
</li>
</ul>
</description>
</release>
<release version="10" type="stable" date="2025-01-30">
<description>
<p>
How are you going to find your friends and coordinate end of day drinks when youre lost
in the middle of a large crowd in a big city? With the new version of your favorite Matrix
client, of course! Here is Fractal 10.
</p>
<ul>
<li>
The QR code scanning code has been ported to libaperture, the library behind GNOME
Camera. This should result in better performance and more reliability.
</li>
<li>
OAuth 2.0 compatibility was added, to make sure that we are ready for the upcoming
authentication changes for matrix.org.
</li>
<li>
Pills for users and rooms mentions show consistently in the right place instead of
seemingly random places, getting rid of one of our oldest and most annoying bug.
</li>
<li>
Attachments go through the send queue, ensuring correct order of all messages and
improving the visual feedback.
</li>
<li>
Videos were often not playing after loading in the room history. This was fixed, and we
also show properly when an error occurred.
</li>
<li>
We were downloading too many different sizes for avatar images, which would fill the
media cache needlessly. We now only download a couple of sizes. This has the extra
benefit of fixing blurry or missing thumbnails in notifications.
</li>
</ul>
<p>
As usual, this release includes other improvements and fixes thanks to all our
contributors, and our upstream projects.
</p>
<p>
We want to address special thanks to the translators who worked on this version. We know
this is a huge undertaking and have a deep appreciation for what youve done. If you want
to help with this effort, head over to l10n.gnome.org.
</p>
</description>
</release>
<release version="9" type="stable" date="2024-10-30">
<description>
<p>
Whats that behind you⁉ 😱 Oh, thats a new Fractal release❣ 😁 🎃
</p>
<ul>
<li>
We switched to the glycin library (the same one used by GNOME Image Viewer) to load
images, allowing us to fix several issues, like supporting more animated formats and
SVGs and respecting EXIF orientation.
</li>
<li>
The annoying bug where some rooms would stay as unread even after opening them is now a
distant memory.
</li>
<li>
The media cache uses its own database that you can delete if you want to free some space
on your system. It will also soon be able to clean up unused media files to prevent it
from growing indefinitely.
</li>
<li>
Sometimes the day separators would show up with the wrong date, not anymore!
</li>
<li>
We migrated to the new GTK 4.16 and libadwaita 1.6 APIs, including CSS variables,
AdwButtonRow and AdwSpinner.
</li>
<li>
We used to only rely on the secrets provider to tell us which Matrix accounts are
logged-in, which caused issues for people sharing their secrets between devices. Now we
also make sure that there is a data folder for a given session before trying to restore
it.
</li>
<li>
Our notifications are categorized as coming from an instant messenger, so graphical
shells that support it, such as Phosh, can play a sound for them.
</li>
<li>
Some room settings are hidden for direct chats, because it does not make sense to change
them in this type of room.
</li>
<li>
The size of the headerbar would change depending on whether the room has a topic or not.
This will not happen anymore.
</li>
</ul>
<p>
As usual, this release includes other improvements and fixes thanks to all our
contributors, and our upstream projects.
</p>
<p>
We want to address special thanks to the translators who worked on this version. We know
this is a huge undertaking and have a deep appreciation for what youve done. If you want
to help with this effort, head over to Damned Lies.
</p>
</description>
</release>
<release version="8" type="stable" date="2024-08-01">
<description>
<p>
Lets see the main improvements:
</p>
<ul>
<li>
Mentions are sent intentionally
</li>
<li>
Authenticated media are supported
</li>
<li>
Draft messages are kept per-room and persisted across restarts
</li>
<li>
More links are detected in messages and room descriptions
</li>
<li>
Collapsed categories in the sidebar are remembered between restarts, with the
“Historical” category collapsed by default
</li>
<li>
A banner appears when synchronization with the homeserver fails too many times in a row
</li>
<li>
The verification and account recovery processes have been polished
</li>
<li>
HTML rendering has been improved, with the support of new elements and attributes
</li>
</ul>
<p>
As usual, this release includes other improvements and fixes thanks to all our
contributors, and our upstream projects.
</p>
<p>
We want to address special thanks to the translators who worked on this version. We know
this is a huge undertaking and have a deep appreciation for what youve done. If you want
to help with this effort, head over to Damned Lies.
</p>
</description>
</release>
<release version="7" type="stable" date="2024-05-02">
<description>
<p>
Here comes Fractal 7, with extended encryption support and improved accessibility.
Server-side key backup and account recovery have been added, bringing greater security.
Third-party verification has received some bug fixes and improvements. Amongst the many
accessibility improvements, navigability has increased, especially in the room history.
But thats not all weve been up to in the past three months:
</p>
<ul>
<li>
Messages that failed to send can now be retried or discarded.
</li>
@ -92,7 +348,7 @@
</li>
<li>
Room details are now considered complete, with the addition of room address management,
permissions, and version upgrade.
permissions, and room upgrade.
</li>
<li>
A new member menu appears when clicking on an avatar in the room history. It offers a
@ -102,18 +358,15 @@
<li>
Pills are clickable and allow to directly go to a room or member profile.
</li>
<li>
Many more improvements on the accessibility front, for better navigability with a screen
reader.
</li>
</ul>
<p>
As usual, this release includes other improvements, fixes and new translations thanks to
all our contributors, and our upstream projects.
</p>
<p>
As the version implies, there might be a slight risk of regressions, but it should be
mostly stable. If all goes well the next step is the release candidate!
We want to address special thanks to the translators who worked on this version. We know
this is a huge undertaking and have a deep appreciation for what youve done. If you want
to help with this effort, head over to Damned Lies.
</p>
</description>
</release>

View File

@ -5,47 +5,15 @@
viewBox="0 0 89.958331 52.916668"
version="1.1"
id="svg8662"
sodipodi:docname="welcome-export.svg"
inkscape:version="1.1-rc (52f87abb86, 2021-05-02)"
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"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<sodipodi:namedview
id="namedview47"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
objecttolerance="10.0"
gridtolerance="10.0"
guidetolerance="10.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="0.99583586"
inkscape:cx="303.76492"
inkscape:cy="15.062723"
inkscape:current-layer="svg8662"
inkscape:object-paths="true"
inkscape:snap-intersection-paths="true"
inkscape:snap-midpoints="true"
inkscape:snap-smooth-nodes="true"
inkscape:snap-bbox="true"
inkscape:bbox-nodes="true"
inkscape:snap-text-baseline="true">
<inkscape:grid
type="xygrid"
id="grid1470" />
</sodipodi:namedview>
<defs
id="defs8656">
<linearGradient
inkscape:collect="always"
id="linearGradient39832">
<stop
style="stop-color:#3584e4;stop-opacity:1"
@ -57,7 +25,6 @@
id="stop39830" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient24559">
<stop
style="stop-color:#ed333b;stop-opacity:1;"
@ -69,7 +36,6 @@
id="stop24557" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient12858">
<stop
style="stop-color:#f66151;stop-opacity:1"
@ -103,7 +69,6 @@
id="stop8143" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient976"
id="radialGradient1221"
gradientUnits="userSpaceOnUse"
@ -113,7 +78,6 @@
fy="212"
r="60" />
<linearGradient
inkscape:collect="always"
id="linearGradient976">
<stop
style="stop-color:#f8e45c;stop-opacity:1"
@ -125,7 +89,6 @@
id="stop974" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient1117"
id="radialGradient1223"
gradientUnits="userSpaceOnUse"
@ -136,7 +99,6 @@
fy="224"
r="16" />
<linearGradient
inkscape:collect="always"
id="linearGradient1117">
<stop
style="stop-color:#5e5c64;stop-opacity:1"
@ -148,7 +110,6 @@
id="stop1115" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient1117"
id="radialGradient1225"
gradientUnits="userSpaceOnUse"
@ -159,7 +120,6 @@
fy="224"
r="16" />
<linearGradient
inkscape:collect="always"
id="linearGradient1325">
<stop
style="stop-color:#f66151;stop-opacity:1"
@ -175,7 +135,6 @@
id="stop1323" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient976"
id="radialGradient1393-0"
gradientUnits="userSpaceOnUse"
@ -186,7 +145,6 @@
r="60"
gradientTransform="matrix(0.26458333,0,0,0.26458333,10.972649,-67.464743)" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient1325"
id="radialGradient1395-6"
gradientUnits="userSpaceOnUse"
@ -197,7 +155,6 @@
fy="29.856375"
r="16.084499" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient1325"
id="radialGradient1397-9-9"
gradientUnits="userSpaceOnUse"
@ -208,7 +165,6 @@
fy="29.856375"
r="16.084499" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient12858"
id="linearGradient12860"
x1="3467.3748"
@ -217,7 +173,6 @@
y2="-383.00339"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient8145"
id="linearGradient15076"
gradientUnits="userSpaceOnUse"
@ -227,7 +182,6 @@
x2="-3272.5"
y2="-438.48035" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient39832"
id="radialGradient39804"
cx="3496.6987"
@ -238,7 +192,6 @@
gradientTransform="matrix(0.61314223,0,0,0.49927324,-2207.2336,232.19657)"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient8161"
id="linearGradient40220"
x1="428.48035"
@ -248,7 +201,6 @@
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.85000059,0,0,0.85000059,64.271801,-492.37307)" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient24559"
id="linearGradient63749"
gradientUnits="userSpaceOnUse"
@ -337,14 +289,10 @@
id="g137264"
style="stroke-width:0.666667">
<path
sodipodi:nodetypes="sssscccsssss"
style="display:inline;fill:#62a0ea;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.00753214px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
d="m -3912.0003,-233.37879 c -4.4319,0 -8,3.56799 -8,8 v 27.89844 c 0,4.43202 3.5681,8 8,8 h 36.3333 l 12.6667,12.66667 v -12.66667 h 8.3333 c 4.432,0 8,-3.56798 8,-8 v -27.89844 c 0,-4.43201 -3.568,-8 -8,-8 z"
id="path137260"
inkscape:connector-curvature="0" />
id="path137260" />
<path
sodipodi:nodetypes="cssccccsccsccssc"
inkscape:connector-curvature="0"
id="path137262"
d="m -3920.0003,-199.48035 v 2 c 0,4.43202 3.5681,8 8,8 h 36.3333 l 12.6667,12.66667 v -2 l -12.6667,-12.66667 h -36.3333 c -4.4319,0 -8,-3.56798 -8,-8 z m 73.3333,0 c 0,4.43202 -3.568,8 -8,8 h -8.3333 v 2 h 8.3333 c 4.432,0 8,-3.56798 8,-8 z"
style="display:inline;fill:#3584e4;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.00753214px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new" />
@ -374,17 +322,13 @@
id="g137282"
style="stroke-width:0.666667">
<path
inkscape:connector-curvature="0"
id="path137272"
d="m -3913.6666,-217.48035 c -4.4319,0 -8,3.56798 -8,8 v 24 c 0,4.43202 3.5681,8 8,8 h 15.3333 v 12.66667 l 12.6667,-12.66667 h 45.9999 c 4.432,0 8,-3.56798 8,-8 v -24 c 0,-4.43202 -3.568,-8 -8,-8 z"
style="display:inline;fill:#3d3846;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.00753214px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
sodipodi:nodetypes="sssscccsssss" />
style="display:inline;fill:#3d3846;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.00753214px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new" />
<path
inkscape:connector-curvature="0"
id="path137274"
d="m -3921.6666,-187.48035 v 2 c 0,4.43202 3.5681,8 8,8 h 15.3333 v -2 h -15.3333 c -4.4319,0 -8,-3.56798 -8,-8 z m 89.9999,0 c 0,4.43202 -3.568,8 -8,8 h -45.9999 l -12.6667,12.66667 v 2 l 12.6667,-12.66667 h 45.9999 c 4.432,0 8,-3.56798 8,-8 z"
style="display:inline;fill:#241f31;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.00753214px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
sodipodi:nodetypes="cssccsccsccccssc" />
style="display:inline;fill:#241f31;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.00753214px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new" />
<rect
style="opacity:1;fill:#77767b;fill-opacity:1;stroke:none;stroke-width:9.33333;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect137276"
@ -469,13 +413,12 @@
ry="3.175" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:4.23333px;line-height:1.25;font-family:Cantarell;-inkscape-font-specification:'Cantarell Bold';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#ffffff;stroke-width:0.264583"
style="font-style:normal;font-variant:normal;font-weight:800;font-stretch:normal;font-size:4.23333px;line-height:1.25;font-family:'Adwaita Sans';-inkscape-font-specification:'Adwaita Sans Ultra-Bold';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#ffffff;stroke-width:0.264583"
x="25.548162"
y="7.6729164"
id="text63745"><tspan
sodipodi:role="line"
id="tspan63743"
style="font-style:normal;font-variant:normal;font-weight:800;font-stretch:normal;font-size:4.23333px;font-family:Cantarell;-inkscape-font-specification:'Cantarell Ultra-Bold';fill:#ffffff;stroke-width:0.264583"
style="font-style:normal;font-variant:normal;font-weight:800;font-stretch:normal;font-size:4.23333px;font-family:'Adwaita Sans';-inkscape-font-specification:'Adwaita Sans Ultra-Bold';fill:#ffffff;stroke-width:0.264583"
x="25.548162"
y="7.6729164">999+</tspan></text>
</g>
@ -551,22 +494,12 @@
rx="2"
ry="2" />
<path
inkscape:connector-curvature="0"
style="opacity:1;vector-effect:none;fill:#e5a50a;fill-opacity:1;stroke:none;stroke-width:12.8571;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
d="M 123.82422,231.53906 A 60,60 0 0 1 64,288 60,60 0 0 1 4.17578,232.46094 60,60 0 0 0 4,236 a 60,60 0 0 0 60,60 60,60 0 0 0 60,-60 60,60 0 0 0 -0.17578,-4.46094 z"
id="path1193" />
<path
sodipodi:open="true"
sodipodi:end="3.1415927"
sodipodi:start="0"
sodipodi:ry="7.0068064"
sodipodi:rx="7.6309938"
sodipodi:cy="236.99103"
sodipodi:cx="64"
sodipodi:type="arc"
id="path1195"
style="opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#3d3846;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
sodipodi:arc-type="arc"
d="m 71.630994,236.99103 a 7.6309938,7.0068064 0 0 1 -3.815497,6.06807 7.6309938,7.0068064 0 0 1 -7.630994,0 7.6309938,7.0068064 0 0 1 -3.815497,-6.06807" />
<rect
ry="8"
@ -580,16 +513,7 @@
<path
style="opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#241f31;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="path1199"
sodipodi:type="arc"
sodipodi:cx="64"
sodipodi:cy="-216"
sodipodi:rx="8"
sodipodi:ry="8"
sodipodi:start="0"
sodipodi:end="3.1415927"
sodipodi:open="true"
transform="scale(1,-1)"
sodipodi:arc-type="arc"
d="m 72,-216 a 8,8 0 0 1 -4,6.9282 8,8 0 0 1 -8,0 A 8,8 0 0 1 56,-216" />
<rect
style="opacity:1;vector-effect:none;fill:#241f31;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
@ -640,17 +564,13 @@
transform="matrix(1.5,0,0,1.5,2465.0001,-75.912199)"
id="g137294">
<path
sodipodi:nodetypes="sssccssss"
style="display:inline;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.00753214px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
d="m -3905.3334,-234.37879 c -4.4319,0 -8,3.56799 -8,8 v 27.33333 c 0,4.43202 3.5681,8 8,8 H -3848 c 4.432,0 8,-3.56798 8,-8 v -27.33333 c 0,-4.43201 -3.568,-8 -8,-8 z"
id="path137290"
inkscape:connector-curvature="0" />
id="path137290" />
<path
inkscape:connector-curvature="0"
id="path137292"
d="m -3913.3334,-201.04546 v 2 c 0,4.43202 3.5681,8 8,8 h 19 l 12.6667,12.66667 v -2 l -12.6667,-12.66667 h -19 c -4.4319,0 -8,-3.56798 -8,-8 z m 73.3334,0 c 0,4.43202 -3.568,8 -8,8 h -25.6667 v 2 H -3848 c 4.432,0 8,-3.56798 8,-8 z"
style="display:inline;fill:#deddda;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.00753214px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
sodipodi:nodetypes="cssccccsccsccssc" />
style="display:inline;fill:#deddda;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.00753214px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new" />
</g>
<rect
y="-412.48035"
@ -689,42 +609,28 @@
cy="-5.023077"
r="15.875" />
<path
inkscape:connector-curvature="0"
style="display:inline;fill:#e5a50a;fill-opacity:1;stroke:none;stroke-width:3.40177;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;enable-background:new"
d="M 43.734473,-6.2033675 A 15.875,15.875 0 0 1 27.905982,8.735256 15.875,15.875 0 0 1 12.077491,-5.9594534 a 15.875,15.875 0 0 0 -0.04651,0.9363763 15.875,15.875 0 0 0 15.875,15.8750001 15.875,15.875 0 0 0 15.875,-15.8750001 15.875,15.875 0 0 0 -0.04651,-1.1802904 z"
id="path1369-2" />
<path
sodipodi:open="true"
sodipodi:end="3.1415927"
sodipodi:start="0"
sodipodi:ry="1.8538842"
sodipodi:rx="2.0190337"
sodipodi:cy="-4.7608676"
sodipodi:cx="27.905983"
sodipodi:type="arc"
id="path1371-3"
style="display:inline;opacity:1;fill:none;fill-opacity:1;stroke:#3d3846;stroke-width:1.05833;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;enable-background:new"
sodipodi:arc-type="arc"
d="m 29.925017,-4.7608676 a 2.0190337,1.8538842 0 0 1 -1.009517,1.6055108 2.0190337,1.8538842 0 0 1 -2.019034,0 2.0190337,1.8538842 0 0 1 -1.009517,-1.6055108" />
<path
inkscape:connector-curvature="0"
id="path1373-7"
d="m 24.707728,-13.490777 a 2.1168783,2.1168783 0 0 0 -1.459859,0.642337 l -0.620118,0.620117 -0.620117,-0.620117 a 2.1168783,2.1168783 0 0 0 -1.51877,-0.641302 2.1168783,2.1168783 0 0 0 -1.474329,3.6349196 l 2.865975,2.8659745 v -0.00212 a 1.0583333,1.0583333 0 0 0 1.49655,0 l 2.863907,-2.8639082 A 2.1168783,2.1168783 0 0 0 24.707728,-13.49083 Z"
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:url(#radialGradient1395-6);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.23333;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
<path
inkscape:connector-curvature="0"
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:url(#radialGradient1397-9-9);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.23333;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 35.291109,-13.490777 a 2.1168783,2.1168783 0 0 0 -1.459859,0.642337 l -0.620118,0.620117 -0.620117,-0.620117 a 2.1168783,2.1168783 0 0 0 -1.51877,-0.641302 2.1168783,2.1168783 0 0 0 -1.474329,3.6349196 l 2.865975,2.8659745 v -0.00212 a 1.0583333,1.0583333 0 0 0 1.49655,0 l 2.863908,-2.8639082 a 2.1168783,2.1168783 0 0 0 -1.53324,-3.6359539 z"
id="path1375-3-5" />
<path
id="path1377-9"
d="m 18.412505,-11.77202 a 2.1168783,2.1168783 0 0 0 0.60203,1.9171976 l 2.865975,2.8659745 v -0.00212 a 1.0583333,1.0583333 0 0 0 1.49655,0 l 2.863907,-2.8639109 a 2.1168783,2.1168783 0 0 0 0.604615,-1.9166782 2.1168783,2.1168783 0 0 1 -0.604615,1.122929 l -2.863907,2.8639074 a 1.0583333,1.0583333 0 0 1 -1.49655,0 v 0.00212 l -2.865975,-2.8659714 a 2.1168783,2.1168783 0 0 1 -0.60203,-1.123448 z"
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#c01c28;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.23333;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
inkscape:connector-curvature="0" />
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#c01c28;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.23333;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
<path
id="path1379-6-2"
d="m 28.995838,-11.77202 a 2.1168783,2.1168783 0 0 0 0.60203,1.9171976 l 2.865975,2.8659745 v -0.00212 a 1.0583333,1.0583333 0 0 0 1.49655,0 l 2.863908,-2.8639109 a 2.1168783,2.1168783 0 0 0 0.604614,-1.9166782 2.1168783,2.1168783 0 0 1 -0.604614,1.122929 l -2.863908,2.8639074 a 1.0583333,1.0583333 0 0 1 -1.49655,0 v 0.00212 l -2.865975,-2.8659714 a 2.1168783,2.1168783 0 0 1 -0.60203,-1.123448 z"
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#c01c28;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.23333;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
inkscape:connector-curvature="0" />
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#c01c28;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.23333;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 33 KiB

View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" height="16px" viewBox="0 0 16 16" width="16px"><path d="m 3 2 c -1.660156 0 -3 1.339844 -3 3 v 8 c 0 1.660156 1.339844 3 3 3 h 8 c 1.660156 0 3 -1.339844 3 -3 v -4 c 0 -0.550781 -0.449219 -1 -1 -1 s -1 0.449219 -1 1 v 4 c 0 0.554688 -0.445312 1 -1 1 h -8 c -0.554688 0 -1 -0.445312 -1 -1 v -8 c 0 -0.554688 0.445312 -1 1 -1 h 4 c 0.550781 0 1 -0.449219 1 -1 s -0.449219 -1 -1 -1 z m 7 -2 c -0.550781 0 -1 0.449219 -1 1 s 0.449219 1 1 1 h 2.585938 l -5.292969 5.289062 c -0.390625 0.394532 -0.390625 1.027344 0 1.417969 s 1.023437 0.390625 1.414062 0 l 5.292969 -5.292969 v 2.585938 c 0 0.550781 0.449219 1 1 1 s 1 -0.449219 1 -1 v -5 c 0 -0.085938 -0.011719 -0.171875 -0.035156 -0.257812 c -0.023438 -0.085938 -0.054688 -0.167969 -0.101563 -0.242188 c -0.042969 -0.074219 -0.09375 -0.144531 -0.15625 -0.207031 c -0.015625 -0.011719 -0.03125 -0.023438 -0.046875 -0.035157 c -0.054687 -0.050781 -0.117187 -0.09375 -0.183594 -0.128906 c -0.035156 -0.019531 -0.074218 -0.035156 -0.113281 -0.0468748 c -0.050781 -0.0234374 -0.101562 -0.0390624 -0.15625 -0.0507812 c -0.039062 -0.0117188 -0.082031 -0.015625 -0.121093 -0.0195312 c -0.03125 -0.00781255 -0.058594 -0.00781255 -0.085938 -0.0117188 z m 0 0" fill="#222222"/></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" height="16px" viewBox="0 0 16 16" width="16px"><path d="m 13.980469 1.988281 c -0.261719 0.007813 -0.507813 0.117188 -0.6875 0.304688 l -0.984375 0.984375 c -1.285156 -0.828125 -2.78125 -1.273438 -4.308594 -1.277344 c -3.648438 0.003906 -6.832031 2.476562 -7.738281 6.011719 c 0.460937 1.746093 1.496093 3.285156 2.941406 4.371093 l -0.910156 0.910157 c -0.261719 0.25 -0.367188 0.625 -0.273438 0.972656 c 0.089844 0.351563 0.363281 0.625 0.714844 0.714844 c 0.347656 0.09375 0.722656 -0.011719 0.972656 -0.273438 l 11 -11 c 0.296875 -0.289062 0.382813 -0.726562 0.222657 -1.105469 c -0.160157 -0.382812 -0.539063 -0.625 -0.949219 -0.613281 z m -5.980469 2.011719 c 0.957031 0 1.886719 0.347656 2.609375 0.976562 l -1.417969 1.417969 c -0.34375 -0.257812 -0.761718 -0.394531 -1.191406 -0.394531 c -1.105469 0 -2 0.894531 -2 2 c 0 0.429688 0.140625 0.847656 0.394531 1.1875 l -1.417969 1.421875 c -0.628906 -0.726563 -0.972656 -1.652344 -0.976562 -2.609375 c 0 -2.210938 1.789062 -4 4 -4 z m 7.027344 2.207031 l -3.34375 3.34375 c -0.402344 0.960938 -1.167969 1.722657 -2.125 2.128907 l -2.28125 2.277343 c 0.242187 0.027344 0.480468 0.039063 0.722656 0.042969 c 3.648438 -0.003906 6.832031 -2.476562 7.738281 -6.011719 c -0.164062 -0.617187 -0.402343 -1.214843 -0.710937 -1.78125 z m -7.527344 0.792969 c 0.277344 0 0.5 0.222656 0.5 0.5 s -0.222656 0.5 -0.5 0.5 s -0.5 -0.222656 -0.5 -0.5 s 0.222656 -0.5 0.5 -0.5 z m 0 0" fill="#222222"/></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg height="128px" viewBox="0 0 128 128" width="128px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<linearGradient id="a" gradientUnits="userSpaceOnUse" x1="8" x2="58" y1="69.999985" y2="69.999985">
<stop offset="0" stop-color="#4aaac9"/>
<stop offset="0.16" stop-color="#8bddf7"/>
<stop offset="0.32" stop-color="#4aaac9"/>
<stop offset="1" stop-color="#4aaac9"/>
</linearGradient>
<linearGradient id="b" gradientUnits="userSpaceOnUse" x1="31.462524" x2="39" y1="113.997253" y2="113.997253">
<stop offset="0" stop-color="#4aaac9"/>
<stop offset="0.469318" stop-color="#74d7f7"/>
<stop offset="1" stop-color="#4aaac9"/>
</linearGradient>
<linearGradient id="c" gradientUnits="userSpaceOnUse" x1="104" x2="120" y1="84" y2="84">
<stop offset="0" stop-color="#1a5fb4"/>
<stop offset="0.5" stop-color="#4296ff"/>
<stop offset="1" stop-color="#1a5fb4"/>
</linearGradient>
<clipPath id="d">
<path d="m 8 24 h 97 v 84 h -97 z m 0 0"/>
</clipPath>
<clipPath id="e">
<path d="m 24 24 h 80 c 8.835938 0 16 7.164062 16 16 v 52 c 0 8.835938 -7.164062 16 -16 16 h -80 c -8.835938 0 -16 -7.164062 -16 -16 v -52 c 0 -8.835938 7.164062 -16 16 -16 z m 0 0"/>
</clipPath>
<linearGradient id="f" gradientUnits="userSpaceOnUse" x1="55.608135" x2="71.783539" y1="100" y2="48.532928">
<stop offset="0" stop-color="#81dffe"/>
<stop offset="1" stop-color="#9bf8fe"/>
</linearGradient>
<filter id="g" height="100%" width="100%" x="0%" y="0%">
<feColorMatrix in="SourceGraphic" type="matrix" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"/>
</filter>
<mask id="h">
<g filter="url(#g)">
<rect fill-opacity="0.35" height="128" width="128"/>
</g>
</mask>
<clipPath id="i">
<rect height="152" width="192"/>
</clipPath>
<path d="m 24 28 h 72 c 8.835938 0 16 7.164062 16 16 v 52 c 0 8.835938 -7.164062 16 -16 16 h -72 c -8.835938 0 -16 -7.164062 -16 -16 v -52 c 0 -8.835938 7.164062 -16 16 -16 z m 0 0" fill="url(#a)"/>
<path d="m 24 28 h 80 c 8.835938 0 16 7.164062 16 16 v 48 c 0 8.835938 -7.164062 16 -16 16 h -80 c -8.835938 0 -16 -7.164062 -16 -16 v -48 c 0 -8.835938 7.164062 -16 16 -16 z m 0 0" fill="#53bde0"/>
<path d="m 24 100 v 12 h 4 c 2.210938 0 4 1.789062 4 4 v 7 c 0 1.992188 1.183594 3.792969 3.011719 4.585938 c 1.828125 0.789062 3.953125 0.417968 5.40625 -0.945313 l 13.523437 -12.707031 c 1.324219 -1.242188 3.070313 -1.933594 4.882813 -1.933594 h 9.175781 v -12 z m 0 0" fill="url(#b)" fill-rule="evenodd"/>
<path d="m 102 58.566406 h 2 c 8.835938 0 16 7.164063 16 16 v 21.433594 c 0 8.835938 -7.164062 16 -16 16 h -2 c -8.835938 0 -16 -7.164062 -16 -16 v -21.433594 c 0 -8.835937 7.164062 -16 16 -16 z m 0 0" fill="url(#c)"/>
<path d="m 86 87 h 18 v 25 h -18 z m 0 0" fill="#1a5fb4"/>
<path d="m 48 24 h 56 c 8.835938 0 16 7.164062 16 16 v 52 c 0 8.835938 -7.164062 16 -16 16 h -56 c -8.835938 0 -16 -7.164062 -16 -16 v -52 c 0 -8.835938 7.164062 -16 16 -16 z m 0 0" fill="#3584e4"/>
<g clip-path="url(#d)">
<g clip-path="url(#e)">
<path d="m 78.804688 16.023438 l 0.527343 2.460937 c -1.207031 -0.082031 -2.417969 4.964844 -3.621093 4.988281 c -19.335938 0.371094 -38.003907 14.230469 -39.148438 34.546875 c -0.835938 14.761719 9.570312 29.839844 25.15625 30.488281 c 10.371094 0.433594 20.96875 -6.957031 21.242188 -17.925781 c 0.179687 -7.078125 -4.953126 -14.3125 -12.488282 -14.355469 c -4.683594 -0.027343 -9.484375 3.425782 -9.398437 8.429688 c 0.074219 2.980469 2.300781 6.042969 5.511719 5.902344 c 1.8125 -0.082032 3.691406 -1.488282 3.539062 -3.453125 c -0.078125 -1.042969 -0.921875 -2.128907 -2.0625 -1.996094 c -0.5625 0.066406 -1.148438 0.539063 -1.046875 1.15625 c 0.070313 0.273437 0.285156 0.570313 0.597656 0.5 c 0.121094 -0.03125 0.25 -0.144531 0.214844 -0.28125 c 0 -0.042969 -0.070313 -0.09375 -0.113281 -0.074219 c 0 0.003906 -0.070313 0.023438 0 0.035156 v 0.007813 v -0.003906 v 0.035156 c 0 0.050781 -0.09375 0.050781 -0.136719 0.03125 c -0.121094 -0.066406 -0.113281 -0.242187 -0.070313 -0.347656 c 0.164063 -0.265625 0.542969 -0.230469 0.777344 -0.074219 c 0.519532 0.367188 0.429688 1.117188 0.070313 1.558594 c -0.710938 0.898437 -2.074219 0.726562 -2.867188 0.042968 c -1.5 -1.28125 -1.167969 -3.601562 0.070313 -4.941406 c 2.167968 -2.367187 5.929687 -1.792968 8.074218 0.28125 c 3.601563 3.476563 2.652344 9.308594 -0.675781 12.597656 c -5.359375 5.292969 -14.109375 3.800782 -18.992187 -1.324218 c -7.570313 -7.953125 -5.304688 -20.664063 2.335937 -27.6875 c 11.480469 -10.550782 29.507813 -7.242188 39.363281 3.785156 c 14.414063 16.121094 9.6875 41.066406 -5.855468 54.582031 c -11.121094 9.226563 -22.246094 15.429688 -32.949219 19.4375 c -13.058594 75.445313 -75.230469 6.835938 -81.039063 -4.195312 l 0.285157 -105.054688 z m 0 0" fill="url(#f)"/>
</g>
</g>
<path d="m 24 106 v 2 h 4 c 2.210938 0 4 1.789062 4 4 v 7 c 0 1.992188 1.183594 3.792969 3.011719 4.585938 c 1.828125 0.789062 3.953125 0.417968 5.40625 -0.945313 l 13.523437 -12.707031 c 1.324219 -1.242188 3.070313 -1.933594 4.882813 -1.933594 h 9.175781 v -2 z m 0 0" fill="#81dffe" fill-rule="evenodd"/>
<g clip-path="url(#i)" mask="url(#h)" transform="matrix(1 0 0 1 -8 -16)">
<path d="m 173 17 h 8 c 1.65625 0 3 1.34375 3 3 v 7 c 0 1.65625 -1.34375 3 -3 3 h -8 c -1.65625 0 -3 -1.34375 -3 -3 v -7 c 0 -1.65625 1.34375 -3 3 -3 z m 0 0" fill="#241f31"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.5 KiB

View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" height="16px" viewBox="0 0 16 16" width="16px"><path d="m 11.019531 7.996094 c 0 1.65625 -1.34375 3 -3 3 s -3 -1.34375 -3 -3 s 1.34375 -3 3 -3 s 3 1.34375 3 3 z m 0 0" fill="#222222"/></svg>

After

Width:  |  Height:  |  Size: 270 B

View File

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" height="16px" viewBox="0 0 16 16" width="16px"><path d="m 8 0 c -4.410156 0 -8 3.589844 -8 8 s 3.589844 8 8 8 s 8 -3.589844 8 -8 s -3.589844 -8 -8 -8 z m 0 2 c 3.332031 0 6 2.667969 6 6 s -2.667969 6 -6 6 s -6 -2.667969 -6 -6 s 2.667969 -6 6 -6 z m 0 1.875 c -0.621094 0 -1.125 0.503906 -1.125 1.125 s 0.503906 1.125 1.125 1.125 s 1.125 -0.503906 1.125 -1.125 s -0.503906 -1.125 -1.125 -1.125 z m -1.523438 3.125 c -0.265624 0.011719 -0.476562 0.230469 -0.476562 0.5 c 0 0.277344 0.222656 0.5 0.5 0.5 h 0.5 v 3 h -0.5 c -0.277344 0 -0.5 0.222656 -0.5 0.5 s 0.222656 0.5 0.5 0.5 h 3 c 0.277344 0 0.5 -0.222656 0.5 -0.5 s -0.222656 -0.5 -0.5 -0.5 h -0.5 v -4 h -2.5 c -0.007812 0 -0.015625 0 -0.023438 0 z m 0 0" fill="#222222"/></svg>

After

Width:  |  Height:  |  Size: 813 B

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
<path d="m 8 1 c -1.65625 0 -3 1.34375 -3 3 s 1.34375 3 3 3 s 3 -1.34375 3 -3 s -1.34375 -3 -3 -3 z m -1.5 7 c -2.492188 0 -4.5 2.007812 -4.5 4.5 v 0.5 c 0 1.109375 0.890625 2 2 2 h 8 c 1.109375 0 2 -0.890625 2 -2 v -0.5 c 0 -2.492188 -2.007812 -4.5 -4.5 -4.5 z m 0 0" fill="#2e3436"/>
</svg>

After

Width:  |  Height:  |  Size: 424 B

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
<path d="m 8 0 c 0.554688 0 1 0.445312 1 1 v 6.5 s 0 0.5 0.5 0.5 s 0.5 -0.5 0.5 -0.5 v -4.5 c 0 -0.554688 0.445312 -1 1 -1 s 1 0.445312 1 1 v 8.5 c 0 0.5 0.5 0.5 0.5 0.5 l 1.792969 -1.707031 c 0.1875 -0.195313 0.445312 -0.300781 0.71875 -0.304688 c 1.082031 0.085938 1.144531 1.269531 0.695312 1.71875 l -3 3 c -0.707031 0.792969 -1.757812 1.289063 -2.707031 1.292969 h -6 c -3 0 -3 -3 -3 -3 v -8 c 0 -0.554688 0.445312 -1 1 -1 s 1 0.445312 1 1 v 3.5 s 0 0.5 0.5 0.5 s 0.5 -0.5 0.5 -0.5 v -6.5 c 0 -0.554688 0.445312 -1 1 -1 s 1 0.445312 1 1 v 5.5 s 0 0.5 0.5 0.5 s 0.5 -0.5 0.5 -0.5 v -6.5 c 0 -0.554688 0.445312 -1 1 -1 z m 0 0" fill="#2e3436"/>
</svg>

After

Width:  |  Height:  |  Size: 786 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><g color="#bebebe" fill="#2e3436"><path d="M6 0a3 3 0 100 6 3 3 0 000-6zM4.5 7A4.49 4.49 0 000 11.5v.5c0 1 1 1 1 1h6V8.875c0-.83.587-1.554 1.355-1.79A4.532 4.532 0 007.5 7zM9 9v4h1V9z" style="marker:none" overflow="visible"/><path d="M8.875 8A.863.863 0 008 8.875v6.25c0 .492.383.875.875.875h6.25a.863.863 0 00.875-.875v-6.25A.863.863 0 0015.125 8zM11 9h2v1h-2zm0 2h2v4h-2z" style="marker:none" overflow="visible"/></g></svg>

After

Width:  |  Height:  |  Size: 488 B

View File

@ -1,3 +1,48 @@
# Stylesheets
# We accept grass (a Rust SASS compiler) or sass (the official dart SASS compiler).
sass_bin = find_program('grass', required: false)
sass_options = []
if not sass_bin.found()
# Require SASS as we need at least one compiler.
sass_bin = find_program('sass')
if sass_bin.found()
# these options are not supported by grass.
sass_options += ['--no-error-css', '--no-source-map']
endif
endif
scss_files = [
'style',
'style-hc',
]
# Keep ordered alphabetically.
scss_deps = files([
'stylesheet/_common.scss',
'stylesheet/_components.scss',
'stylesheet/_config.scss',
'stylesheet/_login.scss',
'stylesheet/_room_details.scss',
'stylesheet/_room_history.scss',
'stylesheet/_session_view.scss',
'stylesheet/_vendor.scss',
])
stylesheet_deps = []
foreach scss: scss_files
stylesheet_deps += custom_target('@0@.scss'.format(scss),
input: '@0@.scss'.format(scss),
output: '@0@.css'.format(scss),
command: [
sass_bin, sass_options, '@INPUT@', '@OUTPUT@',
],
depend_files: scss_deps,
)
endforeach
# Resources
resources = gnome.compile_resources(
'resources',
@ -5,4 +50,5 @@ resources = gnome.compile_resources(
gresource_bundle: true,
install: true,
install_dir: pkgdatadir,
dependencies: stylesheet_deps,
)

View File

@ -13,10 +13,12 @@
<file preprocess="xml-stripblanks">icons/scalable/actions/edit-symbolic.svg</file>
<file preprocess="xml-stripblanks">icons/scalable/actions/emoji-symbolic.svg</file>
<file preprocess="xml-stripblanks">icons/scalable/actions/expander-arrow-symbolic.svg</file>
<file preprocess="xml-stripblanks">icons/scalable/actions/external-link-symbolic.svg</file>
<file preprocess="xml-stripblanks">icons/scalable/actions/fullscreen-symbolic.svg</file>
<file preprocess="xml-stripblanks">icons/scalable/actions/go-bottom-symbolic.svg</file>
<file preprocess="xml-stripblanks">icons/scalable/actions/go-next-symbolic.svg</file>
<file preprocess="xml-stripblanks">icons/scalable/actions/go-previous-symbolic.svg</file>
<file preprocess="xml-stripblanks">icons/scalable/actions/hide-symbolic.svg</file>
<file preprocess="xml-stripblanks">icons/scalable/actions/idp-apple-dark.svg</file>
<file preprocess="xml-stripblanks">icons/scalable/actions/idp-apple.svg</file>
<file preprocess="xml-stripblanks">icons/scalable/actions/idp-facebook.svg</file>
@ -41,24 +43,30 @@
<file preprocess="xml-stripblanks">icons/scalable/actions/settings-symbolic.svg</file>
<file preprocess="xml-stripblanks">icons/scalable/actions/system-search-symbolic.svg</file>
<file preprocess="xml-stripblanks">icons/scalable/actions/user-add-symbolic.svg</file>
<file preprocess="xml-stripblanks">icons/scalable/apps/org.gnome.Fractal.svg</file>
<file preprocess="xml-stripblanks">icons/scalable/status/audio-symbolic.svg</file>
<file preprocess="xml-stripblanks">icons/scalable/status/blocked-symbolic.svg</file>
<file preprocess="xml-stripblanks">icons/scalable/status/checkmark-symbolic.svg</file>
<file preprocess="xml-stripblanks">icons/scalable/status/devices-symbolic.svg</file>
<file preprocess="xml-stripblanks">icons/scalable/status/document-symbolic.svg</file>
<file preprocess="xml-stripblanks">icons/scalable/status/done-symbolic.svg</file>
<file preprocess="xml-stripblanks">icons/scalable/status/dot-symbolic.svg</file>
<file preprocess="xml-stripblanks">icons/scalable/status/empty-page-symbolic.svg</file>
<file preprocess="xml-stripblanks">icons/scalable/status/encryption-symbolic.svg</file>
<file preprocess="xml-stripblanks">icons/scalable/status/error-symbolic.svg</file>
<file preprocess="xml-stripblanks">icons/scalable/status/explore-symbolic.svg</file>
<file preprocess="xml-stripblanks">icons/scalable/status/home-symbolic.svg</file>
<file preprocess="xml-stripblanks">icons/scalable/status/image-symbolic.svg</file>
<file preprocess="xml-stripblanks">icons/scalable/status/info-symbolic.svg</file>
<file preprocess="xml-stripblanks">icons/scalable/status/key-symbolic.svg</file>
<file preprocess="xml-stripblanks">icons/scalable/status/no-camera-symbolic.svg</file>
<file preprocess="xml-stripblanks">icons/scalable/status/notifications-symbolic.svg</file>
<file preprocess="xml-stripblanks">icons/scalable/status/security-symbolic.svg</file>
<file preprocess="xml-stripblanks">icons/scalable/status/person-symbolic.svg</file>
<file preprocess="xml-stripblanks">icons/scalable/status/safety-symbolic.svg</file>
<file preprocess="xml-stripblanks">icons/scalable/status/sync-off-symbolic.svg</file>
<file preprocess="xml-stripblanks">icons/scalable/status/sync-on-symbolic.svg</file>
<file preprocess="xml-stripblanks">icons/scalable/status/sync-partial-symbolic.svg</file>
<file preprocess="xml-stripblanks">icons/scalable/status/user-info-symbolic.svg</file>
<file preprocess="xml-stripblanks">icons/scalable/status/users-symbolic.svg</file>
<file preprocess="xml-stripblanks">icons/scalable/status/verified-danger-symbolic.svg</file>
<file preprocess="xml-stripblanks">icons/scalable/status/verified-symbolic.svg</file>
@ -98,6 +106,7 @@
<file compressed="true">sas-emoji/uk.json</file>
<file compressed="true">sas-emoji/vi.json</file>
<file compressed="true">sas-emoji/zh_Hans.json</file>
<file compressed="true">style-hc.css</file>
<file compressed="true">style.css</file>
</gresource>
</gresources>

View File

@ -0,0 +1,11 @@
// High contrast variant.
// Initialize contrast variable.
@use 'stylesheet/config' with (
$contrast: 'high',
);
@use 'stylesheet/common';
@use 'stylesheet/components';
@use 'stylesheet/login';
@use 'stylesheet/session_view';

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,5 @@
@use 'stylesheet/common';
@use 'stylesheet/components';
@use 'stylesheet/login';
@use 'stylesheet/session_view';

View File

@ -0,0 +1,121 @@
// Global selectors.
@use 'vendor';
:root {
--focus-outline-color: color-mix(in srgb, var(--accent-color) 50%, transparent);
}
textview, text {
color: inherit;
background: none;
}
.bold {
font-weight: bold;
}
button.pill.large {
padding: 12px 40px;
}
.emoji {
font-size: 2em;
}
headerbar .suggested-action, .standalone-button {
min-width: 70px;
}
.extra-large-icon {
-gtk-icon-size: 128px;
}
.form-page {
scrolledwindow > viewport > clamp > box {
margin: 42px 12px;
border-spacing: 24px;
}
levelbar.discrete block {
min-height: 5px;
}
}
box.paragraphs {
// Set the spacing between paragraphs.
border-spacing: 12px;
}
.content .label-button {
min-width: 86px;
}
button.overlaid {
// Make sure the outline is fully visible.
margin: 3px;
}
.avatar-row-list, .string-row-list {
contents {
padding: 0;
}
viewport, listview {
padding: 8px;
}
list, listview {
background-color: transparent;
}
row {
border-radius: vendor.$menu_radius;
margin: 3px 0px;
padding: 6px;
}
}
.avatar-row-list {
row {
&:first-child {
margin-top: 0px;
}
&:last-child {
margin-bottom: 0px;
}
}
}
.string-row-list row {
margin: 0px;
}
.entry-row-error-revealer {
margin-top: 6px;
}
.card-icon {
padding: 12px;
border-radius: 100%;
-gtk-icon-size: 20px;
background-color: color-mix(in srgb, var(--accent-bg-color) 30%, transparent);
}
.card.command {
border-radius: vendor.$menu_radius;
font-size: 90%;
}
scrolledwindow.card {
@include vendor.focus-ring($offset: -1px, $focus-state: ':focus-within');
> textview {
padding: 12px;
}
}
.padded-top-bar {
padding: 0 12px;
}

View File

@ -0,0 +1,168 @@
// Components.
@use "sass:math";
@use 'vendor';
inline-pill {
border-radius: 9999px;
background-color: vendor.$button_color;
@include vendor.focus-ring();
&.activatable {
&:hover {
background-color: vendor.$button_hover_color;
image {
filter: brightness(1.07) ;
}
}
&:active {
background-color: vendor.$button_active_color;
image {
filter: brightness(1.16) ;
}
}
}
}
.selected-avatar avatar {
border: 2px solid var(--accent-bg-color);
}
.blue-checkmark {
color: var(--accent-fg-color);
border-radius: 9999px;
border: solid var(--accent-bg-color) 2px;
background-color: var(--accent-bg-color);
}
role-badge {
color: var(--dark-5);
background-color: var(--light-3);
border-radius: 0.4em;
padding: 0.1em 0.5em;
font-size: 0.8em;
&.creator {
color: var(--accent-fg-color);
background-color: var(--accent-purple);
}
&.admin {
color: var(--accent-fg-color);
background-color: var(--accent-red);
}
&.mod {
color: var(--accent-fg-color);
background-color: var(--accent-yellow);
}
&.muted {
color: var(--light-1);
background-color: var(--dark-2);
}
}
media-viewer toolbarview headerbar {
background: black;
color: white;
}
media-content-viewer controls {
min-width: 300px;
}
location-viewer .map-marker {
color: var(--accent-color);
}
entry inline-pill {
margin-bottom: -0.5em;
}
editable-avatar {
.cutout {
background-color: var(--window-bg-color);
border-radius: 9999px;
padding: 2px;
}
.osd.circular {
$size: 64px;
min-width: $size;
min-height: $size;
border-radius: math.div($size, 2);
}
}
.substring-entry-row .header {
.subtitle {
margin-top: 4px;
margin-bottom: -4px;
}
text placeholder {
opacity: var(--dim-opacity);
}
}
.role-selection-popover {
viewport > box {
padding: 6px;
}
list row {
margin: 0;
padding: 2px 6px;
border-radius: vendor.$menu_radius;
&.spin {
padding: 0;
> box {
min-height: 30px;
}
spinbutton > button {
margin-top: 6px;
margin-bottom: 6px;
}
button.spin-confirm {
min-height: 22px;
min-width: 22px;
padding: 0;
margin-left: 2px;
&:dir(rtl) {
margin-left: 0;
margin-right: 2px;
}
image {
padding: 7px;
}
}
}
}
}
row.button loading-bin label.title {
margin-left: 12px;
margin-right: 12px;
min-height: 40px;
}
crop-circle > .mask {
background: black;
border-radius: 9999px;
}
user-page scrolledwindow > viewport > clamp > box {
margin: 12px;
border-spacing: 24px;
}

View File

@ -0,0 +1,3 @@
// Configuration file with global variable.
$contrast: 'default' !default;

View File

@ -0,0 +1,26 @@
// Login and setup.
login {
min-width: 250px;
}
qrcode {
background-color: white;
padding: 12px;
}
.sso-button {
padding: 4px;
-gtk-icon-size: 26px;
min-height: 34px;
}
setup-view {
clamp {
margin: 12px;
}
.text-button {
min-width: 200px;
}
}

View File

@ -0,0 +1,117 @@
// Room details.
@use 'vendor';
visual-media-history-viewer {
background: black;
color: white;
headerbar {
background: none;
box-shadow: none;
}
gridview {
background: none;
padding: 2px;
}
}
visual-media-history-viewer-item {
background-color: var(--border-color);
transition: vendor.$ease-out-quad;
&:hover, &:focus {
transform: scale(1.03);
}
&:active {
transform: scale(0.98);
}
> overlay > image {
border-radius: 100%;
padding: 12px;
-gtk-icon-size: 24px;
}
}
file-history-viewer, audio-history-viewer {
listview > row {
border-radius: 0;
padding: 6px;
&:last-child {
border-bottom-width: 0;
}
}
}
.room-details listview {
background: transparent;
}
members-list {
listview > row, members-list list > row {
padding: 8px 12px;
min-height: 32px;
}
listview > row {
margin-bottom: 6px;
border-radius: vendor.$card_radius;
}
row .icon {
&:dir(ltr) {
margin-right: 6px;
}
&:dir(rtl) {
margin-left: 6px;
}
}
}
dragoverlay statuspage {
background-color: color-mix(in srgb, var(--accent-bg-color) var(--dim-opacity), transparent);
color: var(--accent-fg-color);
}
.public-address-tag {
color: var(--accent-fg-color);
background-color: var(--accent-bg-color);
border-radius: 0.4em;
padding: 0.3em 0.5em;
margin-left: 0.5em;
}
.permissions-member-list > row {
min-height: 0;
padding: 0;
border-radius: 0;
margin: 6px;
}
permissions-member-row {
padding: 8px;
border-radius: vendor.$card_radius;
@include vendor.focus-ring();
&:hover, &.has-open-popup {
background-color: vendor.$hover_color;
}
&:active {
background-color: vendor.$active_color;
}
}
.user-search-results {
padding: 12px 0px;
> row {
border-radius: vendor.$menu_radius;
}
}

View File

@ -0,0 +1,487 @@
// Room history.
@use 'config';
@use 'vendor';
%nested-effect {
border-left: 2px solid var(--accent-bg-color);
padding-left: 6px;
opacity: if(config.$contrast == 'high', 90%, 70%);
}
room-title {
margin-top: -6px;
margin-bottom: -6px;
min-height: 12px;
padding: 3px 0;
.title {
padding: 0;
font-weight: bold;
}
.subtitle {
padding: 0;
font-weight: normal;
}
&.with-subtitle {
button {
padding-top: 0;
padding-bottom: 0;
}
.title, .subtitle {
margin-top: -0.2rem;
}
}
}
.room-history .room-history-list {
padding-bottom: 0;
> row {
min-height: 0;
padding: 0;
border-radius: 0;
}
}
.room-history-row {
padding-top: 2px;
padding-bottom: 2px;
padding-left: 8px;
padding-right: 8px;
border-radius: vendor.$menu_radius;
@include vendor.focus-ring();
&.has-avatar {
margin-top: 6px;
}
&:not(.has-avatar) {
.event-content {
&:dir(ltr) {
margin-left: 54px;
}
&:dir(rtl) {
margin-right: 54px;
}
}
}
&.has-open-popup {
background-color: vendor.$hover_color;
}
&.selected {
background-color: vendor.$selected_color;
&.has-open-popup {
background-color: vendor.$selected_hover_color;
}
}
&.highlight {
background-color: color-mix(in srgb, var(--accent-bg-color) 20%, transparent);
&.has-open-popup {
background-color: color-mix(in srgb, var(--accent-bg-color) 25%, transparent);
}
&.selected {
background-color: color-mix(in srgb, var(--accent-bg-color) 30%, transparent);
&.has-open-popup {
background-color: color-mix(in srgb, var(--accent-bg-color) 33%, transparent);
}
}
}
}
sender-avatar {
padding: 5px;
border-radius: 100%;
@include vendor.focus-ring();
&:hover {
background-color: vendor.$hover_color;
image {
filter: brightness(1.07) ;
}
}
&:active {
background-color: vendor.$active_color;
image {
filter: brightness(1.16) ;
}
}
&:checked {
background-color: vendor.$selected_color;
image {
filter: brightness(1.1) ;
}
}
popover button.text-button {
padding-left: 10px;
padding-right: 10px;
font-weight: 400;
}
}
message-sender {
@include vendor.focus-ring($offset: -1px, $focus-state: ':focus-within');
border-radius: 3px;
&.activatable {
&:hover, &:focus {
label {
text-decoration-line: underline;
}
}
}
}
.event-content {
.h1 {
font-weight: 800;
font-size: 15pt;
}
.h2 {
font-weight: 800;
font-size: 14pt;
}
.h3 {
font-weight: 700;
font-size: 14pt;
}
.h4 {
font-weight: 700;
font-size: 13pt;
}
.h5 {
font-weight: 700;
font-size: 12pt;
}
.h6 {
font-weight: 700;
font-size: 11pt;
}
.emoji-message {
font-size: 3em;
}
.emote {
color: var(--accent-color);
}
.quote {
@extend %nested-effect;
}
expander-widget > box > {
title {
border-spacing: 6px;
}
:not(title) {
padding: 12px;
}
}
.codeview {
border-radius: vendor.$menu_radius;
padding: 6px;
font-family: monospace;
background-color: var(--text-view-bg);
color: var(--view-fg-color);
}
.timestamp {
min-width: 36px;
font-weight: normal;
}
}
state-group-row.room-history-row {
&:not(.has-avatar) {
.event-content {
&:dir(ltr) {
margin-left: 42px;
}
&:dir(rtl) {
margin-right: 42px;
}
}
}
.expander-title {
padding: 6px 12px;
border-radius: vendor.$menu_radius;
&:hover {
background-color: vendor.$button_hover_color;
}
&:active {
background-color: vendor.$button_active_color;
}
}
image.arrow {
transition: 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
&:not(:checked) image.arrow {
&:dir(ltr) {
transform: rotate(-0.5turn);
}
&:dir(rtl) {
transform: rotate(0.5turn);
}
}
.expander-content {
padding: 3px 6px;
background-color: color-mix(in srgb, var(--view-fg-color) 4%, transparent);
border-radius: vendor.$menu_radius;
}
state-group-item-row {
padding: 6px 12px;
margin: 2px 0;
border-radius: vendor.$menu_radius;
@include vendor.focus-ring();
&.has-open-popup {
background-color: vendor.$hover_color;
}
}
}
message-visual-media {
border-radius: vendor.$menu_radius;
@include vendor.focus-ring();
}
.visual-content {
&.opaque-bg {
background-color: var(--border-color);
}
> .overlaid {
margin: 6px;
}
> .instructions {
padding: 12px;
border-radius: vendor.$menu_radius;
}
&.compact {
> .instructions {
padding: 6px;
}
}
// Copied from .osd button style in https://gitlab.gnome.org/GNOME/libadwaita/-/blob/main/src/stylesheet/widgets/_buttons.scss
&.has-placeholder {
> .instructions {
color: vendor.$osd_fg_color;
background-color: rgb(0 0 0 / 65%);
@if config.$contrast == 'high' {
box-shadow: 0 0 0 1px currentColor;
}
}
&:not(.compact) {
&:hover {
> .instructions {
color: white;
background-color: color-mix(in srgb, black calc(0.85 * 65%), currentColor calc(0.15 * 65%));
}
}
&:active {
> .instructions {
color: white;
background-color: color-mix(in srgb, black calc(0.75 * 65%), currentColor calc(0.25 * 65%));
}
}
}
}
> .spinner {
min-width: 32px;
min-height: 32px;
}
> button {
// Leave enough space at the start to click to be able to view small images.
&:dir(ltr) {
margin-left: 64px;
}
&:dir(rtl) {
margin-right: 64px;
}
}
> image.osd.circular {
min-width: 64px;
min-height: 64px;
border-radius: 32px;
-gtk-icon-size: 32px;
}
.timestamp {
border-radius: 4px;
padding: 2px 5px;
}
&.compact {
> .spinner {
min-width: 16px;
min-height: 16px;
}
> image.osd.circular {
min-width: 32px;
min-height: 32px;
-gtk-icon-size: 16px;
}
}
}
message-reactions {
flowboxchild {
&:hover, &:active {
// Cancel effect under .navigation-sidebar from libadwaita
background-color: transparent;
}
}
&:dir(ltr) .toggle {
padding: 1px 0 1px 6px;
}
&:dir(rtl) .toggle {
padding: 1px 6px 1px 0;
}
.reaction-key-text {
font-size: 0.8em;
}
.reaction-key-emoji {
font-size: 1.1em;
padding-right: 2px;
padding-left: 2px;
}
.reaction-count {
font-size: 0.8em;
}
}
.reaction-chooser {
margin: 6px;
button {
font-size: 1.3em;
-gtk-icon-size: 1.3em;
padding: 2px;
}
}
read-receipts-list {
min-height: 20px;
min-width: 20px;
padding: 6px;
border-radius: 9999px;
@include vendor.focus-ring();
&:hover {
background-color: vendor.$hover_color;
}
&:active {
background-color: vendor.$active_color;
}
&:checked {
background-color: vendor.$selected_color;
}
}
divider-row {
font-size: 0.9em;
font-weight: bold;
label {
opacity: var(--dim-opacity);
}
&.new-messages {
color: var(--accent-color);
label {
opacity: 1;
}
separator {
min-height: 2px;
background-color: var(--accent-color);
}
}
}
typing-row {
padding: 0 6px;
min-height: 30px;
}
.related-event-toolbar {
padding: 0 6px 0 12px;
button {
margin: 12px 6px;
min-height: 24px;
min-width: 24px;
}
.event-content {
@extend %nested-effect;
padding-top: 2px;
padding-bottom: 2px;
}
}
button.send-text-message-button image {
transform: translateX(2px);
}
.composer-replacement {
margin: 12px;
}

View File

@ -0,0 +1,224 @@
// Session view.
@use 'vendor';
@use 'room_history';
@use 'room_details';
// Account switcher
.account-switcher {
list {
background-color: transparent;
}
.account-switcher-row {
border-radius: vendor.$menu_radius;
margin: 3px 0px;
padding: 6px 12px;
&:first-child {
margin-top: 0px;
}
}
button.account-switcher-row {
font-weight: normal;
margin-bottom: 0;
}
}
#new-login-icon {
padding: 12px; // 2 * padding + pixel-size = size (of avatar)
background-color: vendor.$button_color;
border-radius: 9999px;
}
// Sidebar
sidebar {
.collapse-spacing {
padding: 0;
}
searchbar > revealer > box {
padding-top: 0;
padding-bottom: 6px;
}
.sidebar-list row {
margin: 0;
padding: 0;
border-radius: 0;
// Reset focus effect.
&:focus-within {
outline: 0;
}
&:hover, &:selected {
background: none;
}
&:active sidebar-row > *:not(popover) {
background-color: vendor.$active_color;
}
&:selected sidebar-row > *:not(popover) {
background-color: vendor.$selected_color;
}
&:selected sidebar-row:not(.drop-mode) > *:not(popover):hover {
background-color: vendor.$selected_hover_color;
}
&:selected:active sidebar-row > *:not(popover) {
background-color: vendor.$selected_active_color;
}
}
sidebar-row {
> *:not(popover) {
margin: 2px 6px 0;
padding: 9px;
border-radius: vendor.$menu_radius;
}
@include vendor.focus-ring($target: '> *:not(popover)');
&:not(.drop-mode) > *:not(popover):hover {
background-color: vendor.$hover_color;
}
icon-item {
background: none;
font-weight: bold;
image {
min-width: 24px; /* Same width as avatars, so the text is aligned */
}
}
sidebar-section {
margin-top: 6px;
font-size: 0.8em;
font-weight: bold;
image.arrow {
transition: 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
&:not(:checked) image.arrow {
&:dir(ltr) {
transform: rotate(-0.5turn);
}
&:dir(rtl) {
transform: rotate(0.5turn);
}
}
}
.notification-count {
font-weight: bold;
font-size: 0.8em;
border-radius: 9999px;
min-width: 0.8em;
min-height: 0.8em;
line-height: 0.8em;
padding: 0.4em 5px;
color: currentColor;
background-color: color-mix(in srgb, currentColor 15%, transparent);
}
.highlight {
color: var(--accent-fg-color);
background-color: var(--accent-bg-color);
}
&.drag > * {
color: var(--accent-fg-color);
background-color: var(--accent-bg-color);
opacity: var(--disabled-opacity);
}
&.drop-disabled > *:not(popover) {
opacity: var(--disabled-opacity);
}
&.drop-empty > *:not(popover) {
color: var(--accent--color);
}
icon-item.forget {
color: var(--error-color);
background: none;
}
&.drop-active {
background-color: color-mix(in srgb, var(--accent-color) 10%, transparent);
category {
color: var(--accent-color);
}
.dimmed, &.drop-empty .dimmed {
opacity: 1;
}
}
}
}
// Explore
.explore {
.padded-button {
min-width: 64px;
}
.public-rooms row {
border-radius: vendor.$menu_radius;
margin: 6px 0;
padding: 12px;
}
}
.explore-servers-popover list {
background-color: transparent;
color: inherit;
row {
min-height: 36px;
padding: 0 8px;
border-radius: vendor.$menu_radius;
margin: 0 0 2px;
button {
min-height: 24px;
min-width: 24px;
}
}
}
// Invite
.invite-room-name {
font-size: 1.6em;
}
// Event details dialog
.event-details-dialog .sourceview {
font-family: monospace;
}
// Account settings
.account-settings listview {
background: transparent;
}
// Account chooser dialog
.account-chooser list {
background: transparent;
row {
margin-bottom: 6px;
padding: 8px 12px;
min-height: 32px;
border-radius: vendor.$card_radius;
}
}

View File

@ -0,0 +1,41 @@
// SCSS reused directly from other projects.
@use 'config';
// https://gitlab.gnome.org/GNOME/libadwaita/-/blob/1.6.1/src/stylesheet/_colors.scss
$focus_border_opacity: if(config.$contrast == 'high', 80%, 50%);
$focus_border_color: color-mix(in srgb, var(--accent-color) $focus_border_opacity, transparent);
$hover_color: color-mix(in srgb, currentColor 7%, transparent);
$active_color: color-mix(in srgb, currentColor 16%, transparent);
$selected_color: color-mix(in srgb, currentColor 10%, transparent);
$selected_hover_color: color-mix(in srgb, currentColor 13%, transparent);
$selected_active_color: color-mix(in srgb, currentColor 19%, transparent);
$osd_fg_color: RGB(255 255 255 / 90%);
// https://gitlab.gnome.org/GNOME/libadwaita/-/blob/1.6.1/src/stylesheet/widgets/_buttons.scss
$button_color: color-mix(in srgb, currentColor 10%, transparent);
$button_hover_color: color-mix(in srgb, currentColor 15%, transparent);
$button_active_color: color-mix(in srgb, currentColor 30%, transparent);
// https://gitlab.gnome.org/GNOME/libadwaita/-/blob/1.6.1/src/stylesheet/_common.scss
$ease-out-quad: cubic-bezier(0.25, 0.46, 0.45, 0.94);
$focus_transition: outline-color 200ms $ease-out-quad,
outline-width 200ms $ease-out-quad,
outline-offset 200ms $ease-out-quad;
$card_radius: 12px;
$menu_radius: 9px;
// https://gitlab.gnome.org/GNOME/libadwaita/-/blob/1.6.1/src/stylesheet/_drawing.scss
@mixin focus-ring($target: null, $width: 2px, $offset: -$width, $outer: false, $focus-state: ':focus:focus-visible', $transition: null) {
& #{$target} {
outline: 0 solid transparent;
outline-offset: if($outer, $offset + 4px, $offset + $width + 4px);
transition: $focus_transition, $transition;
}
&#{$focus-state} #{$target} {
outline-color: $focus_border_color;
outline-width: $width;
outline-offset: $offset;
}
}

34
deny.toml Normal file
View File

@ -0,0 +1,34 @@
[advisories]
yanked = "deny"
ignore = [
{ id = "RUSTSEC-2024-0436", reason = "paste is unmaintained but used by various dependencies" },
]
[bans]
multiple-versions = "allow"
# To check if a license if compatible with our GPL v3.0 license, see: https://www.gnu.org/licenses/license-list.html
# Keep list sorted alphabetically.
[licenses]
unused-allowed-license = "deny"
allow = [
"Apache-2.0",
"Apache-2.0 WITH LLVM-exception",
"BSD-2-Clause",
"BSD-3-Clause",
"BSL-1.0",
"GPL-3.0",
"LGPL-2.1",
"ISC",
"MIT",
"MPL-2.0",
"Unicode-3.0",
"Zlib",
]
[sources]
required-git-spec="rev"
allow-git = [
"https://github.com/ruma/ruma",
"https://github.com/matrix-org/matrix-rust-sdk",
]

View File

@ -6,7 +6,7 @@
<name xml:lang="en">Fractal</name>
<shortdesc xml:lang="en">Chat on Matrix</shortdesc>
<description xmi:lang="en">
<description xml:lang="en">
Fractal is a Matrix messaging app for GNOME written in Rust. Its interface is optimized for
collaboration in large groups, such as free software projects, and will fit all screens, big or small.
@ -18,8 +18,10 @@
- See who has read messages, and who is typing
- Log into multiple accounts at once (with Single-Sign On support)
</description>
<homepage rdf:resource="https://gitlab.gnome.org/World/fractal" />
<support-forum rdf:resource="https://discourse.gnome.org/tag/fractal" />
<bug-database rdf:resource="https://gitlab.gnome.org/GNOME/fractal/issues" />
<programming-language>Rust</programming-language>
<platform>GTK 4</platform>
@ -27,12 +29,12 @@
<maintainer>
<foaf:Person>
<foaf:name>Julian Sparber</foaf:name>
<gnome:userid>jsparber</gnome:userid>
<foaf:name>Kévin Commaille</foaf:name>
<gnome:userid>kcommaille</gnome:userid>
<foaf:account>
<foaf:OnlineAccount>
<foaf:accountServiceHomepage rdf:resource="https://gitlab.gnome.org"/>
<foaf:accountName>jsparber</foaf:accountName>
<foaf:accountName>kcommaille</foaf:accountName>
</foaf:OnlineAccount>
</foaf:account>
</foaf:Person>
@ -51,12 +53,12 @@
</maintainer>
<maintainer>
<foaf:Person>
<foaf:name>Kévin Commaille</foaf:name>
<gnome:userid>kcommaille</gnome:userid>
<foaf:name>Julian Sparber</foaf:name>
<gnome:userid>jsparber</gnome:userid>
<foaf:account>
<foaf:OnlineAccount>
<foaf:accountServiceHomepage rdf:resource="https://gitlab.gnome.org"/>
<foaf:accountName>kcommaille</foaf:accountName>
<foaf:accountName>jsparber</foaf:accountName>
</foaf:OnlineAccount>
</foaf:account>
</foaf:Person>

View File

@ -1,5 +1,4 @@
#!/bin/bash
# Source: https://gitlab.gnome.org/World/fractal/blob/master/hooks/pre-commit.hook
#!/usr/bin/env bash
export LC_ALL=C
@ -122,12 +121,12 @@ check_cargo() {
elif [ ! -t 1 ]; then
exit 2
elif check_rustup; then
echo -e "$error rustup is installed but the cargo command isn't available"
echo -e "$error rustup is installed but the cargo command isnt available"
exit 2
else
echo ""
echo "y: Install cargo via rustup"
echo "N: Don't install cargo and abort checks"
echo "N: Dont install cargo and abort checks"
echo ""
while true; do
echo -n "Install cargo? [y/N]: "; read yn < /dev/tty
@ -177,7 +176,7 @@ run_rustfmt() {
echo "Rustfmt is needed to check Fractals code style, but it isnt available"
echo ""
echo "y: Install rustfmt via rustup"
echo "N: Don't install rustfmt and abort checks"
echo "N: Dont install rustfmt and abort checks"
echo ""
while true; do
echo -n "Install rustfmt? [y/N]: "; read yn < /dev/tty
@ -256,7 +255,7 @@ run_typos() {
echo "Typos is needed to check spelling mistakes, but it isnt available"
echo ""
echo "y: Install typos via cargo"
echo "N: Don't install typos and abort checks"
echo "N: Dont install typos and abort checks"
echo ""
while true; do
echo -n "Install typos? [y/N]: "; read yn < /dev/tty
@ -295,6 +294,124 @@ run_typos() {
fi
}
# Install machete with cargo.
install_machete() {
echo -e "$Installing cargo-machete…"
cargo install cargo-machete
if ! cargo machete --version>/dev/null 2>&1; then
echo -e "$Could not install cargo-machete"
exit 2
fi
}
# Run machete to check for unused dependencies.
run_machete() {
if ! cargo machete --version >/dev/null 2>&1; then
if [[ $force_install -eq 1 ]]; then
install_machete
elif [ ! -t 1 ]; then
echo "Could not check for unused dependencies, because cargo-machete could not be run"
exit 2
else
echo "cargo-machete is needed to check for unused dependencies, but it isnt available"
echo ""
echo "y: Install cargo-machete via cargo"
echo "N: Dont install cargo-machete and abort checks"
echo ""
while true; do
echo -n "Install cargo-machete? [y/N]: "; read yn < /dev/tty
case $yn in
[Yy]* )
install_machete
break
;;
[Nn]* | "" )
exit 2
;;
* )
echo $invalid
;;
esac
done
fi
fi
echo -e "$Checking for unused dependencies…"
if [[ $verbose -eq 1 ]]; then
echo ""
cargo machete --version
echo ""
fi
if ! cargo machete --with-metadata; then
echo -e " Checking for unused dependencies result: $fail"
echo "Please fix the above issues, either by removing the dependencies, or by adding the necessary configuration option in Cargo.toml (see cargo-machete documentation)"
exit 1
else
echo -e " Checking for unused dependencies result: $ok"
fi
}
# Install cargo-deny with cargo.
install_cargo_deny() {
echo -e "$Installing cargo-deny…"
cargo install cargo-deny
if ! cargo deny --version>/dev/null 2>&1; then
echo -e "$Could not install cargo-deny"
exit 2
fi
}
# Run cargo-deny to check Rust dependencies.
run_cargo_deny() {
if ! cargo deny --version >/dev/null 2>&1; then
if [[ $force_install -eq 1 ]]; then
install_cargo_deny
elif [ ! -t 1 ]; then
echo "Could not check Rust dependencies, because cargo-deny could not be run"
exit 2
else
echo "cargo-deny is needed to check the Rust dependencies, but it isnt available"
echo ""
echo "y: Install cargo-deny via cargo"
echo "N: Dont install cargo-deny and abort checks"
echo ""
while true; do
echo -n "Install cargo-deny? [y/N]: "; read yn < /dev/tty
case $yn in
[Yy]* )
install_cargo_deny
break
;;
[Nn]* | "" )
exit 2
;;
* )
echo $invalid
;;
esac
done
fi
fi
echo -e "$Checking Rust dependencies…"
if [[ $verbose -eq 1 ]]; then
echo ""
cargo deny --version
echo ""
fi
if ! cargo deny check; then
echo -e " Checking Rust dependencies result: $fail"
echo "Please fix the above issues, either by removing the dependencies, or by adding the necessary configuration option in deny.toml (see cargo-deny documentation)"
exit 1
else
echo -e " Checking Rust dependencies result: $ok"
fi
}
# Check if files in POTFILES.in are correct.
#
# This checks, in that order:
@ -521,7 +638,7 @@ run_cargo_sort() {
echo "Cargo-sort is needed to check the sorting in Cargo.toml, but it isnt available"
echo ""
echo "y: Install cargo-sort via cargo"
echo "N: Don't install cargo-sort and abort checks"
echo "N: Dont install cargo-sort and abort checks"
echo ""
while true; do
echo -n "Install cargo-sort? [y/N]: "; read yn < /dev/tty
@ -596,6 +713,10 @@ run_rustfmt
echo ""
run_typos
echo ""
run_machete
echo ""
run_cargo_deny
echo ""
check_potfiles
echo ""
if [[ $git_staged -eq 1 ]]; then

View File

@ -1,5 +1,5 @@
#!/bin/bash
# Depends on: scripts/checks.sh
# Depends on: hooks/checks.sh
# Style helpers
act="\e[1;32m"
@ -11,7 +11,7 @@ res="\e[0m"
echo "-- Pre-commit checks --"
echo "To ignore these checks next time, run: git commit --no-verify"
echo ""
if scripts/checks.sh --git-staged; then
if hooks/checks.sh --git-staged; then
echo ""
echo -e "Pre-commit checks result: ${pos}ok${res}"
elif [[ $? -eq 2 ]]; then

View File

@ -1,8 +1,8 @@
project('fractal',
'rust',
version: '7.beta',
version: '12',
license: 'GPL-3.0-or-later',
meson_version: '>= 0.59')
meson_version: '>= 1.1')
i18n = import('i18n')
gnome = import('gnome')
@ -10,8 +10,8 @@ gnome = import('gnome')
base_id = 'org.gnome.Fractal'
application_id = base_id
major_version = '7'
pre_release_version = 'beta'
major_version = '12'
pre_release_version = ''
version = major_version
if pre_release_version != ''
@ -21,32 +21,29 @@ full_version = version
dependency('glib-2.0', version: '>= 2.76') # update when changing gtk version
dependency('gio-2.0', version: '>= 2.76') # always same version as glib
dependency('gtk4', version: '>= 4.12.0')
dependency(
'libadwaita-1', version: '>= 1.5',
fallback: ['libadwaita', 'libadwaita_dep'],
default_options: ['tests=false', 'examples=false', 'vapi=false']
)
dependency('gtk4', version: '>= 4.16')
dependency('libadwaita-1', version: '>= 1.7')
# Please keep these dependencies sorted.
dependency('gstreamer-1.0', version: '>= 1.20')
dependency('gstreamer-app-1.0', version: '>= 1.20')
dependency('gstreamer-base-1.0', version: '>= 1.20')
dependency('gstreamer-pbutils-1.0', version: '>= 1.20')
dependency('gstreamer-play-1.0', version: '>= 1.20')
dependency('gstreamer-video-1.0', version: '>= 1.20')
dependency(
'gtksourceview-5', version: '>= 5.0.0',
fallback: ['gtksourceview', 'gtksource_dep'],
default_options: ['gtk_doc=false', 'sysprof=false', 'gir=false', 'vapi=false', 'install_tests=false']
)
dependency('openssl', version: '>= 1.0.1')
dependency('gtksourceview-5', version: '>= 5.0.0')
dependency('libwebp', version: '>= 1.0.0')
dependency('openssl', version: '>= 3.0.0')
dependency('shumate-1.0', version: '>= 1.0.0')
dependency('sqlite3', version: '>= 3.24.0')
# Required by glycin crate
dependency('lcms2', version: '>=2.12.0')
# Linux-only dependencies
if build_machine.system() == 'linux'
dependency('libpipewire-0.3', version: '>= 0.3.0')
dependency('xdg-desktop-portal', version: '>= 1.14.1')
# Required by glycin crate
dependency('libseccomp', version: '>= 2.5.0')
endif
glib_compile_resources = find_program('glib-compile-resources', required: true)
@ -69,7 +66,12 @@ iconsdir = datadir / 'icons'
podir = meson.project_source_root() / 'po'
gettext_package = meson.project_name()
if get_option('profile') == 'development'
# When the `build-env` profile is used, we only want to set up the build
# environment for the sandbox, we will not try to compile the app, so we can
# remove some build steps.
build_env_only = get_option('profile') == 'build-env'
if get_option('profile') == 'development' or build_env_only
profile = 'Devel'
application_id += '.Devel'
elif get_option('profile') == 'hack'
@ -97,14 +99,11 @@ if profile == 'Devel'
run_command('cp', '-f', 'hooks/pre-commit.hook', '.git/hooks/pre-commit')
endif
meson.add_dist_script(
'build-aux/dist-vendor.sh',
meson.project_build_root() / 'meson-dist' / meson.project_name() + '-' + version,
meson.project_source_root()
)
if not build_env_only
subdir('data')
subdir('po')
endif
subdir('data')
subdir('po')
subdir('src')
gnome.post_install(

View File

@ -6,7 +6,15 @@ option(
'beta',
'development',
'hack',
'build-env',
],
value: 'default',
description: 'The build profile for Fractal. One of "default", "beta", "development" or "hack".'
)
option(
'disable-glycin-sandbox',
type : 'boolean',
value : false,
description: 'Whether the sandbox of glycin should be disabled.' +
'This is only useful during development.'
)

View File

@ -1,5 +1,6 @@
# please keep this list sorted alphabetically
#
bg
ca
cs
da
@ -16,6 +17,7 @@ fur
fy
gl
he
hi
hr
hu
id
@ -36,6 +38,8 @@ sl
sr
sr@latin
sv
th
tr
uk
uz
zh_CN

View File

@ -10,28 +10,34 @@ src/account_switcher/account_switcher_popover.ui
src/account_switcher/session_item.ui
src/application.rs
src/components/action_button.ui
src/components/auth_dialog.rs
src/components/auth_dialog.ui
src/components/avatar/editable.rs
src/components/avatar/editable.ui
src/components/camera/qrcode_scanner.rs
src/components/camera/qrcode_scanner.ui
src/components/camera/viewfinder.rs
src/components/crypto/identity_setup_view.rs
src/components/crypto/identity_setup_view.ui
src/components/crypto/recovery_setup_view.rs
src/components/crypto/recovery_setup_view.ui
src/components/editable_avatar.rs
src/components/editable_avatar.ui
src/components/dialogs/auth/in_browser_page.ui
src/components/dialogs/auth/mod.rs
src/components/dialogs/auth/mod.ui
src/components/dialogs/auth/password_page.ui
src/components/dialogs/message_dialogs.rs
src/components/dialogs/room_preview.rs
src/components/dialogs/room_preview.ui
src/components/dialogs/user_profile.ui
src/components/offline_banner.rs
src/components/join_room_dialog.rs
src/components/join_room_dialog.ui
src/components/location_viewer.rs
src/components/media_content_viewer.rs
src/components/reaction_chooser.ui
src/components/media/content_viewer.rs
src/components/media/location_viewer.rs
src/components/pill/at_room.rs
src/components/power_level_selection/popover.ui
src/components/power_level_selection/row.ui
src/components/rows/loading_row.ui
src/components/spinner.rs
src/components/user_page.rs
src/components/user_page.ui
src/components/user_profile_dialog.ui
src/contrib/qr_code_scanner/mod.ui
src/contrib/qr_code.rs
src/error_page.rs
src/error_page.ui
src/identity_verification_view/accept_request_page.rs
src/identity_verification_view/accept_request_page.ui
@ -43,11 +49,13 @@ src/identity_verification_view/completed_page.rs
src/identity_verification_view/completed_page.ui
src/identity_verification_view/confirm_qr_code_page.rs
src/identity_verification_view/confirm_qr_code_page.ui
src/identity_verification_view/mod.rs
src/identity_verification_view/mod.ui
src/identity_verification_view/no_supported_methods_page.rs
src/identity_verification_view/no_supported_methods_page.ui
src/identity_verification_view/qr_code_scanned_page.rs
src/identity_verification_view/qr_code_scanned_page.ui
src/identity_verification_view/room_left_page.ui
src/identity_verification_view/sas_page.rs
src/identity_verification_view/sas_page.ui
src/identity_verification_view/scan_qr_code_page.rs
@ -58,21 +66,28 @@ src/login/advanced_dialog.ui
src/login/greeter.ui
src/login/homeserver_page.rs
src/login/homeserver_page.ui
src/login/idp_button.rs
src/login/in_browser_page.rs
src/login/in_browser_page.ui
src/login/method_page.rs
src/login/method_page.ui
src/login/mod.rs
src/login/mod.ui
src/login/session_setup_view.ui
src/login/sso_page.ui
src/login/sso_idp_button.rs
src/secret/linux.rs
src/session/model/session.rs
src/session/model/notifications/mod.rs
src/session/model/room/join_rule.rs
src/session/model/room/mod.rs
src/session/model/room/permissions.rs
src/session/model/room_list/mod.rs
src/session/model/sidebar_data/category/category_type.rs
src/session/model/sidebar_data/section/name.rs
src/session/model/sidebar_data/icon_item.rs
src/session/model/user_sessions_list/user_session.rs
src/session/view/account_settings/encryption_page/import_export_keys_subpage.rs
src/session/view/account_settings/encryption_page/import_export_keys_subpage.ui
src/session/view/account_settings/encryption_page/mod.rs
src/session/view/account_settings/encryption_page/mod.ui
src/session/view/account_settings/general_page/change_password_subpage.rs
src/session/view/account_settings/general_page/change_password_subpage.ui
src/session/view/account_settings/general_page/deactivate_account_subpage.rs
@ -84,65 +99,76 @@ src/session/view/account_settings/general_page/mod.ui
src/session/view/account_settings/mod.ui
src/session/view/account_settings/notifications_page.rs
src/session/view/account_settings/notifications_page.ui
src/session/view/account_settings/security_page/ignored_users_subpage/ignored_user_row.rs
src/session/view/account_settings/security_page/ignored_users_subpage/ignored_user_row.ui
src/session/view/account_settings/security_page/ignored_users_subpage/mod.ui
src/session/view/account_settings/security_page/import_export_keys_subpage.rs
src/session/view/account_settings/security_page/import_export_keys_subpage.ui
src/session/view/account_settings/security_page/mod.rs
src/session/view/account_settings/security_page/mod.ui
src/session/view/account_settings/user_sessions_page/mod.ui
src/session/view/account_settings/user_sessions_page/user_session_row.rs
src/session/view/account_settings/user_sessions_page/user_session_row.ui
src/session/view/account_settings/safety_page/ignored_users_subpage/ignored_user_row.rs
src/session/view/account_settings/safety_page/ignored_users_subpage/ignored_user_row.ui
src/session/view/account_settings/safety_page/ignored_users_subpage/mod.ui
src/session/view/account_settings/safety_page/mod.rs
src/session/view/account_settings/safety_page/mod.ui
src/session/view/account_settings/user_session/user_session_list_subpage.ui
src/session/view/account_settings/user_session/user_session_row.ui
src/session/view/account_settings/user_session/user_session_subpage.rs
src/session/view/account_settings/user_session/user_session_subpage.ui
src/session/view/content/explore/mod.ui
src/session/view/content/explore/public_room_row.rs
src/session/view/content/explore/servers_popover.ui
src/session/view/content/explore/server_row.ui
src/session/view/content/invite.rs
src/session/view/content/invite.ui
src/session/view/content/invite_request.rs
src/session/view/content/invite_request.ui
src/session/view/content/mod.ui
src/session/view/content/room_details/addresses_subpage/completion_popover.ui
src/session/view/content/room_details/addresses_subpage/mod.rs
src/session/view/content/room_details/addresses_subpage/mod.ui
src/session/view/content/room_details/general_page/mod.rs
src/session/view/content/room_details/general_page/mod.ui
src/session/view/content/room_details/edit_details_subpage.rs
src/session/view/content/room_details/edit_details_subpage.ui
src/session/view/content/room_details/general_page.rs
src/session/view/content/room_details/general_page.ui
src/session/view/content/room_details/history_viewer/audio_row.rs
src/session/view/content/room_details/history_viewer/audio_row.ui
src/session/view/content/room_details/history_viewer/audio.ui
src/session/view/content/room_details/history_viewer/file_row.rs
src/session/view/content/room_details/history_viewer/file_row.ui
src/session/view/content/room_details/history_viewer/file.ui
src/session/view/content/room_details/history_viewer/media.ui
src/session/view/content/room_details/invite_subpage/invitee_list.rs
src/session/view/content/room_details/history_viewer/visual_media.ui
src/session/view/content/room_details/invite_subpage/list.rs
src/session/view/content/room_details/invite_subpage/mod.rs
src/session/view/content/room_details/invite_subpage/mod.ui
src/session/view/content/room_details/members_page/members_list_view/extra_lists.rs
src/session/view/content/room_details/members_page/members_list_view/member_row.ui
src/session/view/content/room_details/join_rule_subpage.rs
src/session/view/content/room_details/join_rule_subpage.ui
src/session/view/content/room_details/member_row.ui
src/session/view/content/room_details/members_page/members_list_view/membership_subpage_row.rs
src/session/view/content/room_details/members_page/members_list_view/mod.rs
src/session/view/content/room_details/members_page/members_list_view/mod.ui
src/session/view/content/room_details/members_page/mod.rs
src/session/view/content/room_details/mod.rs
src/session/view/content/room_details/mod.ui
src/session/view/content/room_details/permissions/add_members_subpage.ui
src/session/view/content/room_details/permissions/members_subpage.rs
src/session/view/content/room_details/permissions/members_subpage.ui
src/session/view/content/room_details/permissions/permissions_subpage.rs
src/session/view/content/room_details/permissions/permissions_subpage.ui
src/session/view/content/room_details/room_upgrade_dialog.rs
src/session/view/content/room_history/event_actions.ui
src/session/view/content/room_history/item_row.rs
src/session/view/content/room_details/upgrade_dialog/mod.rs
src/session/view/content/room_details/upgrade_dialog/mod.ui
src/session/view/content/room_history/divider_row.rs
src/session/view/content/room_history/event_actions/context_menu.rs
src/session/view/content/room_history/event_actions/context_menu.ui
src/session/view/content/room_history/event_actions/group.rs
src/session/view/content/room_history/event_actions/quick_reaction_chooser.ui
src/session/view/content/room_history/message_row/audio.rs
src/session/view/content/room_history/message_row/content.rs
src/session/view/content/room_history/message_row/file.rs
src/session/view/content/room_history/message_row/file.ui
src/session/view/content/room_history/message_row/location.rs
src/session/view/content/room_history/message_row/location.ui
src/session/view/content/room_history/message_row/media.rs
src/session/view/content/room_history/message_row/message_state_stack.rs
src/session/view/content/room_history/message_row/message_state_stack.ui
src/session/view/content/room_history/message_row/mod.rs
src/session/view/content/room_history/message_row/reaction/mod.rs
src/session/view/content/room_history/message_row/reaction_list.ui
src/session/view/content/room_history/message_row/reply.ui
src/session/view/content/room_history/message_row/sender_name.rs
src/session/view/content/room_history/message_row/text/widgets.rs
src/session/view/content/room_history/message_row/visual_media.rs
src/session/view/content/room_history/message_row/visual_media.ui
src/session/view/content/room_history/message_toolbar/attachment_dialog.ui
src/session/view/content/room_history/message_toolbar/completion/completion_popover.rs
src/session/view/content/room_history/message_toolbar/mod.rs
@ -153,30 +179,31 @@ src/session/view/content/room_history/mod.ui
src/session/view/content/room_history/read_receipts_list/mod.rs
src/session/view/content/room_history/sender_avatar/mod.rs
src/session/view/content/room_history/sender_avatar/mod.ui
src/session/view/content/room_history/state_row/creation.rs
src/session/view/content/room_history/state_row/creation.ui
src/session/view/content/room_history/state_row/mod.rs
src/session/view/content/room_history/state_row/tombstone.rs
src/session/view/content/room_history/state_row/tombstone.ui
src/session/view/content/room_history/state/content.rs
src/session/view/content/room_history/state/creation.rs
src/session/view/content/room_history/state/creation.ui
src/session/view/content/room_history/state/group_row.rs
src/session/view/content/room_history/title.ui
src/session/view/content/room_history/typing_row.rs
src/session/view/content/room_history/verification_info_bar.rs
src/session/view/create_dm_dialog/mod.rs
src/session/view/create_dm_dialog/mod.ui
src/session/view/create_direct_chat_dialog/mod.rs
src/session/view/create_direct_chat_dialog/mod.ui
src/session/view/create_room_dialog.rs
src/session/view/create_room_dialog.ui
src/session/view/event_details_dialog.rs
src/session/view/event_details_dialog.ui
src/session/view/media_viewer.rs
src/session/view/media_viewer.ui
src/session/view/room_creation.rs
src/session/view/room_creation.ui
src/session/view/sidebar/category_row.rs
src/session/view/sidebar/mod.rs
src/session/view/sidebar/mod.ui
src/session/view/sidebar/room_row.rs
src/session/view/sidebar/row.rs
src/session/view/sidebar/section_row.rs
src/session_list/mod.rs
src/shortcuts.ui
src/user_facing_error.rs
src/utils/matrix.rs
src/utils/media.rs
src/utils/message_dialog.rs
src/utils/matrix/media_message.rs
src/utils/matrix/mod.rs
src/utils/media/image/mod.rs
src/utils/media/mod.rs
src/window.ui

View File

@ -1,4 +1,4 @@
# These are files that we don't want to translate
# Please keep this file sorted alphabetically.
src/i18n.rs
src/utils/macros.rs
src/utils/toast.rs

5053
po/bg.po Normal file

File diff suppressed because it is too large Load Diff

6392
po/cs.po

File diff suppressed because it is too large Load Diff

5599
po/de.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

4135
po/es.po

File diff suppressed because it is too large Load Diff

4545
po/eu.po

File diff suppressed because it is too large Load Diff

5427
po/fa.po

File diff suppressed because it is too large Load Diff

5965
po/fi.po

File diff suppressed because it is too large Load Diff

8747
po/fr.po

File diff suppressed because it is too large Load Diff

6537
po/he.po

File diff suppressed because it is too large Load Diff

4962
po/hi.po Normal file

File diff suppressed because it is too large Load Diff

5754
po/id.po

File diff suppressed because it is too large Load Diff

7521
po/it.po

File diff suppressed because it is too large Load Diff

4726
po/ka.po

File diff suppressed because it is too large Load Diff

5916
po/nb.po

File diff suppressed because it is too large Load Diff

6510
po/nl.po

File diff suppressed because it is too large Load Diff

5921
po/oc.po

File diff suppressed because it is too large Load Diff

6177
po/pt.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

8477
po/ru.po

File diff suppressed because it is too large Load Diff

6142
po/sl.po

File diff suppressed because it is too large Load Diff

7045
po/sv.po

File diff suppressed because it is too large Load Diff

4731
po/th.po Normal file

File diff suppressed because it is too large Load Diff

5558
po/tr.po

File diff suppressed because it is too large Load Diff

5394
po/uk.po

File diff suppressed because it is too large Load Diff

5221
po/uz.po Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 117 KiB

After

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 97 KiB

After

Width:  |  Height:  |  Size: 116 KiB

View File

@ -1,7 +1,7 @@
use gtk::{self, glib, prelude::*, subclass::prelude::*, CompositeTemplate};
use gtk::{self, CompositeTemplate, glib, prelude::*, subclass::prelude::*};
use crate::{
components::{Avatar, AvatarData, Spinner},
components::{Avatar, AvatarData},
prelude::*,
session::model::Session,
session_list::{FailedSession, SessionInfo},
@ -41,8 +41,6 @@ mod imp {
type ParentType = gtk::ListBoxRow;
fn class_init(klass: &mut Self::Class) {
Spinner::ensure_type();
Self::bind_template(klass);
}

View File

@ -6,7 +6,7 @@
<object class="GtkBox">
<property name="spacing">10</property>
<child>
<object class="ComponentsAvatar" id="avatar">
<object class="Avatar" id="avatar">
<property name="size">40</property>
</object>
</child>
@ -25,7 +25,7 @@
<property name="xalign">0.0</property>
<property name="hexpand">True</property>
<style>
<class name="dim-label"/>
<class name="dimmed"/>
<class name="caption"/>
</style>
</object>
@ -38,7 +38,9 @@
<object class="GtkStackPage">
<property name="name">loading</property>
<property name="child">
<object class="Spinner"/>
<object class="AdwSpinner">
<property name="width-request">24</property>
</object>
</property>
</object>
</child>

View File

@ -1,6 +1,6 @@
use adw::{prelude::*, subclass::prelude::*};
use futures_channel::oneshot;
use gtk::{glib, CompositeTemplate};
use gtk::{CompositeTemplate, glib};
use tracing::error;
mod account_row;
@ -60,13 +60,13 @@ mod imp {
impl AccountChooserDialog {
/// Set the list of logged-in sessions.
fn set_session_list(&self, session_list: SessionList) {
self.accounts.bind_model(Some(&session_list), |session| {
fn set_session_list(&self, session_list: &SessionList) {
self.accounts.bind_model(Some(session_list), |session| {
let row = AccountRow::new(session.downcast_ref().unwrap());
row.upcast()
});
self.session_list.set(Some(&session_list));
self.session_list.set(Some(session_list));
}
}
}
@ -92,18 +92,19 @@ impl AccountChooserDialog {
let (sender, receiver) = oneshot::channel();
self.imp().sender.replace(Some(sender));
self.present(parent);
self.present(Some(parent));
receiver.await.ok().flatten()
}
/// Select the given row in the session list.
#[template_callback]
fn select_row(&self, row: gtk::ListBoxRow) {
fn select_row(&self, row: &gtk::ListBoxRow) {
if let Some(sender) = self.imp().sender.take() {
// The index is -1 when it is not in a GtkListBox, but we just got it from the
// GtkListBox so we can safely assume it's a valid u32.
let index = row.index() as u32;
let index = row
.index()
.try_into()
.expect("selected row should have an index");
let session_id = self
.session_list()

View File

@ -1,30 +1,25 @@
use gtk::{
glib::{self, clone, closure},
prelude::*,
subclass::prelude::*,
CompositeTemplate,
};
use gtk::{CompositeTemplate, glib, glib::clone, prelude::*, subclass::prelude::*};
use super::AccountSwitcherPopover;
use crate::{
Window,
components::Avatar,
session_list::SessionInfo,
utils::{template_callbacks::TemplateCallbacks, BoundObjectWeakRef},
Window,
utils::{BoundObjectWeakRef, TemplateCallbacks},
};
mod imp {
use std::cell::RefCell;
use glib::subclass::InitializingObject;
use super::*;
#[derive(Debug, Default, CompositeTemplate)]
#[derive(Debug, Default, CompositeTemplate, glib::Properties)]
#[template(resource = "/org/gnome/Fractal/ui/account_switcher/account_switcher_button.ui")]
#[properties(wrapper_type = super::AccountSwitcherButton)]
pub struct AccountSwitcherButton {
pub popover: BoundObjectWeakRef<AccountSwitcherPopover>,
pub watch: RefCell<Option<gtk::ExpressionWatch>>,
/// The popover of this button.
#[property(get, set = Self::set_popover, explicit_notify, nullable)]
popover: BoundObjectWeakRef<AccountSwitcherPopover>,
}
#[glib::object_subclass]
@ -38,6 +33,7 @@ mod imp {
SessionInfo::ensure_type();
Self::bind_template(klass);
Self::bind_template_callbacks(klass);
TemplateCallbacks::bind_template_callbacks(klass);
}
@ -46,40 +42,85 @@ mod imp {
}
}
#[glib::derived_properties]
impl ObjectImpl for AccountSwitcherButton {
fn constructed(&self) {
self.parent_constructed();
let obj = self.obj();
obj.connect_toggled(|obj| {
obj.handle_toggled();
});
let watch = obj
.property_expression("root")
.chain_property::<Window>("session-selection")
.chain_property::<gtk::SingleSelection>("n-items")
.chain_closure::<bool>(closure!(|_: Option<glib::Object>, n_items: u32| {
n_items > 0
}))
.bind(&*obj, "visible", glib::Object::NONE);
self.watch.replace(Some(watch));
}
fn dispose(&self) {
if let Some(watch) = self.watch.take() {
watch.unwatch();
}
self.reset();
}
}
impl WidgetImpl for AccountSwitcherButton {}
impl ButtonImpl for AccountSwitcherButton {}
impl ToggleButtonImpl for AccountSwitcherButton {}
#[gtk::template_callbacks]
impl AccountSwitcherButton {
/// Set the popover of this button.
fn set_popover(&self, popover: Option<&AccountSwitcherPopover>) {
if self.popover.obj().as_ref() == popover {
return;
}
// Reset the state.
self.reset();
let obj = self.obj();
if let Some(popover) = popover {
// We need to remove the popover from the previous button, if any.
if let Some(parent) = popover
.parent()
.and_downcast::<super::AccountSwitcherButton>()
{
parent.set_popover(None::<AccountSwitcherPopover>);
}
let closed_handler = popover.connect_closed(clone!(
#[weak]
obj,
move |_| {
obj.set_active(false);
}
));
popover.set_parent(&*obj);
self.popover.set(popover, vec![closed_handler]);
}
obj.notify_popover();
}
/// Toggle the popover of this button.
#[template_callback]
fn toggle_popover(&self) {
let obj = self.obj();
if obj.is_active() {
let Some(window) = obj.root().and_downcast::<Window>() else {
return;
};
let popover = window.account_switcher();
self.set_popover(Some(popover));
popover.popup();
} else if let Some(popover) = self.popover.obj() {
popover.popdown();
}
}
/// Reset the state of this button.
fn reset(&self) {
if let Some(popover) = self.popover.obj() {
popover.unparent();
}
self.popover.disconnect_signals();
self.obj().set_active(false);
}
}
}
glib::wrapper! {
/// A button showing the currently selected account and opening the account switcher popover.
/// A button showing the currently selected session and opening the account switcher popover.
pub struct AccountSwitcherButton(ObjectSubclass<imp::AccountSwitcherButton>)
@extends gtk::Widget, gtk::Button, gtk::ToggleButton, @implements gtk::Accessible;
}
@ -89,56 +130,6 @@ impl AccountSwitcherButton {
pub fn new() -> Self {
glib::Object::new()
}
pub fn popover(&self) -> Option<AccountSwitcherPopover> {
self.imp().popover.obj()
}
pub fn set_popover(&self, popover: Option<&AccountSwitcherPopover>) {
let old_popover = self.popover();
if old_popover.as_ref() == popover {
return;
}
let imp = self.imp();
// Reset the state.
if let Some(popover) = old_popover {
popover.unparent();
}
imp.popover.disconnect_signals();
self.set_active(false);
if let Some(popover) = popover {
// We need to remove the popover from the previous button, if any.
if let Some(parent) = popover.parent().and_downcast::<AccountSwitcherButton>() {
parent.set_popover(None);
}
let closed_handler = popover.connect_closed(clone!(@weak self as obj => move |_| {
obj.set_active(false);
}));
popover.set_parent(self);
imp.popover.set(popover, vec![closed_handler]);
}
}
fn handle_toggled(&self) {
if self.is_active() {
let Some(window) = self.root().and_downcast::<Window>() else {
return;
};
let popover = window.account_switcher();
self.set_popover(Some(popover));
popover.popup();
} else if let Some(popover) = self.popover() {
popover.popdown();
}
}
}
impl Default for AccountSwitcherButton {

View File

@ -1,9 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="AccountSwitcherButton" parent="GtkToggleButton">
<signal name="toggled" handler="toggle_popover" swapped="yes"/>
<binding name="visible">
<closure type="gboolean" function="invert_boolean">
<lookup name="is-empty" type="FixedSelection">
<lookup name="session-selection" type="Window">
<lookup name="root">AccountSwitcherButton</lookup>
</lookup>
</lookup>
</closure>
</binding>
<binding name="tooltip-text">
<lookup name="user-id-string" type="SessionInfo">
<lookup name="selected-item" type="GtkSingleSelection">
<lookup name="selected-item" type="FixedSelection">
<lookup name="session-selection" type="Window">
<lookup name="root">AccountSwitcherButton</lookup>
</lookup>
@ -16,13 +26,14 @@
</accessibility>
<style>
<class name="image-button"/>
<class name="circular"/>
</style>
<property name="child">
<object class="ComponentsAvatar">
<object class="Avatar">
<property name="size">24</property>
<binding name="data">
<lookup name="avatar-data" type="SessionInfo">
<lookup name="selected-item" type="GtkSingleSelection">
<lookup name="selected-item" type="FixedSelection">
<lookup name="session-selection" type="Window">
<lookup name="root">AccountSwitcherButton</lookup>
</lookup>

View File

@ -1,12 +1,12 @@
use gtk::{
CompositeTemplate,
glib::{self, clone},
prelude::*,
subclass::prelude::*,
CompositeTemplate,
};
use super::session_item::SessionItemRow;
use crate::utils::BoundObjectWeakRef;
use crate::utils::{BoundObjectWeakRef, FixedSelection};
mod imp {
use glib::subclass::InitializingObject;
@ -18,12 +18,12 @@ mod imp {
#[properties(wrapper_type = super::AccountSwitcherPopover)]
pub struct AccountSwitcherPopover {
#[template_child]
pub sessions: TemplateChild<gtk::ListBox>,
sessions: TemplateChild<gtk::ListBox>,
/// The model containing the logged-in sessions selection.
#[property(get, set = Self::set_session_selection, explicit_notify, nullable)]
pub session_selection: BoundObjectWeakRef<gtk::SingleSelection>,
session_selection: BoundObjectWeakRef<FixedSelection>,
/// The selected row.
pub selected_row: glib::WeakRef<SessionItemRow>,
selected_row: glib::WeakRef<SessionItemRow>,
}
#[glib::object_subclass]
@ -34,7 +34,7 @@ mod imp {
fn class_init(klass: &mut Self::Class) {
Self::bind_template(klass);
Self::Type::bind_template_callbacks(klass);
Self::bind_template_callbacks(klass);
klass.install_action("account-switcher.close", None, |obj, _, _| {
obj.popdown();
@ -52,92 +52,94 @@ mod imp {
impl WidgetImpl for AccountSwitcherPopover {}
impl PopoverImpl for AccountSwitcherPopover {}
#[gtk::template_callbacks]
impl AccountSwitcherPopover {
/// Set the model containing the logged-in sessions selection.
fn set_session_selection(&self, selection: Option<gtk::SingleSelection>) {
if selection == self.session_selection.obj() {
fn set_session_selection(&self, selection: Option<&FixedSelection>) {
if selection == self.session_selection.obj().as_ref() {
return;
}
let obj = self.obj();
self.session_selection.disconnect_signals();
self.sessions.bind_model(selection.as_ref(), |session| {
let row = SessionItemRow::new(session.downcast_ref().unwrap());
self.sessions.bind_model(selection, |session| {
let row = SessionItemRow::new(
session
.downcast_ref()
.expect("sessions list box item should be a Session"),
);
row.upcast()
});
if let Some(selection) = &selection {
let selected_handler =
selection.connect_selected_item_notify(clone!(@weak obj => move |selection| {
obj.update_selected_item(selection.selected());
}));
obj.update_selected_item(selection.selected());
if let Some(selection) = selection {
let selected_handler = selection.connect_selected_item_notify(clone!(
#[weak(rename_to = imp)]
self,
move |selection| {
imp.update_selected_item(selection.selected());
}
));
self.update_selected_item(selection.selected());
self.session_selection
.set(selection, vec![selected_handler]);
}
obj.notify_session_selection();
self.obj().notify_session_selection();
}
/// Select the given row in the session list.
#[template_callback]
fn select_row(&self, row: &gtk::ListBoxRow) {
self.obj().popdown();
let Some(selection) = self.session_selection.obj() else {
return;
};
let index = u32::try_from(row.index()).expect("selected row has an index");
selection.set_selected(index);
}
/// Update the selected item in the session list.
fn update_selected_item(&self, selected: u32) {
let old_selected = self.selected_row.upgrade();
let new_selected = if selected == gtk::INVALID_LIST_POSITION {
None
} else {
let index = selected.try_into().expect("item index should fit into i32");
self.sessions
.row_at_index(index)
.and_downcast::<SessionItemRow>()
};
if old_selected == new_selected {
return;
}
if let Some(row) = &old_selected {
row.set_selected(false);
}
if let Some(row) = &new_selected {
row.set_selected(true);
}
self.selected_row.set(new_selected.as_ref());
}
}
}
glib::wrapper! {
/// A popover allowing to switch between the available sessions, to open their
/// account settings, or to log into a new account.
pub struct AccountSwitcherPopover(ObjectSubclass<imp::AccountSwitcherPopover>)
@extends gtk::Widget, gtk::Popover, @implements gtk::Accessible;
}
#[gtk::template_callbacks]
impl AccountSwitcherPopover {
pub fn new() -> Self {
glib::Object::new()
}
fn selected_row(&self) -> Option<SessionItemRow> {
self.imp().selected_row.upgrade()
}
/// Select the given row in the session list.
#[template_callback]
fn select_row(&self, row: gtk::ListBoxRow) {
self.popdown();
let Some(selection) = self.session_selection() else {
return;
};
// The index is -1 when it is not in a GtkListBox, but we just got it from the
// GtkListBox so we can safely assume it's a valid u32.
selection.set_selected(row.index() as u32);
}
/// Update the selected item in the session list.
fn update_selected_item(&self, selected: u32) {
let imp = self.imp();
let old_selected = self.selected_row();
let new_selected = if selected == gtk::INVALID_LIST_POSITION {
None
} else {
imp.sessions
.row_at_index(selected as i32)
.and_downcast::<SessionItemRow>()
};
if old_selected == new_selected {
return;
}
if let Some(row) = &old_selected {
row.set_selected(false);
}
if let Some(row) = &new_selected {
row.set_selected(true);
}
imp.selected_row.set(new_selected.as_ref());
}
}
impl Default for AccountSwitcherPopover {

View File

@ -1,5 +1,5 @@
use adw::subclass::prelude::*;
use gtk::{glib, prelude::*, CompositeTemplate};
use adw::{prelude::*, subclass::prelude::*};
use gtk::{CompositeTemplate, glib};
use crate::components::{Avatar, AvatarData};
@ -15,18 +15,18 @@ mod imp {
#[properties(wrapper_type = super::AvatarWithSelection)]
pub struct AvatarWithSelection {
#[template_child]
pub child_avatar: TemplateChild<Avatar>,
child_avatar: TemplateChild<Avatar>,
#[template_child]
pub checkmark: TemplateChild<gtk::Image>,
checkmark: TemplateChild<gtk::Image>,
/// The [`AvatarData`] displayed by this widget.
#[property(get = Self::data, set = Self::set_data, explicit_notify, nullable)]
pub data: PhantomData<Option<AvatarData>>,
data: PhantomData<Option<AvatarData>>,
/// The size of the Avatar.
#[property(get = Self::size, set = Self::set_size, minimum = -1, default = -1)]
pub size: PhantomData<i32>,
size: PhantomData<i32>,
/// Whether this avatar is selected.
#[property(get = Self::is_selected, set = Self::set_selected, explicit_notify)]
pub selected: PhantomData<bool>,
selected: PhantomData<bool>,
}
#[glib::object_subclass]
@ -103,7 +103,7 @@ mod imp {
}
glib::wrapper! {
/// A widget displaying an `Avatar` for a `Room` or `User` and an optional selected effect.
/// A widget displaying an [`Avatar`] and an optional selected effect.
pub struct AvatarWithSelection(ObjectSubclass<imp::AvatarWithSelection>)
@extends gtk::Widget, adw::Bin, @implements gtk::Accessible;
}
@ -112,8 +112,4 @@ impl AvatarWithSelection {
pub fn new() -> Self {
glib::Object::new()
}
pub fn avatar(&self) -> &Avatar {
&self.imp().child_avatar
}
}

View File

@ -5,7 +5,7 @@
<property name="child">
<object class="GtkOverlay">
<child>
<object class="ComponentsAvatar" id="child_avatar"></object>
<object class="Avatar" id="child_avatar"></object>
</child>
<child type="overlay">
<object class="GtkImage" id="checkmark">

View File

@ -3,7 +3,7 @@ mod account_switcher_popover;
mod avatar_with_selection;
mod session_item;
pub use self::{
pub(crate) use self::{
account_switcher_button::AccountSwitcherButton,
account_switcher_popover::AccountSwitcherPopover,
};

View File

@ -1,4 +1,4 @@
use gtk::{self, glib, prelude::*, subclass::prelude::*, CompositeTemplate};
use gtk::{CompositeTemplate, glib, prelude::*, subclass::prelude::*};
use super::avatar_with_selection::AvatarWithSelection;
use crate::{
@ -20,22 +20,22 @@ mod imp {
#[properties(wrapper_type = super::SessionItemRow)]
pub struct SessionItemRow {
#[template_child]
pub avatar: TemplateChild<AvatarWithSelection>,
avatar: TemplateChild<AvatarWithSelection>,
#[template_child]
pub display_name: TemplateChild<gtk::Label>,
display_name: TemplateChild<gtk::Label>,
#[template_child]
pub user_id: TemplateChild<gtk::Label>,
user_id: TemplateChild<gtk::Label>,
#[template_child]
pub state_stack: TemplateChild<gtk::Stack>,
state_stack: TemplateChild<gtk::Stack>,
#[template_child]
pub error_image: TemplateChild<gtk::Image>,
error_image: TemplateChild<gtk::Image>,
/// The session this item represents.
#[property(get, set = Self::set_session, explicit_notify)]
pub session: glib::WeakRef<SessionInfo>,
pub user_bindings: RefCell<Vec<glib::Binding>>,
session: glib::WeakRef<SessionInfo>,
user_bindings: RefCell<Vec<glib::Binding>>,
/// Whether this session is selected.
#[property(get = Self::is_selected, set = Self::set_selected, explicit_notify)]
pub selected: PhantomData<bool>,
selected: PhantomData<bool>,
}
#[glib::object_subclass]
@ -46,7 +46,7 @@ mod imp {
fn class_init(klass: &mut Self::Class) {
Self::bind_template(klass);
Self::Type::bind_template_callbacks(klass);
Self::bind_template_callbacks(klass);
}
fn instance_init(obj: &InitializingObject<Self>) {
@ -66,6 +66,7 @@ mod imp {
impl WidgetImpl for SessionItemRow {}
impl ListBoxRowImpl for SessionItemRow {}
#[gtk::template_callbacks]
impl SessionItemRow {
/// Whether this session is selected.
fn is_selected(&self) -> bool {
@ -145,6 +146,23 @@ mod imp {
self.session.set(session);
self.obj().notify_session();
}
/// Show the account settings for the session of this row.
#[template_callback]
fn show_account_settings(&self) {
let Some(session) = self.session.upgrade() else {
return;
};
let obj = self.obj();
obj.activate_action("account-switcher.close", None)
.expect("`account-switcher.close` action should exist");
obj.activate_action(
"win.open-account-settings",
Some(&session.session_id().to_variant()),
)
.expect("`win.open-account-settings` action should exist");
}
}
}
@ -154,24 +172,8 @@ glib::wrapper! {
@extends gtk::Widget, gtk::ListBoxRow, @implements gtk::Accessible;
}
#[gtk::template_callbacks]
impl SessionItemRow {
pub fn new(session: &SessionInfo) -> Self {
glib::Object::builder().property("session", session).build()
}
#[template_callback]
pub fn show_account_settings(&self) {
let Some(session) = self.session() else {
return;
};
self.activate_action("account-switcher.close", None)
.unwrap();
self.activate_action(
"win.open-account-settings",
Some(&session.session_id().to_variant()),
)
.unwrap();
}
}

View File

@ -21,14 +21,16 @@
<object class="GtkLabel" id="display_name">
<property name="xalign">0.0</property>
<property name="hexpand">True</property>
<property name="ellipsize">end</property>
</object>
</child>
<child>
<object class="GtkLabel" id="user_id">
<property name="xalign">0.0</property>
<property name="hexpand">True</property>
<property name="ellipsize">end</property>
<style>
<class name="dim-label"/>
<class name="dimmed"/>
<class name="caption"/>
</style>
</object>
@ -41,7 +43,11 @@
<object class="GtkStackPage">
<property name="name">loading</property>
<property name="child">
<object class="Spinner"/>
<object class="AdwSpinner">
<property name="valign">center</property>
<property name="halign">center</property>
<property name="height-request">24</property>
</object>
</property>
</object>
</child>
@ -54,9 +60,6 @@
<property name="valign">center</property>
<property name="halign">center</property>
<property name="tooltip-text" translatable="yes">Account Settings</property>
<accessibility>
<property name="label" translatable="yes">Account Settings</property>
</accessibility>
<signal name="clicked" handler="show_account_settings" swapped="true"/>
<style>
<class name="circular"/>

View File

@ -1,4 +1,4 @@
use std::{cell::RefCell, fmt, rc::Rc};
use std::{borrow::Cow, cell::RefCell, fmt, rc::Rc};
use adw::{prelude::*, subclass::prelude::*};
use gettextrs::gettext;
@ -6,28 +6,39 @@ use gtk::{gio, glib, glib::clone};
use tracing::{debug, error, info, warn};
use crate::{
config, intent,
GETTEXT_PACKAGE, Window, config,
intent::SessionIntent,
prelude::*,
session::model::{Session, SessionState},
session_list::{FailedSession, SessionInfo, SessionList},
spawn,
system_settings::SystemSettings,
toast,
utils::{matrix::MatrixIdUri, BoundObjectWeakRef, LoadingState},
Window,
utils::{BoundObjectWeakRef, LoadingState, matrix::MatrixIdUri},
};
/// The key for the current session setting.
pub(crate) const SETTINGS_KEY_CURRENT_SESSION: &str = "current-session";
/// The name of the application.
pub(crate) const APP_NAME: &str = "Fractal";
/// The URL of the homepage of the application.
pub(crate) const APP_HOMEPAGE_URL: &str = "https://gitlab.gnome.org/World/fractal/";
mod imp {
use std::cell::Cell;
use super::*;
#[derive(Debug)]
pub struct Application {
/// The application settings.
pub settings: gio::Settings,
pub(super) settings: gio::Settings,
/// The system settings.
pub system_settings: SystemSettings,
pub(super) system_settings: SystemSettings,
/// The list of logged-in sessions.
pub session_list: SessionList,
pub intent_handler: BoundObjectWeakRef<glib::Object>,
pub(super) session_list: SessionList,
intent_handler: BoundObjectWeakRef<glib::Object>,
last_network_state: Cell<NetworkState>,
}
impl Default for Application {
@ -37,6 +48,7 @@ mod imp {
system_settings: Default::default(),
session_list: Default::default(),
intent_handler: Default::default(),
last_network_state: Default::default(),
}
}
}
@ -52,43 +64,77 @@ mod imp {
fn constructed(&self) {
self.parent_constructed();
let app = self.obj();
app.set_up_gactions();
app.set_up_accels();
// Initialize actions and accelerators.
self.set_up_gactions();
self.set_up_accels();
self.session_list
.connect_error_notify(clone!(@weak app => move |session_list| {
// Listen to errors in the session list.
self.session_list.connect_error_notify(clone!(
#[weak(rename_to = imp)]
self,
move |session_list| {
if let Some(message) = session_list.error() {
let window = app.present_main_window();
let window = imp.present_main_window();
window.show_secret_error(&message);
}
}));
spawn!(
clone!(@weak self.session_list as session_list => async move {
}
));
// Restore the sessions.
spawn!(clone!(
#[weak(rename_to = session_list)]
self.session_list,
async move {
session_list.restore_sessions().await;
})
);
}
));
// Watch the network to log its state.
let network_monitor = gio::NetworkMonitor::default();
network_monitor.connect_network_changed(clone!(
#[weak(rename_to = imp)]
self,
move |network_monitor, _| {
let network_state = NetworkState::with_monitor(network_monitor);
if imp.last_network_state.get() == network_state {
return;
}
network_state.log();
imp.last_network_state.set(network_state);
}
));
}
}
impl ApplicationImpl for Application {
fn activate(&self) {
self.parent_activate();
debug!("Application::activate");
self.obj().present_main_window();
self.present_main_window();
}
fn startup(&self) {
self.parent_startup();
// Set icons for shell
gtk::Window::set_default_icon_name(crate::APP_ID);
}
fn open(&self, files: &[gio::File], _hint: &str) {
debug!("Application::open");
self.obj().present_main_window();
self.present_main_window();
if files.len() > 1 {
warn!("Trying to open several URIs, only the first one will be processed");
}
if let Some(uri) = files.first().map(|f| f.uri()) {
self.obj().process_uri(&uri);
if let Some(uri) = files.first().map(FileExt::uri) {
self.process_uri(&uri);
} else {
debug!("No URI to open");
}
@ -97,9 +143,336 @@ mod imp {
impl GtkApplicationImpl for Application {}
impl AdwApplicationImpl for Application {}
impl Application {
/// Get or create the main window and make sure it is visible.
///
/// Returns the main window.
fn present_main_window(&self) -> Window {
let window = if let Some(window) = self.obj().active_window().and_downcast() {
window
} else {
Window::new(&self.obj())
};
window.present();
window
}
/// Set up the application actions.
fn set_up_gactions(&self) {
self.obj().add_action_entries([
// Quit
gio::ActionEntry::builder("quit")
.activate(|obj: &super::Application, _, _| {
if let Some(window) = obj.active_window() {
// This is needed to trigger the close request and save the window
// state.
window.close();
}
obj.quit();
})
.build(),
// About
gio::ActionEntry::builder("about")
.activate(|obj: &super::Application, _, _| {
obj.imp().show_about_dialog();
})
.build(),
// Show a room. This is the action triggered when clicking a notification about a
// message.
gio::ActionEntry::builder(SessionIntent::SHOW_MATRIX_ID_ACTION_NAME)
.parameter_type(Some(&SessionIntent::static_variant_type()))
.activate(|obj: &super::Application, _, variant| {
debug!(
"`{}` action activated",
SessionIntent::SHOW_MATRIX_ID_APP_ACTION_NAME
);
let Some((session_id, intent)) =
variant.and_then(SessionIntent::show_matrix_id_from_variant)
else {
error!(
"Activated `{}` action without the proper payload",
SessionIntent::SHOW_MATRIX_ID_APP_ACTION_NAME
);
return;
};
obj.imp().process_session_intent(session_id, intent);
})
.build(),
// Show an identity verification. This is the action triggered when clicking a
// notification about a new verification.
gio::ActionEntry::builder(SessionIntent::SHOW_IDENTITY_VERIFICATION_ACTION_NAME)
.parameter_type(Some(&SessionIntent::static_variant_type()))
.activate(|obj: &super::Application, _, variant| {
debug!(
"`{}` action activated",
SessionIntent::SHOW_IDENTITY_VERIFICATION_APP_ACTION_NAME
);
let Some((session_id, intent)) = variant
.and_then(SessionIntent::show_identity_verification_from_variant)
else {
error!(
"Activated `{}` action without the proper payload",
SessionIntent::SHOW_IDENTITY_VERIFICATION_APP_ACTION_NAME
);
return;
};
obj.imp().process_session_intent(session_id, intent);
})
.build(),
]);
}
/// Sets up keyboard shortcuts for application and window actions.
fn set_up_accels(&self) {
let obj = self.obj();
obj.set_accels_for_action("app.quit", &["<Control>q"]);
obj.set_accels_for_action("win.show-help-overlay", &["<Control>question"]);
obj.set_accels_for_action("window.close", &["<Control>w"]);
}
/// Show the dialog with information about the application.
fn show_about_dialog(&self) {
let dialog = adw::AboutDialog::builder()
.application_name(APP_NAME)
.application_icon(config::APP_ID)
.developer_name(gettext("The Fractal Team"))
.license_type(gtk::License::Gpl30)
.website(APP_HOMEPAGE_URL)
.issue_url("https://gitlab.gnome.org/World/fractal/-/issues")
.support_url("https://matrix.to/#/#fractal:gnome.org")
.version(config::VERSION)
.copyright(gettext("© The Fractal Team"))
.developers([
"Alejandro Domínguez",
"Alexandre Franke",
"Bilal Elmoussaoui",
"Christopher Davis",
"Daniel García Moreno",
"Eisha Chen-yen-su",
"Jordan Petridis",
"Julian Sparber",
"Kévin Commaille",
"Saurav Sachidanand",
])
.designers(["Tobias Bernard"])
.translator_credits(gettext("translator-credits"))
.build();
// This can't be added via the builder
dialog.add_credit_section(Some(&gettext("Name by")), &["Regina Bíró"]);
// If the user wants our support room, try to open it ourselves.
dialog.connect_activate_link(clone!(
#[weak(rename_to = imp)]
self,
#[weak]
dialog,
#[upgrade_or]
false,
move |_, uri| {
if uri == "https://matrix.to/#/#fractal:gnome.org"
&& imp.session_list.has_session_ready()
{
imp.process_uri(uri);
dialog.close();
return true;
}
false
}
));
dialog.present(Some(&self.present_main_window()));
}
/// Process the given URI.
fn process_uri(&self, uri: &str) {
debug!(uri, "Processing URI…");
match MatrixIdUri::parse(uri) {
Ok(matrix_id) => {
self.select_session_for_intent(SessionIntent::ShowMatrixId(matrix_id));
}
Err(error) => warn!("Invalid Matrix URI: {error}"),
}
}
/// Select a session to handle the given intent as soon as possible.
fn select_session_for_intent(&self, intent: SessionIntent) {
debug!(?intent, "Selecting session for intent…");
// We only handle a single intent at time, the latest one.
self.intent_handler.disconnect_signals();
if self.session_list.state() == LoadingState::Ready {
match self.session_list.n_items() {
0 => {
warn!("Cannot process intent with no logged in session");
}
1 => {
let session = self
.session_list
.first()
.expect("there should be one session");
self.process_session_intent(session.session_id(), intent);
}
_ => {
spawn!(clone!(
#[weak(rename_to = imp)]
self,
async move {
imp.ask_session_for_intent(intent).await;
}
));
}
}
} else {
debug!(?intent, "Session list is not ready, queuing intent…");
// Wait for the list to be ready.
let cell = Rc::new(RefCell::new(Some(intent)));
let handler = self.session_list.connect_state_notify(clone!(
#[weak(rename_to = imp)]
self,
#[strong]
cell,
move |session_list| {
if session_list.state() == LoadingState::Ready {
imp.intent_handler.disconnect_signals();
if let Some(intent) = cell.take() {
imp.select_session_for_intent(intent);
}
}
}
));
self.intent_handler
.set(self.session_list.upcast_ref(), vec![handler]);
}
}
/// Ask the user to choose a session to process the given Matrix ID URI.
///
/// The session list needs to be ready.
async fn ask_session_for_intent(&self, intent: SessionIntent) {
debug!(?intent, "Asking to select a session to process intent…");
let main_window = self.present_main_window();
let Some(session_id) = main_window.ask_session().await else {
warn!("No session selected to show intent");
return;
};
self.process_session_intent(session_id, intent);
}
/// Process the given intent for the given session, as soon as the
/// session is ready.
fn process_session_intent(&self, session_id: String, intent: SessionIntent) {
let Some(session_info) = self.session_list.get(&session_id) else {
warn!(
session = session_id,
?intent,
"Could not find session to process intent"
);
toast!(self.present_main_window(), gettext("Session not found"));
return;
};
debug!(session = session_id, ?intent, "Processing session intent…");
if session_info.is::<FailedSession>() {
// We can't do anything, it should show an error screen.
warn!(
session = session_id,
?intent,
"Could not process intent for failed session"
);
} else if let Some(session) = session_info.downcast_ref::<Session>() {
if session.state() == SessionState::Ready {
self.present_main_window()
.process_session_intent(session.session_id(), intent);
} else {
debug!(
session = session_id,
?intent,
"Session is not ready, queuing intent…"
);
// Wait for the session to be ready.
let cell = Rc::new(RefCell::new(Some((session_id, intent))));
let handler = session.connect_ready(clone!(
#[weak(rename_to = imp)]
self,
#[strong]
cell,
move |_| {
imp.intent_handler.disconnect_signals();
if let Some((session_id, intent)) = cell.take() {
imp.present_main_window()
.process_session_intent(&session_id, intent);
}
}
));
self.intent_handler.set(session.upcast_ref(), vec![handler]);
}
} else {
debug!(
session = session_id,
?intent,
"Session is still loading, queuing intent…"
);
// Wait for the session to be a `Session`.
let cell = Rc::new(RefCell::new(Some((session_id, intent))));
let handler = self.session_list.connect_items_changed(clone!(
#[weak(rename_to = imp)]
self,
#[strong]
cell,
move |session_list, pos, _, added| {
if added == 0 {
return;
}
let Some(session_id) = cell
.borrow()
.as_ref()
.map(|(session_id, _)| session_id.clone())
else {
return;
};
for i in pos..pos + added {
let Some(session_info) =
session_list.item(i).and_downcast::<SessionInfo>()
else {
break;
};
if session_info.session_id() == session_id {
imp.intent_handler.disconnect_signals();
if let Some((session_id, intent)) = cell.take() {
imp.process_session_intent(session_id, intent);
}
break;
}
}
}
));
self.intent_handler
.set(self.session_list.upcast_ref(), vec![handler]);
}
}
}
}
glib::wrapper! {
/// The Fractal application.
pub struct Application(ObjectSubclass<imp::Application>)
@extends gio::Application, gtk::Application, adw::Application,
@implements gio::ActionMap, gio::ActionGroup;
@ -114,255 +487,23 @@ impl Application {
.build()
}
/// Get or create the main window and make sure it is visible.
///
/// Returns the main window.
fn present_main_window(&self) -> Window {
let window = if let Some(window) = self.active_window().and_downcast() {
window
} else {
Window::new(self)
};
window.present();
window
}
/// The application settings.
pub fn settings(&self) -> gio::Settings {
pub(crate) fn settings(&self) -> gio::Settings {
self.imp().settings.clone()
}
/// The system settings.
pub fn system_settings(&self) -> SystemSettings {
pub(crate) fn system_settings(&self) -> SystemSettings {
self.imp().system_settings.clone()
}
/// The list of logged-in sessions.
pub fn session_list(&self) -> &SessionList {
pub(crate) fn session_list(&self) -> &SessionList {
&self.imp().session_list
}
/// Set up the application actions.
fn set_up_gactions(&self) {
self.add_action_entries([
// Quit
gio::ActionEntry::builder("quit")
.activate(|app: &Application, _, _| {
if let Some(window) = app.active_window() {
// This is needed to trigger the delete event
// and saving the window state
window.close();
}
app.quit();
})
.build(),
// About
gio::ActionEntry::builder("about")
.activate(|app: &Application, _, _| {
app.show_about_dialog();
})
.build(),
// Show a room. This is the action triggered when clicking a notification.
gio::ActionEntry::builder("show-room")
.parameter_type(Some(&intent::ShowRoomPayload::static_variant_type()))
.activate(|app: &Application, _, v| {
let Some(payload) = v.and_then(|v| v.get::<intent::ShowRoomPayload>()) else {
error!("Triggered `show-room` action without the proper payload");
return;
};
app.process_intent(intent::SessionIntent::ShowRoom(payload));
})
.build(),
]);
}
/// Sets up keyboard shortcuts for application and window actions.
fn set_up_accels(&self) {
self.set_accels_for_action("app.quit", &["<Control>q"]);
self.set_accels_for_action("win.show-help-overlay", &["<Control>question"]);
}
fn show_about_dialog(&self) {
let dialog = adw::AboutDialog::builder()
.application_name("Fractal")
.application_icon(config::APP_ID)
.developer_name(gettext("The Fractal Team"))
.license_type(gtk::License::Gpl30)
.website("https://gitlab.gnome.org/World/fractal/")
.issue_url("https://gitlab.gnome.org/World/fractal/-/issues")
.support_url("https://matrix.to/#/#fractal:gnome.org")
.version(config::VERSION)
.copyright(gettext("© 2017-2024 The Fractal Team"))
.developers(vec![
"Alejandro Domínguez".to_string(),
"Alexandre Franke".to_string(),
"Bilal Elmoussaoui".to_string(),
"Christopher Davis".to_string(),
"Daniel García Moreno".to_string(),
"Eisha Chen-yen-su".to_string(),
"Jordan Petridis".to_string(),
"Julian Sparber".to_string(),
"Kévin Commaille".to_string(),
"Saurav Sachidanand".to_string(),
])
.designers(vec!["Tobias Bernard".to_string()])
.translator_credits(gettext("translator-credits"))
.build();
// This can't be added via the builder
dialog.add_credit_section(Some(&gettext("Name by")), &["Regina Bíró"]);
dialog.present(&self.present_main_window());
}
/// Process the given URI.
fn process_uri(&self, uri: &str) {
match MatrixIdUri::parse(uri) {
Ok(matrix_id) => self.process_intent(matrix_id),
Err(error) => warn!("Invalid Matrix URI: {error}"),
}
}
/// Process the given intent, as soon as possible.
fn process_intent(&self, intent: impl Into<intent::AppIntent>) {
let intent = intent.into();
debug!("Processing intent {intent:?}");
// We only handle a single intent at time, the latest one.
self.imp().intent_handler.disconnect_signals();
let session_list = self.session_list();
if session_list.state() == LoadingState::Ready {
match intent {
intent::AppIntent::WithSession(session_intent) => {
self.process_session_intent(session_intent);
}
intent::AppIntent::ShowMatrixId(matrix_uri) => match session_list.n_items() {
0 => {
warn!("Cannot open URI with no logged in session");
}
1 => {
let session = session_list.first().expect("There should be one session");
let session_intent = intent::SessionIntent::with_matrix_uri(
session.session_id(),
matrix_uri,
);
self.process_session_intent(session_intent);
}
_ => {
spawn!(clone!(@weak self as obj => async move {
obj.choose_session_for_uri(matrix_uri).await;
}));
}
},
}
} else {
// Wait for the list to be ready.
let cell = Rc::new(RefCell::new(Some(intent)));
let handler = session_list.connect_state_notify(
clone!(@weak self as app, @strong cell => move |session_list| {
if session_list.state() == LoadingState::Ready {
app.imp().intent_handler.disconnect_signals();
if let Some(intent) = cell.take() {
app.process_intent(intent);
}
}
}),
);
self.imp()
.intent_handler
.set(session_list.upcast_ref(), vec![handler]);
}
}
/// Ask the user to choose a session to process the given Matrix ID URI.
///
/// The session list needs to be ready.
async fn choose_session_for_uri(&self, matrix_uri: MatrixIdUri) {
let main_window = self.present_main_window();
let Some(session_id) = main_window.choose_session_for_uri().await else {
warn!("No session selected to show URI");
return;
};
let session_intent = intent::SessionIntent::with_matrix_uri(session_id, matrix_uri);
self.process_session_intent(session_intent);
}
/// Process the given for a session, as soon as the session is ready.
fn process_session_intent(&self, intent: intent::SessionIntent) {
let Some(session_info) = self.session_list().get(intent.session_id()) else {
warn!("Could not find session to process intent {intent:?}");
toast!(self.present_main_window(), gettext("Session not found"));
return;
};
if session_info.is::<FailedSession>() {
// We can't do anything, it should show an error screen.
warn!("Could not process intent {intent:?} for failed session");
} else if let Some(session) = session_info.downcast_ref::<Session>() {
if session.state() == SessionState::Ready {
self.present_main_window()
.process_session_intent_ready(intent);
} else {
// Wait for the session to be ready.
let cell = Rc::new(RefCell::new(Some(intent)));
let handler = session.connect_state_notify(
clone!(@weak self as app, @strong cell => move |session| {
if session.state() == SessionState::Ready {
app.imp().intent_handler.disconnect_signals();
if let Some(intent) = cell.take() {
app.present_main_window().process_session_intent_ready(intent);
}
}
}),
);
self.imp()
.intent_handler
.set(session.upcast_ref(), vec![handler]);
}
} else {
// Wait for the session to be a `Session`.
let session_list = self.session_list();
let cell = Rc::new(RefCell::new(Some(intent)));
let handler = session_list.connect_items_changed(
clone!(@weak self as app, @strong cell => move |session_list, pos, _, added| {
if added == 0 {
return;
}
let Some(session_id) = cell.borrow().as_ref().map(|i| i.session_id().to_owned()) else {
return;
};
for i in pos..pos + added {
let Some(session_info) = session_list.item(i).and_downcast::<SessionInfo>() else {
break;
};
if session_info.session_id() == session_id {
app.imp().intent_handler.disconnect_signals();
if let Some(intent) = cell.take() {
app.process_session_intent(intent);
}
break;
}
}
}),
);
self.imp()
.intent_handler
.set(session_list.upcast_ref(), vec![handler]);
}
}
pub fn run(&self) {
/// Run Fractal.
pub(crate) fn run(&self) {
info!("Fractal ({})", config::APP_ID);
info!("Version: {} ({})", config::VERSION, config::PROFILE);
info!("Datadir: {}", config::PKGDATADIR);
@ -375,14 +516,14 @@ impl Default for Application {
fn default() -> Self {
gio::Application::default()
.and_downcast::<Application>()
.unwrap()
.expect("application should always be available")
}
}
/// The profile that was built.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[allow(dead_code)]
pub enum AppProfile {
pub(crate) enum AppProfile {
/// A stable release.
Stable,
/// A beta release.
@ -393,7 +534,7 @@ pub enum AppProfile {
impl AppProfile {
/// The string representation of this `AppProfile`.
pub fn as_str(&self) -> &str {
pub(crate) fn as_str(&self) -> &str {
match self {
Self::Stable => "stable",
Self::Beta => "beta",
@ -402,9 +543,17 @@ impl AppProfile {
}
/// Whether this `AppProfile` should use the `.devel` CSS class on windows.
pub fn should_use_devel_class(&self) -> bool {
pub(crate) fn should_use_devel_class(self) -> bool {
matches!(self, Self::Devel)
}
/// The name of the directory where to put data for this profile.
pub(crate) fn dir_name(self) -> Cow<'static, str> {
match self {
AppProfile::Stable => Cow::Borrowed(GETTEXT_PACKAGE),
_ => Cow::Owned(format!("{GETTEXT_PACKAGE}-{self}")),
}
}
}
impl fmt::Display for AppProfile {
@ -412,3 +561,41 @@ impl fmt::Display for AppProfile {
f.write_str(self.as_str())
}
}
/// The state of the network.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum NetworkState {
/// The network is available.
Unavailable,
/// The network is available with the given connectivity.
Available(gio::NetworkConnectivity),
}
impl NetworkState {
/// Construct the network state with the given network monitor.
fn with_monitor(monitor: &gio::NetworkMonitor) -> Self {
if monitor.is_network_available() {
Self::Available(monitor.connectivity())
} else {
Self::Unavailable
}
}
/// Log this network state.
fn log(self) {
match self {
Self::Unavailable => {
info!("Network is unavailable");
}
Self::Available(connectivity) => {
info!("Network connectivity is {connectivity:?}");
}
}
}
}
impl Default for NetworkState {
fn default() -> Self {
Self::Available(gio::NetworkConnectivity::Full)
}
}

View File

@ -1,7 +1,5 @@
use adw::subclass::prelude::*;
use gtk::{glib, glib::closure_local, prelude::*, CompositeTemplate};
use super::Spinner;
use adw::{prelude::*, subclass::prelude::*};
use gtk::{CompositeTemplate, glib, glib::closure_local};
#[derive(Debug, Default, Hash, Eq, PartialEq, Clone, Copy, glib::Enum)]
#[repr(u32)]
@ -35,10 +33,10 @@ mod imp {
use std::{
cell::{Cell, RefCell},
marker::PhantomData,
sync::LazyLock,
};
use glib::subclass::{InitializingObject, Signal};
use once_cell::sync::Lazy;
use super::*;
@ -46,41 +44,39 @@ mod imp {
#[template(resource = "/org/gnome/Fractal/ui/components/action_button.ui")]
#[properties(wrapper_type = super::ActionButton)]
pub struct ActionButton {
#[template_child]
stack: TemplateChild<gtk::Stack>,
#[template_child]
button_default: TemplateChild<gtk::Button>,
/// The icon used in the default state.
#[property(get, set = Self::set_icon_name, explicit_notify)]
pub icon_name: RefCell<String>,
/// The extra classes applied to the button in the default state.
pub extra_classes: RefCell<Vec<String>>,
icon_name: RefCell<String>,
/// The extra CSS classes applied to the button in the default state.
extra_classes: RefCell<Vec<&'static str>>,
/// The action emitted by the button.
#[property(get = Self::action_name, set = Self::set_action_name, override_interface = gtk::Actionable)]
pub action_name: RefCell<Option<glib::GString>>,
action_name: RefCell<Option<glib::GString>>,
/// The target value of the action of the button.
#[property(get = Self::action_target_value, set = Self::set_action_target, override_interface = gtk::Actionable)]
pub action_target: RefCell<Option<glib::Variant>>,
action_target: RefCell<Option<glib::Variant>>,
/// The state of the button.
#[property(get, set = Self::set_state, explicit_notify, builder(ActionState::default()))]
pub state: Cell<ActionState>,
state: Cell<ActionState>,
/// The tooltip text of the button of the default state.
#[property(set = Self::set_default_state_tooltip_text)]
pub default_state_tooltip_text: PhantomData<Option<String>>,
#[template_child]
pub stack: TemplateChild<gtk::Stack>,
#[template_child]
pub button_default: TemplateChild<gtk::Button>,
#[template_child]
pub spinner: TemplateChild<Spinner>,
default_state_tooltip_text: PhantomData<Option<String>>,
}
#[glib::object_subclass]
impl ObjectSubclass for ActionButton {
const NAME: &'static str = "ComponentsActionButton";
const NAME: &'static str = "ActionButton";
type Type = super::ActionButton;
type ParentType = adw::Bin;
type Interfaces = (gtk::Actionable,);
fn class_init(klass: &mut Self::Class) {
Self::bind_template(klass);
Self::Type::bind_template_callbacks(klass);
Self::bind_template_callbacks(klass);
klass.set_css_name("action-button");
}
@ -93,8 +89,8 @@ mod imp {
#[glib::derived_properties]
impl ObjectImpl for ActionButton {
fn signals() -> &'static [Signal] {
static SIGNALS: Lazy<Vec<Signal>> =
Lazy::new(|| vec![Signal::builder("clicked").build()]);
static SIGNALS: LazyLock<Vec<Signal>> =
LazyLock::new(|| vec![Signal::builder("clicked").build()]);
SIGNALS.as_ref()
}
}
@ -120,6 +116,7 @@ mod imp {
}
}
#[gtk::template_callbacks]
impl ActionButton {
/// Set the icon used in the default state.
fn set_icon_name(&self, icon_name: &str) {
@ -131,6 +128,27 @@ mod imp {
self.obj().notify_icon_name();
}
/// Set the extra CSS classes applied to the button in the default
/// state.
pub(super) fn set_extra_classes(&self, classes: &[&'static str]) {
let mut extra_classes = self.extra_classes.borrow_mut();
if *extra_classes == classes {
// Nothing to do.
return;
}
for class in extra_classes.drain(..) {
self.button_default.remove_css_class(class);
}
for class in classes {
self.button_default.add_css_class(class);
}
extra_classes.extend(classes);
}
/// Set the state of the button.
fn set_state(&self, state: ActionState) {
if self.state.get() == state {
@ -148,8 +166,13 @@ mod imp {
}
/// Set the tooltip text of the button of the default state.
fn set_default_state_tooltip_text(&self, text: Option<String>) {
self.button_default.set_tooltip_text(text.as_deref());
fn set_default_state_tooltip_text(&self, text: Option<&str>) {
self.button_default.set_tooltip_text(text);
}
#[template_callback]
fn button_clicked(&self) {
self.obj().emit_by_name::<()>("clicked", &[]);
}
}
}
@ -166,25 +189,12 @@ impl ActionButton {
glib::Object::new()
}
pub fn extra_classes(&self) -> Vec<String> {
self.imp().extra_classes.borrow().clone()
}
pub fn set_extra_classes(&self, classes: &[&str]) {
let imp = self.imp();
for class in imp.extra_classes.borrow_mut().drain(..) {
imp.button_default.remove_css_class(&class);
}
for class in classes.iter() {
imp.button_default.add_css_class(class);
}
self.imp()
.extra_classes
.replace(classes.iter().map(ToString::to_string).collect());
/// Set the extra CSS classes applied to the button in the default state.
pub(crate) fn set_extra_classes(&self, classes: &[&'static str]) {
self.imp().set_extra_classes(classes);
}
/// Connect to the signal emitted when the button is clicked.
pub fn connect_clicked<F: Fn(&Self) + 'static>(&self, f: F) -> glib::SignalHandlerId {
self.connect_closure(
"clicked",
@ -194,9 +204,4 @@ impl ActionButton {
}),
)
}
#[template_callback]
fn button_clicked(&self) {
self.emit_by_name::<()>("clicked", &[]);
}
}

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="ComponentsActionButton" parent="AdwBin">
<template class="ActionButton" parent="AdwBin">
<child>
<object class="GtkStack" id="stack">
<property name="transition-type">crossfade</property>
@ -13,9 +13,9 @@
<class name="circular"/>
</style>
<property name="valign">center</property>
<property name="icon-name" bind-source="ComponentsActionButton" bind-property="icon-name" bind-flags="sync-create"/>
<property name="action-name" bind-source="ComponentsActionButton" bind-property="action-name" bind-flags="sync-create"/>
<property name="action-target" bind-source="ComponentsActionButton" bind-property="action-target" bind-flags="sync-create"/>
<property name="icon-name" bind-source="ActionButton" bind-property="icon-name" bind-flags="sync-create"/>
<property name="action-name" bind-source="ActionButton" bind-property="action-name" bind-flags="sync-create"/>
<property name="action-target" bind-source="ActionButton" bind-property="action-target" bind-flags="sync-create"/>
<signal name="clicked" handler="button_clicked" swapped="true"/>
</object>
</property>
@ -27,15 +27,14 @@
<property name="child">
<object class="GtkButton">
<style>
<class name="opaque"/>
<class name="circular"/>
<class name="suggested-action"/>
</style>
<property name="tooltip-text" translatable="yes">Confirm Change</property>
<property name="valign">center</property>
<property name="icon-name">checkmark-symbolic</property>
<property name="action-name" bind-source="ComponentsActionButton" bind-property="action-name" bind-flags="sync-create"/>
<property name="action-target" bind-source="ComponentsActionButton" bind-property="action-target" bind-flags="sync-create"/>
<property name="action-name" bind-source="ActionButton" bind-property="action-name" bind-flags="sync-create"/>
<property name="action-target" bind-source="ActionButton" bind-property="action-target" bind-flags="sync-create"/>
<signal name="clicked" handler="button_clicked" swapped="true"/>
</object>
</property>
@ -47,15 +46,14 @@
<property name="child">
<object class="GtkButton">
<style>
<class name="opaque"/>
<class name="circular"/>
<class name="suggested-action"/>
</style>
<property name="tooltip-text" translatable="yes">Try Again</property>
<property name="valign">center</property>
<property name="icon-name">refresh-symbolic</property>
<property name="action-name" bind-source="ComponentsActionButton" bind-property="action-name" bind-flags="sync-create"/>
<property name="action-target" bind-source="ComponentsActionButton" bind-property="action-target" bind-flags="sync-create"/>
<property name="action-name" bind-source="ActionButton" bind-property="action-name" bind-flags="sync-create"/>
<property name="action-target" bind-source="ActionButton" bind-property="action-target" bind-flags="sync-create"/>
<signal name="clicked" handler="button_clicked" swapped="true"/>
</object>
</property>
@ -74,9 +72,12 @@
<property name="can-target">false</property>
<property name="valign">center</property>
<child>
<object class="Spinner" id="spinner">
<object class="AdwSpinner">
<property name="valign">center</property>
</object>
<property name="halign">center</property>
<property name="height-request">20</property>
<property name="width-request">20</property>
</object>
</child>
</object>
</property>
@ -89,7 +90,7 @@
<property name="child">
<object class="GtkButton">
<style>
<class name="opaque"/>
<class name="suggested-action"/>
<class name="circular"/>
<class name="success"/>
</style>

View File

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="ComponentsAudioPlayer" parent="AdwBin">
<child>
<object class="GtkMediaControls">
<property name="media-stream" bind-source="ComponentsAudioPlayer" bind-property="media-file" bind-flags="sync-create"/>
</object>
</child>
</template>
</interface>

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