Commit Graph

7144 Commits

Author SHA1 Message Date
Michael Telatynski
102a1ddb9e Fix token expiry racing with login causing wrong error to be shown (#29566)
* Fix token expiry racing with login causing wrong error to be shown

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Add tests

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* yay jest

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

---------

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
2025-03-25 12:07:07 +00:00
Will Hunt
599112e122 Replace checkboxes with Compound checkboxes, and appropriately label each checkbox. (#29363)
* Fix labelling of avatar menu

* Make the integration manager toggle more clear.

* fix label

* lint

* Update snapshots.

* Refactor many cases of checkbox to use the new compound component.

* Remove non-checkbox related changes

* Reset some things

* Remove usages of mx_checkbox* styling.

* Use label locators for apperance tests.

* small linter tweaks

* lint

* update screenshot

* Test updates

* lint

* Realign checkboxes for device selection.

* Fixup QuickSettings styling

* remove comment

* lint

* flex comment

* remove unused label

* remove redundant classes

* add test for spaces

* lint

* Copyright

* fixup spaces test

* spaces lint

* Replace pin with compound pin.

* Realign icons

* Remove hack for colouring icons

* Adjust existing rooms component to correctly label room.

* Add test for adding an existing room to an existing space.

* Set deterministic sort order for rooms

* lint
2025-03-20 15:35:54 +00:00
Andy Balaam
170dcd1c0e In force-verify mode, prevent bypassing by cancelling device verification (#29487)
* In force-verify mode, prevent bypassing by cancelling device verification

* Don't show the after-login screen if we are racing with forced verification

* Unit test for not bypassing verification by cancelling device verify
2025-03-20 15:10:08 +00:00
Arpit Batra
435d0f96b8 Add title attribute to user identifier (#29547) 2025-03-20 08:58:57 +00:00
Michael Telatynski
a32704ae5b Silence React error about getDerivedStateFromProps (#29544)
Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
2025-03-19 18:07:21 +00:00
Michael Telatynski
5b1be70ee8 Avoid legacy contexts as much as possible (#29537)
Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
2025-03-19 10:40:06 +00:00
Michael Telatynski
a6ae04bcde Update react imports (#29538)
Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
2025-03-19 10:39:52 +00:00
Robin
aa996010b4 Show error screens in group calls (#29254)
* Avoid destroying calls until they are hidden from the UI

We often want calls to exist even when no more participants are left in the MatrixRTC session. So, we should avoid destroying calls as long as they're being presented in the UI; this means that the user has an intent to either join the call or continue looking at an error screen, and we shouldn't interrupt that interaction.

The RoomViewStore is now what takes care of creating and destroying calls, rather than the CallView. In general it seems kinda impossible to safely create and destroy model objects from React lifecycle hooks, so moving this responsibility to a store seemed appropriate and resolves existing issues with calls in React strict mode.

* Wait for a close action before closing a call

This creates a distinction between the user hanging up and the widget being ready to close, which is useful for allowing Element Call to show error screens when disconnected from the call, for example.

* Don't expect a 'close' action in video rooms

These use the returnToLobby option and are expected to remain visible when the user leaves the call.
2025-03-05 20:41:26 +00:00
Florian Duros
e749b017c9 refactor: rename mx_RoomList as mx_LegacyRoomList (#29362) 2025-02-27 13:34:54 +00:00
Florian Duros
0997e0a747 refactor: rename RoomListView as RoomListPanel (#29361) 2025-02-26 11:14:04 +00:00
Florian Duros
8857c07acb Move view_create_chat & view_create_room to actions.ts (#29319)
* refactor: replace `view_create_chat` by `Action.CreateChat`

* refactor: replace `view_create_room` by `Action.CreateRoom`
2025-02-19 15:11:43 +00:00
Florian Duros
28ed506fe1 refactor: rename RoomListHeader as LegacyRoomListHeader (#29308) 2025-02-19 14:06:01 +00:00
Michael Telatynski
dd2da5c132 Fix up UIA types and remove unused prop (#29255)
Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
2025-02-17 09:53:26 +00:00
Florian D
2abd5342c2 New room list: add search section (#29251)
* feat(new room list): move `RoomListView` to its own folder and add styling

* feat(new room list): add search section

* test(new room list): add tests for `RoomListSearch`

* test(new room list): add tests for `RoomListView`

* test(e2e): add method to close notification toast to `ElementAppPage`

* test(e2e): add tests for the search section

* test(e2e): add tests for the room list view

* refactor: use Flex component

* fix: loop icon size in search button

* refactor: remove `focus_room_filter` listener
2025-02-13 15:49:09 +00:00
Florian D
85f80b1d0a Replace focus_room_filter dispatch by Action.OpenSpotlight (#29259)
* refactor(room search): replace `focus_room_filter` dispatch by `Action.OpenSpotlight`

* test(LoggedInView): add test to Ctrl+k shortcut
2025-02-13 15:18:41 +00:00
R Midhun Suresh
03a5ee1c5b New Room List: Create new labs flag (#29239)
* Create new labs flag

* Render empty room list view

* Reload on flag change

* Rename RoomList.tsx to LegacyRoomList.tsx

and rename NewRoomListView.tsx to RoomListView.tsx

* Update labs.md
2025-02-12 12:14:18 +00:00
David Baker
53c97dfa50 Don't reload roomview on offline connectivity check (#29243)
* Don't reload roomview on offline connectivity check

Doesn't look like this was a regression as far as I can see, but
you did have to switch rooms while offline for it to start happening.

There's no use reloading the room until we're online again.

Fixes https://github.com/element-hq/element-web/issues/29072

* Add regression test

* Move it down the file to avoid changing the snapshots
2025-02-11 20:34:32 +00:00
renovate[bot]
4a381c2a10 Update all non-major dependencies (#29194)
* Update all non-major dependencies

* Delint

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Prettier

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

---------

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>
2025-02-05 13:25:06 +00:00
Michael Telatynski
7eb969bbc2 Apply lint rule @typescript-eslint/no-empty-object-type (#29159)
* Apply lint rule @typescript-eslint/no-empty-object-type

To avoid the footgun that is https://www.totaltypescript.com/the-empty-object-type-in-typescript

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

---------

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
2025-02-04 13:41:34 +00:00
Florian Duros
d3ea250d77 Remove call to MatrixClient.setGlobalErrorOnUnknownDevices (#29134)
* refactor(MatrixChat): remove `MatrixClient.setGlobalErrorOnUnknownDevices` call

MatrixClient.setGlobalErrorOnUnknownDevices is not implemented in the rust-crypto and will be removed when the legacy crypto will be ripped out.

* test(e2e): remove `MatrixClient.setGlobalErrorOnUnknownDevices` call

MatrixClient.setGlobalErrorOnUnknownDevices is not implemented in the rust-crypto and will be removed when the legacy crypto will be ripped out.
2025-01-29 17:24:44 +00:00
Robin
c453d33456 Make themed widgets reflect the effective theme (#28342)
* Make themed widgets reflect the effective theme

So that widgets such as Element Call will show up in the right theme even if the app is set to match the system theme.

* Remove debug log line
2025-01-28 10:53:35 +00:00
R Midhun Suresh
f29ce94dd4 Style room header icons and facepile for toggled state (#28968)
* Fix tiny typo in existing code

* Create a hook that uses the right panel store

So that we track changes to the right panel phases

* Create a context that wraps the previous hook we created

We do this so that we can get by using a single event listener i.e we
only need to call `useCurrentPhase` in the provider as opposed to
calling it in each header icon.

* Create a hook that tells you if a panel is open or not

* Create component that wraps Icon

and adds a class name when the corresponding panel is open

* Style room header icons for when they are toggled

* Style face pile for toggle state

* Fix broken CI

* Give directory a better name

* Update year in license

* Use a stronger type
2025-01-27 15:05:46 +00:00
R Midhun Suresh
95da3834f2 Move threads header below base card header (#28969)
* Move threads header below base card header

* Fix jest tests
2025-01-27 11:10:25 +00:00
Michael Telatynski
ef1597ff2d Enable react-compiler eslint to spot antipatterns (#28652)
* Switch to React18 useId

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Enable react-compiler eslint

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Fix an easy one

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Disable in tests

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Fix usage of useRef as memoization

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Fix mutation of external values in hooks

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Make React compiler happy about some frankly non-issues

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Fix MapMock

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Revert MemberListViewModel.tsx changes and disable linter per line

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Make viewmodel compatible with react-compiler linter

- Remove searchQuery ref/state and instead pass this query to the
  loadMember function.
- Now we no longer need a separate search function

---------

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
Co-authored-by: R Midhun Suresh <hi@midhun.dev>
2025-01-16 12:26:00 +00:00
Michael Telatynski
e5ca7954c8 Refactor LegacyCallHandler event emitter to use TypedEventEmitter (#29008)
* Switch LegacyCallHandler over to TypedEventEmitter and use emits to notify consumers of protocol support updates

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Add test for dialpad

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

---------

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
2025-01-16 10:44:20 +00:00
Michael Telatynski
60f70b93e0 Remove FTUE onboarding as it is incompatible with SSO/OIDC (#28943)
* Remove FTUE onboarding as it is incompatible with SSO/OIDC

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Update tests

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Remove stale screenshots

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

---------

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
2025-01-14 13:35:20 +00:00
R Midhun Suresh
ebef0d353e Implement new memberlist design with MVVM architecture (#28874)
* Add new e2e icon for the member tile

* Add new presence icon for member tile

* Implement new member tile

* Implement memberlist view model

* Implement new memberlist header view

* Support the new memberlist in Diasambiguated profile

1. Use MemberInfo instead of RoomMember
2. CSS changes to reflect the new design

* Implement new memberlist view

* Add and use a new overflow component

We used the EntityTile component as a pretend overflow tile in some
places. This new lighter component is added so  that we can remove the
complex EntityTile component.

* Remove old code

* Add/remove css files from _components.pcss

* Increase minimum width as per design

* Actually use the new memberlist view

* Fix broken jest tests

* Add jest tests

* Playwright: Make it possible to disable presence

* Add playwright tests

* Fix lint error

* Undo translation changes that must be done via localazy

* Update license header

* Use waitFor instead of setTimeout

* Remove comment

* Switch over from template to container hs

* Revert unintended change

* Move config to top level
2025-01-08 17:15:06 +00:00
David Langley
69ee8fd96a Change License: AGPL + Element Commercial (#28856)
* Add commercial licence and update config files

* Update license in headers

* Revert "Update license in headers"

This reverts commit 7ed7949485.

* Update only spdx id

* Remove LicenseRef- from package.json

LicenseRef- no longer allowed in npm v3 package.json
This fixes the warning in the logs and failing build check.
2025-01-06 11:18:54 +00:00
Michael Telatynski
1e42f28a69 Harden Settings using mapped types (#28775)
* Harden Settings using mapped types

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Fix issues found during hardening

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Remove oidc native flow stale key

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

---------

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
2024-12-23 20:25:15 +00:00
Michael Telatynski
db02f26005 Delabs native OIDC support (#28615)
Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
2024-12-20 13:13:41 +00:00
Michael Telatynski
be181d2c79 Use mapped types around account data events (#28752)
* Use mapped types around account data events

---------

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
2024-12-19 22:53:51 +00:00
Michael Telatynski
cd7cf86b96 Remove AccountPasswordStore and related flows (#28750)
* Remove AccountPasswordStore and related flows

As they are no longer needed since MSC3967

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Improve coverage

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Update src/CreateCrossSigning.ts

Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>

* Update comment

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

---------

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>
2024-12-19 11:55:05 +00:00
David Baker
b330de5d6e Factor out crypto setup process into a store (#28675)
* Factor out crypto setup process into a store

To make components pure and avoid react 18 dev mode problems due
to components making requests when mounted.

* fix test

* test for the store

* Add comment
2024-12-11 13:10:27 +00:00
Michael Telatynski
01304439ee Make tsc faster again (#28678)
* Stash initial work to bring TSC from over 6 mins to under 1 minute

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Stabilise types

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Fix incorrect props to AccessibleButton

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Swap AccessibleButton element types to match the props they provide

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Changed my mind, remove spurious previously ignored props

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Update snapshots

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

---------

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
2024-12-06 17:49:32 +00:00
David Baker
c659afa8db Rename CreateCrossSigningDialog to InitialCryptoSetupDialog (#28658)
* Rename CreateCrossSigningDialog to InitialCryptoSetup

because it will soon encompass things other than just creating cross
signing.

* Fix name & tests

* Fix import

* Remove code creating key backup

Because this was split out from my key backup by default PR

* Fix comment

* Convert to named export
2024-12-06 10:26:26 +00:00
Florian Duros
dbdb23f6bc Notify to resize the timeline when the pinned message banner is displayed or hidden (#28654) 2024-12-05 16:11:40 +00:00
Michael Telatynski
00aadf1580 Merge pull request #28538 from element-hq/t3chguy/fix/20721 2024-12-02 11:23:18 +00:00
Michael Telatynski
d8ebc68aa8 Remove abandoned Voice Broadcasts labs flag (#28548)
* Remove abandoned Voice Broadcasts labs flag

Any existing voice broadcasts will be shown as a series of voice messages which will sequence play as normal

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Remove dead code

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Update snapshots

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

---------

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
2024-12-02 10:53:27 +00:00
Michael Telatynski
b87437d439 Improve performance of RoomContext in RoomHeader (#28574)
* Improve performance of RoomContext in RoomHeader

This allows a component to subscribe to only part of the RoomContext so they do not need to re-render on every single change

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Update tests

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Prettier

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Add comment

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

---------

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
2024-12-02 09:49:52 +00:00
renovate[bot]
418f121f96 Update all non-major dependencies (#28556)
* Update all non-major dependencies

* Prettier

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

---------

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>
2024-12-02 09:39:36 +00:00
Michael Telatynski
351774d3e3 Merge branch 'develop' into t3chguy/fix/20721 2024-12-02 09:22:51 +00:00
Florian Duros
6798239aa8 Check room encryption earlier (#28579) 2024-11-27 15:22:45 +00:00
Michael Telatynski
1bee3becfb Merge branch 'develop' of https://github.com/vector-im/element-web into t3chguy/fix/20721 2024-11-27 14:53:20 +00:00
Michael Telatynski
3dbcb5efa3 Merge branch 'develop' of https://github.com/vector-im/element-web into dbkr/stateafter
# Conflicts:
#	test/unit-tests/components/structures/RoomView-test.tsx
#	test/unit-tests/components/structures/TimelinePanel-test.tsx
2024-11-27 10:47:35 +00:00
Florian Duros
af846f8be9 Replace MatrixClient.isRoomEncrypted by MatrixClient.CryptoApi.isEncryptionEnabledInRoom in RoomView (#28278)
* Replace `MatrixClient.isRoomEncrypted` by `MatrixClient.CryptoApi.isEncryptionEnabledInRoom` in RoomView

* Add `isRoomEncrypted` to room

* Update e2eStatus and urlPreview when isRoomEncrypted is computed

* Fix e2e test

* Add tests when user verification change

* Reduced abusive timeout in e2e test
2024-11-26 21:34:32 +00:00
Michael Telatynski
de820e11fc Remove Twemoji SBIX font in favour of COLRv0 (#28549)
* Remove Twemoji SBIX font in favour of COLRv0

as it is supported everywhere we need it

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Remove unused mock

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

---------

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
2024-11-26 14:20:15 +00:00
Michael Telatynski
3f221891f7 Remove space-specific right panel store handling
This is no longer needed as the right panel always corresponds to the currently viewed room/space only.

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
2024-11-25 17:29:32 +00:00
Florian Duros
ede91bf921 Use CryptoApi.getKeyBackupInfo instead of deprecated MatrixClient.getKeyBackupVersion (#28450)
* Use `CryptoApi.getKeyBackupInfo` instead of deprecated `MatrixClient.getKeyBackupVersion`

* Review changes

---------

Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>
2024-11-25 09:30:42 +00:00
Michael Telatynski
95630f525f Remove usage of legacyRoot in RTL tests (#28485)
* Remove usage of legacyRoot in RTL tests

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

---------

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
2024-11-20 18:09:51 +00:00
Michael Telatynski
ca33d9165a Migrate to React 18 createRoot API (#28256)
* Migrate to React 18 createRoot API

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Discard changes to src/components/views/settings/devices/DeviceDetails.tsx

* Iterate

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Attempt to stabilise test

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* legacyRoot?

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Fix tests

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Improve coverage

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Update snapshots

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Improve coverage

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

---------

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
2024-11-20 13:29:23 +00:00