- Don't access member that's not there
- Use NeoChatRoomMember instead of RoomMember
BUG: 492733
(cherry picked from commit 2a5359e73b)
Co-authored-by: Tobias Fella <fella@posteo.de>
Previously this would be undefined and i18n doesn't handle this very
well
(cherry picked from commit fad4e506bc)
Co-authored-by: Carl Schwan <carl@carlschwan.eu>
Since the room window is fullscreen on mobile and you can't see the room list,
the first thing you'll be doing is backing out so you can choose the actual room you want to see
(cherry picked from commit 17da652152)
Co-authored-by: Bart Ribbers <bribbers@disroot.org>
Before this commit, NeoChat has two methods of detecting whether or not a piece
of text was an emoji. One is through a regex, and the other is by using the ICU
library. The two methods are used in different parts of the code.
This commit removes the regex detector and instead uses ICU for all the places
where NeoChat needs to figure out whether or not a string is an emoji. This
fixes increasing the font size for messages that only consist of emoji when
certain emoji are used that the regex did not handle (such as the transgender
symbol and transgender flag emojis).
(cherry picked from commit f7533a454c)
This is hardcoded, but it's probably a safe assumption to think most
people running modern NeoChat are using Plasma 6 anyway.
(cherry picked from commit aa116a35f5)
The OSM plugin has a different zoom tolerance than what we're hardcoding
here. This fixes the map looking funky from being too zoomed while
trying to fit multiple location points at once.
(cherry picked from commit 15d6287995)
It's not immediately obvious that you can press on this static text to
bring up the user's details. This isn't a problem with the avatar - for
example - because it has a pointing hand cursor. Let's do the same here.
(cherry picked from commit 0ccfe7d991)
This has insets on it - probably from qqc2-desktop-style - and makes it
look extremely bad when scrolling through messages as the background
size doesn't match. Now the insets are set to zero, except for topInset.
This is done to work around a visual bug where you can see a one-pixel
line right above the SectionDelegate when scrolling.
(cherry picked from commit ab5585cd06)
There's a brief moment during startup where the model knows about the rooms, but their state
is not loaded, which makes them show up in the room list with ugly fallback titles.
To prevent this, we delay closing the welcome page until the basestate is loaded.
(cherry picked from commit bd1d4289c0)
Amends bc67033c00 and e0c3a1c143
No idea why this isn't caught by CI, but it fails for me otherwise.
Signed-off-by: Andreas Sturmlechner <asturm@gentoo.org>
(cherry picked from commit 22743b6d8b)
Constructing the timezone string is relatively heavy and is done for each delegate, even when the tooltip is never shown
(cherry picked from commit 42cec7d5ba)
The intention is that NeochatRoomMember can be created passed to QML and then be fully managed by it. It effectively just grabs the current RoomMember, calls the correct function then discards it so that we don't end up trying to access an already deleted state event.
(cherry picked from commit 11fd4f88ec)
a2a8ad09 Create NeochatRoomMember as a shim for RoomMember so it can be safely passed to QML
0867eef5 Fix showAuthor
0f72ccd0 Mamange the creation of NeochatRoomMembers and only create one per member rather than event.
dba88fe2 REmove getAuthor as no longer needed
4e3a61d1 Update include
32d4d9f7 Pass NeochatRoomMembers rather than RoomMembers to menus
8e4b2034 Don't leak memory
c2f2bb26 Fix code component regression.
5aee89be Make sure the sender Id is intialised properly for pending events
c10c2677 Tweak intialisation
b3146034 Make sure event objects are created for new pending events
e4fab6d9 Pass an empty NeochatRoomMember when not in the map
Co-authored-by: James Graham <james.h.graham@protonmail.com>
This is yet more stuff broken due to referencing a implicit pageStack
that no longer exists.
(cherry picked from commit cb8ed02e82)
Co-authored-by: Joshua Goins <josh@redstrate.com>
These really don't need to be persistent, as they even stick around
when NeoChat is closed. This also spams the user's notification system
usually, if they get lots of invitations at once which don't go away
automatically.
(cherry picked from commit 51197d7c1a)
Matrix currently has a significant moderation loophole, thanks to
invites. Right now, anyone can invite anyone to a room - and clients
like NeoChat will gladly display these rooms to them and even give you
a notification.
However, this creates a pretty easy attack since room names and avatars
are arbitrary and this is a known vector of harassment in the Matrix
community. There's currently no tools to block this server-side, so
let's try to improve the situation where we can.
This adds a new setting to the Security page, wherein it allows you to
block invites from people you don't share a room with. This prevents the
notification from appearing and NeoChat will attempt to leave the room
immediately.
Since this depends on MSC 2666 - a currently unstable feature - the
server may not support it and NeoChat will disable the setting in this
case.
(cherry picked from commit 07fee30cc0)
Sometimes a ghost notification will appear, this is sometimes a stray
m.room.invite notification we didn't handle or some other event. Let's
outright reject all notifications from Invite-type rooms to prevent this
from happening altogether.
(cherry picked from commit 83c6ce0ace)
Update the user model so it also sorts by power level and update how we initialize the model to improve performance.
The following is also changed:
- Store a single `UserListModel` in `RoomManager` and use it for everything, this means we don't create extra models (incluiding the long initialisation for each in big rooms)
- By using the single model once it has loaded the users of the new room opening and closing the draw now happens instantly (previously the model would have to be loaded every time the drawer was opened).
- To stop the initial loading and room change of Neochat slowing down (as the `UserListModel` would be loaded before the `TimelineView` is shown) the initialisation of the model is delayed until the `TimelineView` has loaded. This prioritises showing some messages in the timeline over populating the model so in large rooms the user list will initially be blank, but this keeps the initial load snappier.
Create a list model for read markers. The primary reason is to stop `RoomMembers` being accessed after their state event is deleted. With this the read marker doesn't pass and `RoomMember` objects to qml.
- move the logic for remembering local filenames from
messagecontentmodel to neochatroom
- use it also when maximized and in context menu opening, to stop
re-downloading
- make onFileTransferCompleted signal connection one-shot (stops memory
leak)
- fix them vanishing after "opening" a file (they get downloaded to
/tmp/ without extension, which caused them to lose preview)
- make all text/plain mimetype files preview
- don't show them in Replies (in consistency with media components)
- Fix size and duration not showing in MimeComponents in replies
- Display Itinerary in replies as MimeComponent (in consistency with media
components)
Make sure that the Author in the content model is only ever updated int he following circumstacnes:
- The member updates their displayname or avatar
- A previously hidden author line is shown
This is done by only doing a full reset on initialisation or when a previously hidden author is shown. The rest of the time we only reset the other content in the message, i.e. everything below the author line.
Fix the InlineMessages for the room upgrades in RoomSettings, they should show even if we aren't currently in the room. Resolve resource can join the predecessor/sucessor if required.
Closesnetwork/neochat#618
Use plain items instead of FormCard delegate items, this isn't a FormCard
Set placeholder text for textfield
Remove redundant subtitle
Use inlinemessage for errors
Before:
{width=405 height=247}
After:
{width=404 height=234}
- NeoChat stores pointer to event
- Event is replaced
- libQuotient deletes the event and notifies us that the event changes
- We're accessing the event to check its id
- Boom
Make this not boom by accessing the ID that we're additionally storing anyway.
Use new KirigamiAddons ConfigurationsView as a replacement for
CategorizedSettings. Fix some issues on desktop when running Qt 6.8
and some less recent issues on mobile.
Visually this looks the same.
Depends on https://github.com/quotient-im/libQuotient/pull/695
Currently basic just to show a working implementation using RoomMember. Currently only the room event and search models are moved over. Will change everything else over once the dependent pr is complete.
Note this technically won't build for now because of the lack of RoomMember support but I'll push that at the quotient-next branch next.
This is needed as well to get a branch that builds on dev.
The shortcut needs to work when there is no Global Menu, so it's also in QuickSwitcher.qml.
It can't be in both places, since that breaks it. So we remove it here.
BUG: 488212
- Refactor and cleanup code
- Don't paginate through notifications - it spams the server with requests and realistically only contains anything relevant on startup after a long time, in which case you're going to lose some notification anyway
- Only show newest notification for the respective room, closing the old notification if one exists
- Only show text of this notification
BUG: 475228
Some of our search pages (such as the room and user search) has a list
header item. Due to how this works, it's not actually a part of the
list view keyboard navigation and a whole separate item. So in the tab
order, it comes *after* the list view which makes no sense. And it's
part of the list view, so users must expect it to be selectable with the
up and down arrows like other items.
This simple change makes it so it behaves as expected. The first actual
list item is selected by default, but it's possible to navigate to the
list header item via the up arrow key and then return to the list view
using the down arrow. The list header item is also removed from the tab
order and the whole page is much nicer to use now.
One of them didn't even have a tooltip, which is a simple oversight
since it already has accessible text. The tooltips now use the attached
property instead of creating a new QQC2.ToolTip too.
Some of the items were able to activated via the keyboard, but many were
not like the notifications and "create a space" buttons. This is because
the signals were hooked up to onClicked but the accessible and keyboard
nav were hooked up to onSelected. All of the buttons trigger their
actions with onSelected now.
This was previously not keyboard navigable at all, making it
impossible to switch servers in this dialog solely with a keyboard. This
patch makes it possible to do some basic selection but not deletion yet,
but it's a good start.
Previously it was possible to keep clicking and highlighting each member
which doesn't make any sense. We could make this exclusive by having it
highlight only when index == currentIndex, but honestly it doesn't need
to be highlighted at all. Clicking on a room member opens their user
card, there's no persistent state the user needs to keep track of here.
There are 2 main reason for doing this:
1. Because I can, I wanted to see if I could do it
2. It gets rid of the janky qml re parenting stuff so should be faster.
Add a model for managing permissions (power levels) in rooms. This gets rid of a whole bunch of boiler plate in NeoChat and as a bonus makes it easy to add a feature to allow setting the permission level for any event.
Improve the behaviour of jump to last unread message. The view will now jump as high as possible if the last unread message isn't loaded. This at least triggers more items to load which will eventually get the user to the last unread message.
Sometimes this part of the code causes segfault for me.
I don't know what the root cause is though, it's *very* random. I guess the tagToken should always be long enough, but sometimes it's just one character.
This reverts commit fa57db8e83, because it
caused the last message you replied to to be shown as a reply in every
subsequent message you send, but they're only visible to people using
clients that aren't NeoChat, so you don't immediately realize that
you're causing pandemonium in your chatrooms.
This matches previous behavior before
e2eb6ab33c and including the markdown
blockquote breaks edits. This also adds a test to ensure it does indeed
get stripped.
Right now they use the standard text but left and right arrow icons,
which is a bit odd, and I think fails to convey what will happen when
clicked especially whern the drawer is closed.
Instead, let's use descriptive tooltip text for both, and a descriptive
icon for the the "this will open the drawer" handle button. For the one
to close the drawer, the default icon seems better, so let's stop
overriding it.
I know hamburger menus sometimes aren't amazing, but the current icon is
misleading. It's a plus button which generally means "create new".
However the menu is full of actions not related to creating new things,
including:
- Explore Rooms
- Find your Friends
- Scan a QR Code
These actions may technically result in a new room appearing in the
sidebar, but that's not a user's definition of creating a new thing;
these are *joining* a thing, and the fact that a new entry appears in
the sidebar is an implementation detail.
As a result the existing icon is inaccurate, and also holds back the
menu from adding additional items in the future that are even less
related to creating new rooms. An example would be the quick room
switcher, which is not exposed visibly in the UI anywhere, and could not
logically live in the current menu without changing its icon and text.
A category won't be shown if there are no relevant IDs (will add the ability to add new ones later).
Part of network/neochat#565

- Have LinkPreviewers stored in NeoChatConnection so that they don't have to be reloaded everytime the MessageContentModel is refreshed
- This means the link is never changed (it will be swiched for a new previewer with the new link)
- LinkPreviewers are stored by URL so they can be re-used by any event with the same URL
BUG: 484927 (because the offending code is ripped out)
This draws heavily on what @carlschwan did in network/neochat!1579 but I found it easier to start again and grab the bits as I needed them plus some other copying from what I did in the Space tree model.
From my current limited testing this seems to work nicely try and break it.
Shutup qt about below
```
SortFilterRoomListModel is neither a QObject, nor default- and copy-constructible, nor uncreatable. You should not use it as a QML type.
SortFilterRoomTreeModel is neither a QObject, nor default- and copy-constructible, nor uncreatable. You should not use it as a QML type.
SortFilterSpaceListModel is neither a QObject, nor default- and copy-constructible, nor uncreatable. You should not use it as a QML type.
```
Move the various room models into RoomManager. This means the same room models are always used and is a base from which further logic can be moved from QML to cpp.
Fixes#645
- Active space handling is moved from QML to RoomManager
- Active tab in SpaceDrawer (space / no space / DM) is unified in a single variable
- RoomList & RoomPage loading is simplified: We're always pushing a RoomPage now; if there is no room, a placeholder is shown
- SpaceHomePage is moved into RoomPage; This replaces the entire push/replace room/spacehome logic
- If the current room is a space, the space home is shown, otherwise the timeline
- The concept of "previous room" is removed entirely. If we're leaving the active room, the placeholder room page is shown
- When clicking on a space in the list, the space room list is switched and the space home page is shown
In short, these changes should (after some initial regressions) lead to a less crashy NeoChat :)
Make sure that messages are not marked as read when going back to the roomlist after entering a room when neochat is thin and only showing a single page
Fixes#642
At its best, this worked ok-ish, though it was always missing basic features.
It's also a massive memory leak and significantly complicates the codebase.
(Which is not yet cleaned up by this commit)
Currently, it is entirely broken and noone noticed or cared enough to report or fix that.
BUG: 455984
When curtain user is spamming a lot of messages in a short amount
of time, mod need to scroll all the way up to the first spam message to
know who send those spam message, thus start banning them.
This patch add a context menu to open the sender detail dialog, it could
make banning the spam user and batch-deleting spam messages easier.
Make sure that the neochat can handle switching connection when the current one is logged out. This is mostly about using QPointer to handle use after free issues due to room objects being deleted.
Steal the look of itinerary items from itinerary but simplified. Also includes new support for flights and restaurants

This adds previews for downloaded pdfs and code files.


UCHAR_EMOJI_PRESENTATION is replaced with UCHAR_EMOJI, which seems to be more useful for decting emojis.
The lambda is also turned into a proper function as there's no apparent reason for it to be a lambda.
Many URLs we see in the KDE rooms end with a question mark, without a
space. The linkify regex for plain URLs incorrectly considered them as
part of the link, which usually breaks them when opened in a web
browser. Now the regex excludes these, unless they are accompanied by
another character (so links like kde.org/realurl?is=true will still
work.)
Move the itinerary model representation to it's own component and instantiate from MessageComponentModel. This starts to lay some groundwork for previewing other files.
These share the same D-Bus service name (org.kde.neochat) which comes
with a fun little addition: KRunner activation! While this is not a
problem while NeoChat is running - since it's already registered - this
becomes an issue while searching for NeoChat in something like the
Kickoff. The Kickoff (and consequently, KRunner) tries to activate the
NeoChat D-Bus service which runs our unified push parts.
This introduces a "FakeRunner" which watches closely for calls to the
KRunner interface while we're in unified push mode (or directly called
from D-Bus but not running) so it quits immediately.
KStatusNotifierItem automatically does this for us
since we associate our window with it
Doing it again causes the window to be toggled again, which means
it won't be shown
BUG: 479721
BUG: 482779
Stop space hierarchy being duplicated. This is done by making sure old jobs are cleared at all resets and to make doubly sure when a child is inserted it overrides itself so there can never be duplicates
Make sure that the new rules for counting notifications for muted, mention and low priority rooms is applied consistently to the room list, space drawer and the task manager notification badge
implements #644
Change the LastActivity sort order to Activity and update to a more flexible way of sorting based on an order from model roles.
Add options to actually switch between Alphabetical and Activity
Based on some old work by @tdfischer
implements #103
The aim is to be able to use separate delegate for things like codeblocks and quotes so that they can be styled differently.

Currently the ability to reply in threads was added but not the ability to actually view threads so this doesn't currently make much sense to just have enabled int he main build.
Note: I want to cherrypick this so it's just the flag. I'll add a feature flag page to dev tools for master soon.
Currently, this is only to pause playback of other media when something new starts playing.
In the future, it will also be used for other things, like call ringing, etc.
This is the first step in separation, so we can focus more on the
actions in this menu, and it's not tangled up in how the context menu is
shown and displayed.
This handles the following non-functioning cases from the space saving mr:
- Selecting home or friends
- Switching space that has the same room selected
For now everything should look identical. However this moves to using a model for the content of the message and is intended to lay the foundation for improved message content representation, e.g. splitting up a text message in multiple sections and using different delegates for things like code and quotes.
According to the HIG, scrolling should be kept to a minimum on settings
dialogs. The default window size for the dialog is too small on desktop,
and usually needs to be resized to prevent scrolling.
- When click on a space the space home page is shown, unless the current room is also a member of the new space
- When changing to friends or global the first is entered
- The global now only contains rooms that are not part of a space
- Global is now home
Get rid of the anchors and move to layouts for th bubble and avatars.
This allows the timestamp to be fixed in compact mode so it always sits on the far right. It's also just now more compact than before.

Make the user search automatically. This includes a timer to ensure that we aren't constantly pinging the server as the user types, the search is started 0.5s after the user stops typing. The `PublicRoomListModel` is upgraded to work in the same manner as it was architected slightly differently.
Add the ability to search in the user directory for friends.
This adds an option in roomlist when on the friends tab and opens a search dialog when clicked. The new search model searches the user directory for the given filter term.
Pull the generic aspects from Room search and join room pages into it's own component. This is done in anticipation of using the new generic search page for a user search functionality.
- `SearchPage` is now used for the generic version with the old one being renamed `RoomSearchPage`
- `JoinRoomPage` is renamed to `ExploreRoomsPage` inline with everywhere else in NeoChat
There is also some cleanup of the code for both search pages in here.
Make sure that message delegates are getting the room object directly rather than requiring the assumption that currentRoom is declared somewhere higher up.
Update the UX to refer to structure direct chats as friends. The direct chats are pulled into their own tab in the space drawer.
The `UserDetailDialog` is also updated to check whether a direct chat already exists and if not ask to invite as friend.

Since this means that the space drawer can no longer be hidden when there are no spaces,
also make it less empty by adding a button for creating new spaces.
More things will come in the future.
BUG: 479051
After downloading a file, the model calls the extractor and uses the
JSON to show some basic information about the content and allows to import
the data to Itinerary. This is entirely runtime-optional; no build-time dependencies
are required and nothing changes if the extractor isn't available.
Directly calling signals is the supported way to send signals.
Calling signal handlers worked in the past, but will be phased out in
the future (https://bugreports.qt.io/browse/QTBUG-120573).
Refactor `LinkPreviewer` to take an event and put the functions for getting the link in the class itself. This means the functions in `EventHandler` are no longer required.
This mr also sets up `LinkPreviewer` so that it is automatically updated when an event is edited. This includes changing the link if edited, and it can handle a message having a previous link removed or a one added when one didn't exist before.
Also adds test suite.
Currently we effectively create the reactions list in EventHandler then pass that data into a model. This reworks the model so that we just pass in a room and an event and it grabs it's own data. This means that:
- the functions in event handler are no longer required
- the model can update itself to add/remove reactions so no need to handle that in MessageEventModel
- MessageEventModel only needs to create new ReactionModels or remove old ones when no reactions exist anymore
A basic test suite has also been created for the ReactionModel
Refactor PollHandler to make it more reliable. This ended up with much more code than I expected as the original intent was just to stop a crash when switching rooms.
- Using a event string was flaky, changing to using an event reference is more reliable.
- Since we're only creating them from NeoChatRoom there is no need to to be able to set properties from QML so only read properties.
- Pass from the MessageEventModel rather than an invokable method.
- Create a basic test suite
- Create properties in PollHandler to remove the need to use content in PollDelegate, this means content is no longer a required role.
The fixes include:
- improving the timer to make it more reliable
- making sure a read marker is added when changin rooms, this is needed when the messages have already been loaded.
- increase the default timer to 10s to avoid the read marker disappearing and being re-added when a message arrive in quick succession.
BUG: 465300
Cleanup leftover issues from moving ReplyComponent away from GridLayout.
- Remove leftover GridLayout properties or references to them or convert as required
- Remove unneeded Item wrapper
Erroneous activations of the D-Bus service could cause the daemon to be
launched without any messageReceived signals being called (which then
hooks up the notifications to quit the app.) Now there's a five-second
timeout to prevent it from living too long.
I don't think it possible to open settings without an account connected anymore, however just to make sure I've made sure that a nullptr connection is handled in `AccountEmoticonsModel`.
BUG: 478024
Make sure that custom emojis in inline code blocks are not turned into images.
By calling preprocess text in `texthandler` the whole function can be simplified as it will now never be called on any text inside any code block (which was the reason for all the split stuff previously).
BUG: 477512
This will cause the name to show up more often than necessary, but that's better than not showing it at all, which leads to messages being attributed to the wrong person.
The root cause here is a mismatch in event visibility between EventStatus::Hidden and filterAcceptsRow in MessageFilterModel, which will be fixed in a future patch.
Stop the console being pinged with qrc:/org/kde/neochat/qml/MessageEditComponent.qml:158: TypeError: Cannot read property 'isEditing' of undefined.
Fixesnetwork/neochat#629
Currently trying to scroll with this scrollbar is probablematic and it's
unlikely we will find an easy solution to fix it, so make it non interactible.
This adds a dedicated "set up for push notifications only" function in
Controller, which only sets up the KUnifiedPush connector for receiving
the message and then quitting right afterward. If the user tries to
open a notification, then it will quit and open the main client.
Add the ability to set and show suggested rooms for spaces.
This is just adding the basic functionality, we can do more things with it later like sort/filter the space home for example.
- Don't use card for welcome message and instead use same layout as
kwordquiz
- Add separator between login and register button
- Add type annotation in functions
If the last active connection is not reachable (server down, keychain problems,
token revoked, etc.), NeoChat currently fails to load at all, with the only fix
being to delete a line from the config file. This is surprisingly hard to fix with
a nice UX as long as we stick to the principle of loading the user's last active
connection automatically.
This patch thus drops that principle; instead, the user is always asked to choose
the connection to continue with.
This was only set for the Controller, but it needed to be set for the
RoomManager too before opening a room. This could cause NeoChat to crash
when activating a notification, for example.
We aren't using thr Qt5 version anymore, and it's not really a point in
describing which exact Qt version we use with libQuotient in a user
facing string like this anyway.
Create a mobile version of explore component and place it at the bottom for single handed use. This also refactors the UserInfo component so it can be at the top on mobile as well as the bottom on dektop.
This should have no effect on desktop and should be identical.

Fix opening a room in a new window. This is done by makeing the model top level parameters in RoomPage set from RoomManager but overwritten by RoomWindow
This MR deals with only sending threaded messages. Showing threads will turn up in a follow up. This allows you to start a new thread by clicking reply in thread to a normal message.
You can also do a threaded reply to a threaded message in the main timeline at the moment because those messages aren't shown in a separate thread timeline yet but will be in future.
This function will automatically create a "neochatstarerc" for us, and
KConfig will decide the best place for us to place our state. It won't
always be in AppDataLocation.
Move the functionality to cache the contents of a chat bar from the room directly and to a new ChatCache object. This works pretty much the same with a few extra check and balances, this also made it easy to put a test suite around the functionality so I did. The current functionality should be identical to what exists.
This is in prep for threads which will require managing even more caches if we create one per thread.
- Don't show a dot over profile pictures.
The dot was intended to be part of the Avatar when there is no image and the Avatar is too small to show an icon.
Currently, it is visible over the profile picture. If we still want the dot, it should be upstreamed
- Fix avatar images in StateComponent
So the original space parent and child stuff was technically a bit naughty in that it allowed multiple rooms to be set as the canonical parent. Because while a room can have multiple parents only one should be canonical. This adds the following:
- When adding a child or parent there is an extra check to select if the new parent should be canonical
- Any parent can be selected as the canonical one from the room settings
- All functions ensure that there is only ever one canonical parent by ensuring all others are false when a new one is set.
This is an update to searching the public room list. Currently if you can't find the room you're looking for you can type a full alias of room ID into the search bar and a view/join button appears. This is hard to discover and technically broken since it was turned into a generic component for finding rooms (it kinda works but doesn't fit now as it's focussed on the joining rooms not adding new ones to spaces). It is also not very discoverable if you don't know it's there.
This patch patch updates the workflow to be truly generic and hopefully more discoverable. Instead of using the search bar if no results are found a button asking if someone wants to manually enter a room ID or alias appears. This launches a dialog where the user can type in an alias or ID and it has some basic checking to make sure the string looks as expected.
The new functionality also generically works for joining rooms and adding children to spaces.
Add a space homepage with the ability to both create new room and add existing rooms to the space. This uses a tree model for the space hierarchy and will go to any number of levels. The user should only see the add options if they have appropriate permissions.
This MR also combines the create space and room pages and adds a lot of optional functionality for managing space children.

It seems at some point in time the 16x16 tray icon got lost/hastily upscaled to a 22x22 tray icon,
which resulted in proportions as well as icon guidelines being slightly off.
This replaces the tray icon with a new one redrawn to adhere to icon guidelines and proportions closer
to the colour icon.
If you use your private keys (like when deleting the quotient database)
your session is broken as you have differing keys on the server. While
it is possible to work your way out of it, it's better to warn users to
bite the bullet and log in again.
This introduces a new base delegate that handles sizing the content of delegate in the timeline, i.e. it handles all the size helper stuff. This is then used for all the other main delegates:
- messages
- state
- read marker
This means they now all have identical base code to do the sizing (read marker still had legacy code).
Because the new base delegate is called `TimelineDelegate` both `TimelineContainer` and `MessageDelegate` have been renamed:
- MessageDelegate -> TextDelegate - this never made sense before images, videos, etc are all technically messages in Matrix parlance
- TimelineContainer -> MessageDelegate - this has always really been the base for messages
Note - this is mostly groundwork for dealing with the layout polish loop spam which will hopefully be fixed in part 2 with a bubble rework.
Rework the file menu so that it no longer relies on having a reference to the media delegate to manage a download for either opening externally or copying to clipboard. This allows the menus to be moved out of the delegates and maximize components and have them accessed through RoomManager. This reduces duplication and reduces the number of components in an already heavy delegate.
This is a very developer-oriented action, and other uses of this dialog
(such as interacting with room state events under a room debug page) is
also locked behind this option.
The dialog won't show again after being closed first time, so we need
to dynamically destroy it on both accept and reject. It helps clear out
any state on its way.
Change the `JoinRoomPage` so that it emits a `roomSelected` signal with the selected delegate's info instead of calling the functions to join or enter the room itself. This is so that the `JoinRoomPage` can be used for other purposes like selecting an existing child to add to a space.
Restore compact mode using the darker/lighter depending on color scheme background (i.e. the same as the bubble background) it broke somewhere in the refactor of roompage
Make sure that the console isn't spammed having `linkpreviewer` undefined in `LinkPreviewDelegate`, even though it shouldn't ever be and I couldn't find any case where it was but my console was still intermittently getting spammed.
ChatBar animated its implicit height, and there is no way for us to
force it animating on integer values only. It is contained in a Layout
type, and QtQuick.Layouts are known to round up size of their items and
position them on an integer scale. All in all, is caused bottom of chat
bar (action icons row and the whole bottom edge) to flicker during
height animation.
Similar to text handler, pull out the disparate array of functions which format information from an event ready for display in the UI and put in a handler class with a test suite.
requires https://github.com/quotient-im/libQuotient/pull/686
Add a tab bar to the room drawer which includes a new media tab in addition to the room information tab. This mr completes the architecture for adding others easily later e.g. message highlights or threads.
To put this together I had to make sure things like the menus and the maximize delegate were available to both the room drawer and page so there is some rework there to put it all together.
Wide\

Mobile\

Add handling for new default push rules added in 1.7 also add a generic unknown handling for if any others are added in the future so they don't appear in keywords
Previously, some functions that conceptually belong to the connection needed to be in the Controller, since we didn't have a place to put them.
This fixes that by extending the Connection class in a similar way as we extend the Room class.
Merge the functionality of CollapseStateProxyModel into MessageFilterModel there is no need for a whole separate model the filters can be combined trivialy.
Push the room drawer as a page rather than a drawer when on mobile or the window is thin.
This also lays some foundations for having multiple different pages in the drawer by separating the room information into it's own component which could be switched out to show other things like highlights or media.
Add a timer to lockout the scroll trigger for marking messages as read in the first second after changing room. This is because the scrollview can't differentiate between mouse scrolling and the multiple changes in scrollview that happen as the room is changed over.
Instead of using translated custom values (which are not accepted by
AppStream validation) this adds the Windows-specific screenshots as
normal screenshots with custom attribute x-kde-os="windows". AppStream
validation accepts custom attributes (in fact, it ignores any attributes
other than "type").
Upstream appstream tooling will treat those screenshots as any other
extra screenshots (screenshots without type="default").
This fixes two minor inconveniences:
- When closing the chat window and re-showing it from the systray icon, the geometry was not properly restored. The window was always shown in the middle of the screen. Now, one gets the window back with it's actual last position and size.
- It is now possible to not only show the window from the systray icon, but also to close it. This is the way other chat programs do it (Kopete back in the day, Konversation, Quassel IRC etc.)
Make sure that the image container has it's implicit width/height set so that the correct size can always be calculated. This was breaking images that were a reply to another message (not sure if that's legal because we don't allow but other clients do because I found one).
In some cases (where we don't get a thumbnail) we load the entire image,
which might be large. Even when we get a thumbnail, the smoothing we
apply doesn't get the best results and the only other option is
mipmapping which is more memory intensive - it stores progressively
smaller images but keeps all of them in memory.
Now the ImageDelegate sets the sourceSize, which helps reduce the memory
footprint (since Qt will throw away whatever parts of the image we don't
need) and makes the images look smoother when scaled. However,
AnimatedImages do not support this so this change introduces a new
property to tell if the image could possibly be animated. It will
erroneously pick up formats that could support animation (e.g. WebP) but
other image formats will still benefit so it's a net positive. The
ImageDelegate will load the correct image component depending on this
property.
When auto-completing rooms, there may be some that do not have
canonical addresses (e.g. 1-to-1 chats). These can't be linked anyway,
so skip them and any other unlinkable entries.
The correct render hint is actually SmoothPixmapTransform, as
Antialiasing only matters for primitives. Also, render a white
background for potentially transparent avatars.
Hide the emoji button in the `chatbar` and don't instantiate the dialog component on mobile. This isn't needed on mobile as the virtual keyboard can add emojis. Should also save a small amount of memory on mobile from the dialog which is normally always instantiated.
Fix it so that the view is correctly positioned at the bottom when the room is changed and make sure this is not seen as a scroll event (i.e. messages are not automatically marked as read but the timer has to time out first and all visible on screen).
Avatars are shown rounded in the main interface, so they should look the
same in the notification tray too. On top of that, if the room is a
group then show that group's icon when applicable in the bottom right.
It's not obvious at first glance that you can click on the avatar in the
account editor to upload an image. This adds a new button when there is
no image uploaded.
- Split the list into sections for "this devices", "verified devices", "unverified devices", and "devices without encryption support"
- Sort the lists by last activity
Add missing #pragma once + missing include
* speeds up incremental builds as changes to a header will not always
need the full mocs_compilation.cpp for all the target's headers rebuild,
while having a moc file sourced into a source file only adds minor
extra costs, due to small own code and the used headers usually
already covered by the source file, being for the same class/struct
* seems to not slow down clean builds, due to empty mocs_compilation.cpp
resulting in those quickly processed, while the minor extra cost of the
sourced moc files does not outweigh that in summary.
Measured times actually improved by some percent points.
(ideally CMake would just skip empty mocs_compilation.cpp & its object
file one day)
* enables compiler to see all methods of a class in same compilation unit
to do some sanity checks
* potentially more inlining in general, due to more in the compilation unit
* allows to keep using more forward declarations in the header, as with the
moc code being sourced into the cpp file there definitions can be ensured
and often are already for the needs of the normal class methods
This is a significant rework of the handling of push rules. Rather than using a lot of boilerplate code for the default models `KeywordNotificationModel` has been converted to `PushRuleModel` and now handles all push rules.
The new model has the following features:
- Handles all push rules
- Has special handling for the names of default keywords (i.e. it still gives the same text as previously for showing in the settings menus)
- Push rules for blocking individuals or room overrides are still there but hidden so will be available for developer tools (to follow)
- Room specific keywords are now supported.
The notification settings pages have also been refactored to take advantage of the new models. Each section is now just a repeater with a filter for the rules that it should contain. The push rule delegate has now been cleaned up and uses required properties.
Implements network/neochat#574
The sidebar grew a lot and now contains some tools. This makes the space
left for the room members very small. Particuliary on mobile.
So make the whole sidebar contained inside the ScrollView
This also refactor a few things (e.g. use a plain ToolBar for the header)
Create a media model for all the media message in the timeline and then setup `NeoChatMaximizeComponent` so that it can use the media model to scroll through all loaded images and video in the current room.
Depends upon libraries/kirigami-addons!105
FEATURE: 467411
This fixes APKs on binary factory having exploded in size 3x-5x after
the Qt 5.15.10 update. This also affects release packages and will need
to be backported to those (in Craft).
This is an interim solution until AppStream (hopefully) gets support
for platform-specific screenshots. The captions will be extracted for
translation.
We don't need to use a ToolBar for the titleDelegate since the
titleDelegate is already included inside a toolbar. This work magically
when using the default font size of 10px Noto Sans but breaks with 11px
BUG: 467242
Just loading that plugin already triggers an HTTP request, so lets only
do that when really needed and even more importantly, not for every single
location delegate again.
data() being called with an invalid model index seems to happen during
normal operations here, with something in the proxy model chain not
catching that case (due to a row being filtered out presumably?).
This check worked for accounts that already had custom emojis, but if it
never had any added, m_images was never filled and the model would crash
when adding more.
The aim is to put some additional filtering in place to better stop floods of old notifications. This is achieved with a couple of new filters and better tracking of old notifications.
- Make sure to paginate through all notification on initialization to ensure they are all added to old notifications. While we were not previously putting a limit on the number of returned notifications the server can and will do this when there are a very large amount.
- Find the newest timestamp for each connection on initialization and don't post any notifications with an earlier timestamp.
- Track old notifications on a per-connection basis.
Closesnetwork/neochat#358 and network/neochat#423
Create a cpp helper class to calculate the correct delegate width given it's parent width.
This is designed to be more robust and hopefully easier to understand than the current mass of javascript calcs.
BUG: 470167
Still coming from Spectral, where they were taken from Quaternion, where they were dropped because they don't work as expected.
Also, soon to be removed from libQuotient itself.
Always use `NeoChatRoom::getUser` for getting user details in a room context.
- `MessageEventModel` now calls `getUser`
- `getUser` is now overloaded to also be able to take a `NeoChatUser*`
- add params to `getUser` that are needed for the model outputs
Restore the functionality to edit or reply to the last message in the `chatbar`.
This is achieved be moving the functions `getLastLocalUserMessageEventId` and `getLatestMessageFromRow` to `NeoChatRoom` as `editLastMessage` and `replyLastMessage` as `chatbar` no longer has access to `messageEventModel`.
The functions are also simplified as they only need to find the `eventId` and always from row 0 as this was the only use of the functions.
BUG: 469733
Make sure that the `updateNotificationState` function is called when the base state is loaded so that new rooms after startup have a valid notification state.
Fixesnetwork/neochat#583
We can't (easily) make this declarative, since there are no spaces on startup, causing the loader to be disabled,
making the repeater not load anything, which means the loader stays disabled.
We should figure out a better solution, since this means that the drawer doesn't open immediately when joining a space,
but for now this fix is better then the current bug.
Create a reaction model that provides all the required data for `ReactionDelegate` so that none need to be calculated in QML.
This also cleans up the API for `ReactionDelegate`
Instead of issuing a new notification for every message, bundle them by
room.
It looks like the code was originally designed to do that and somehow we
forgot along the way.
It also fixes the leaking in m_notifications as we were never cleaning
after it.
What happens is roughly: The notification is received in one account and marked as received locally.
In the other account, the event is marked as "read" in the json, which makes us delete it from the
received messages. Then it is received on the first account...
Limit the maximum number of avatars shown for other user read markers and collapsed state events
For state events \

For read markers \

Restore part of the contents previously introduced by
cc21f8cca9 which was partially
lost, probably due to an extra '>' outside the tags
which confused the translation system.
Credits for the text, see the original commit (Carl Schwan).
Unread count is deprecated and notification count should be used in all cases. As such remove unreadCount and use notification count in all places it was being used.
Fixesnetwork/neochat#76 \
BUG: 466515
Update README.md ensuring that info is up to date.
The following has been changed:
- Updated about info (intro, features)
- Reference KDE standard docs for building, MRs, etc
This move the finding of links and the creation of a `linkpreviewer` into c++.
- The links are now extracted from the text in `texthandler`
- The `messageeventmodel` now creates and stores `linkpreviewers` for events that have links in the current room.
Two new model roles have been created to let a text delegate know when the link preview should be shown (`showLinkPreview`) and pass the link previewer (`linkPreviewer`). Empty link previewer are returned where link don't exist so the qml doesn't have to have checks for whether the parameters are undefined.
Further improvements to the handling of `mediaInfo` in `messageeventmodel`.
`blurhash` and `thumbnailInfo` are now replaced with a single `tempInfo` object that contains a single temp source. The priority is thumbnail > `blurhash` > empty if none exist.
Fixesnetwork/neochat#235
Create a `messageeventmodel` role for media info and reply media info that is a QMap with all the required data.
This replaces the MediaUrlRole, FileMimeTypeRole and the ContentTypeRole. The reply role no longer needs the content role.
This also ensures mxc urls are now generated for replies. All the media parameters will now have default values assigned in the model so the QML no longer needs to do this.
- Update the message event and user models so that the full source url is output.
- Separate the reply author into its own role
- Create an empty user object that can be passed so that the QML code no longer needs to check if certain parameters exist.
- Make avatarForMember return and empty QUrl if a valid avatar cannot be found and make use in the user and event models
As well as cleaning up the QML this should also stop the QML Image: Media id '' doesn't follow server/mediaId pattern spam in the log.
- Update the conatainsUser function to use memberState so that invites do not show up as being in the leave state.
- Update the InviteUser page to use Kirigami.BasicListItem and make the invite button remain visible but be untoggleable when the if user has already been invited.
closesnetwork/neochat#202
- Now has tabs setup as more features are added
- First extra tab has basic server info
- Use mobileform to make it look nicer
- For the room data tab allow the room to be changed from within devtools
- For the room data tab allow m.room.member events to be filtered out so other event types can be found easily
- For the room data tab allow viewing room account data
network/neochat#557
Document and cleanup userlist model.
- Remove unneeded enum UserTypes
- Cleanup includes and remove need to include QPointer
- make clear that it is a user or users that are being refreshed
Note: breaks libquotient 0.6 compatibility because of the changes to how m_currentRoom is handled
Update the message role to be named plainText and use it the message delegate for openMessageContext.
This removes the need for plainText in controller so it is removed.
Aborting the request causes a lot of logged messages. In theory, not stopping the job causes some overhead,
but that's negligible and the provider is on its way out anyway.
Use new kirigami-addons MaximizeImage.qml to replace local FullScreenImage.qml
depends upon libraries/kirigami-addons!88
TODO
- [x] Remove the old `fullscreenimage.qml` before merging as no longer needed
Implements #571
There will be some case, like the notify is still exist, but user have
logout their account, user leave the room, these cause the room become a
nullptr, and when click the notify message, it make neochat coredump
Also modernize the codebase where possible (e.g use required properties,
reorder properties, fix warnings, don't use Action when not needed)
Signed-off-by: Carl Schwan <carl@carlschwan.eu>
This MR goes over text and cleans it up to be more unifying. Mostly just lowercasing words in non-titles, but it also changes the "show fancy effects" text to be clearer with its meaning.
It also fixes the room access being printed in the room settings: 
I'd like to do a second pass later with another MR to unify triple dots (...) and ellipsis (…)
Add documentation to NeochatRoom and reorganise the functions in the header file in a more logical order.
For Q_PROPERTIES the documentation is on the property not the functions it calls as seems to be the convention elsewhere.
Use kirigami to set the proper link and error color for mentions and error underlining in chatbox
This is with my own colorscheme:

Change location marker to GPS icon, make sure the point is the anchor and colour it with highlight colour
m.self \

m.pin \

When a local message is edited make sure that the initial message that will be merged remains hidden so it doesn't flash up then disappear.
closesnetwork/neochat#314
Make return/enter create a newline on mobile. This is the traditional behaviour in other messengers as the send icon and return have are the same time to access and solves the linked issue.
Closesnetwork/neochat#466
Rework the filtering of state events in the timeline and for lastevent. This is now consistent everywhere and includes the following:
- The timeline settings are obeyed everywhere
- A new setting is added to filter all state events
- Last event obeys the timeline setting in all cases
- The roomlist will show a state event as the latest event if it's visible in the timeline
- Names are no longer hyperlinked in eventToString if plaintext is selected.
BUG: 455048\
Closesnetwork/neochat#148
- Add the ability to set the deafult url preview setting for the room if you have sufficient power level.
- Add the ability for the user to set the desired url preview setting.
network/neochat#560
Improve the handling of text both when sending and receiving.
The main feature is to fix the linked bug (and a host of others that are unreported but similar) which is caused by the fact that we don't properly clean html. This mr does that as per the matrix spec https://spec.matrix.org/v1.5/client-server-api/#mroommessage-msgtypes. So any disallowed tags or attributes are removed and it does the special handling for certain attributes.
Additionally the functions are also designed to cover any other text formatting required, particularly fro received strings.
The receive side is covered by 2 functions `handleRecieveRichText` and `handleRecievePlainText`. The rich/plain in the function name refers to the output type not the input type (both can take plain and rich input), so `handleRecieveRichText` is called to get a string suitable to go in a rich text control and `handleRecievePlainText` for a plain control.
The functions also handle the following some of which was previously handled by `eventToString` in `NeoChatRoom`:
- Strip and reply from the string
- Format any user mentions
- Linkify links in plain strings
- Handle mxc urls in rich text (uses the new `room->makeMediaUrl` functionality from libQuotient)
- `handleRecievePlainText` also deals with markup making `NeoChatRoom->subtitle` redundant
There is also an extensive test suite which defines the behaviour and the best way to review this is probably to look at the tests and decide whether you agree with the expected output given the inputs and/or if there is any missing behaviour.
The final aim especially with the test suite is to give us a framework to make further updates in the future easier and hopefully prevent a new feature breaking old behaviour with the tests.
BUG: 463932 \
BUG: 466330 \
BUG: 466930
Add the option to set powerlevel to userdetaildialog.
This is done by making the powerleveldialog into it's own file and using that.
implements network/neochat#570
- Move the room list drag handler and logic to RoomList.qml.
- Make the compact mode logic not rely on a saved width value from Config as this was causing the room list to have large icons the first launch after a recent update.
- Instead save the compact mode state and initialise the width based upon that.
Remove the global menu and move explore and new chat/room buttons to new `ExploreComponent.qml`.
This is designed to sit in the header of the `RoomListPage` and will only be visible when the room list is. The other settings have just been removed as they are covered by the `UserInfo` component and quick can be done form the decoration or system tray.
When wide\

Collapsed mode\

This feature doesn't work very well at the moment, but that's not an
excuse not to have a keyboard shortcut for it. As usual, it's the same
shortcut as many other chat clients use.
Since commit eee93e0f1, the ChatBar has a conflicting shortcut that
takes precedence even when it doesn't do anything, so that the Escape
shortcut of RoomPage is never actually invoked any more.
Fix this by using Keys.onShortcutOverride() instead in ChatBar and
accepting the event only when it actually cancelled something. So if
you're writing a reply, the first time pressing Escape cancels the reply
and the second one calls the RoomPage shortcut that goes to the
RoomListPage.
This is the same key combination as commonly used by other chat clients
such as Element, Slack and Discord. For consistency, also add the same
Alt+Up/Down shortcut as used in thes other clients as aliases for
switching rooms without considering the unread status.
This is a key combination that doesn't seem to be used either in NeoChat
nor with a common meaning in other chat clients, so let's use it for
switching the user.
This allows to use the room switching shortcuts like Ctrl+PgUp/PgDn even
when the RoomPage doesn't currently have the focus. It's also a nice
code simplification.
If you're on the first visible room and try to switch to the previous
one (or on the last visible room switching to the next one), the first
(or last) room in the list is incorrectly selected even if it's not
currently visible.
Fix this by not first entering each room and then checking whether it is
the one we really wanted, but iterating until we find a room that we
want and only entering it then.
- Make sure the connection to the room's chatBoxEditIdChanged signal is made so that the edit box gets filled.
- Make sure the minimum height and preferred width are available to the loader so they can be set and dynamically updated.
BUG: 465934
Before this change, Ctrl+PgUp/PgDown didn't select the next room, but
actually moved two rooms at once because the signal handler was called
twice. I'm not entirely sure why this happens (it might be a bug in a
lower layer?), but as we don't want to handle the same event elsewhere,
accepting the event doesn't feel wrong and it appears to fix the issue.
So let's just do that.
BUG: 459997
Update linkpreviewer to minimise the number of resizes.
- There is now a placeholder loading element to hold space while the data is obtained
- The component starts with a set size but can be expanded to see the whole item.
- The expand/contract button is only visible on hover
- The default size is picked to show 3 lines of text (1 heading and 2 description, 2 heading and 1 description, etc)
This is designed to help with the timeline scroll jumping CCBUG: 463235 by minimizing the amount of resizing for items in the timeline.
Before

After when compressed

After When expanded

After Loading

Implement folding sections for multiple consecutive state events. This also reworks some of the aggregated text output:
- Only new days cause a new section
- The aggregated text starts with either a single username or n users
- If the same user did the same action mutltiple times it will be in the aggregated text a user did x n times
- When there are multiple authors in a block with multiple state event types it will use or rather than and before the last event. e.g 3 user left the room or joined the room.
Folded

Unfolded

Implements network/neochat#90
This is mostly a stylistic rework of the chatbar but there are some buxfixes / improvements in here as well. The aim was to make the chatbar so it's size was managed in the same manner as the timeline in both bubble and compactmode in the same manner as network/neochat!476.
The other features are:
- Replies, attachments and edits now look like they are inside the chatbar and use a similar styling to edits in message bubbles
- Replies and edits now part of the message so they arte part of the ScrollView and will scroll away when the text is long
- ~~The emoji picker is now a popup so it doesn't mess with the timeline layout when activated~~ (done in network/neochat!697)
- ~~Emoji dialog is now no longer required as the picker itself is a popup now~~ (no longer the case see above)
- The scrollbar now sits on the right of the chatbar actions rather than weirdly to the left
- The action icons will always stay in the same place even as the chatbar gets taller
Updated\

Scrollbar behaviour before

Scrollbar behaviour after

This patch fixes two key issues:
* `?` is considered part of the URL, even if there might not be anything past it. I've seen people now putting spaces after URLs to get around this issue.
* `)` is also part of the URL, as well as `:` despite those not being valid characters at the end of URLs.
When sending an image as an attachment, the message you type into the
chat box becomes its caption. However, it's not clear when in the chat
box itself, which confusingly says you're typing a message.
This should fix the binary factory build, but it unfortunately not backward
compatible below Qt 5.15.8. Qt 6 will need the same changes anyway, so it's
not all bad at least.
Separate the setting for globally setting push rules on/off from the configuration to decide whether desktop popup notifications are sent.
The current master setting is pulling double duty and should probably be separate as some people may want to see notification counts in Neochat but don't want to see popup notifications on their desktop.
Change the userlist model so that permission names are based upon the following power level convention:
- 0: member
- 50: moderator
- 100: admin
- other: custom
This is inline with the new permission room page. Follow on from network/neochat!712
- Handle notifications from all accounts not just the active one.
- When a notification from the non-active account is clicked the active account is changed over to enter the correct room.
network/neochat#121
Back when testing !745, i was using `kdesrc-run` and this bug slipped through my fingers: It began to create folder named after the file inside the home (or in this case, kdesrc-run home) folder.
This fixes that. Now the clipboard image files go correctly to `~/.cache/KDE/screenshots/` folder.
Anyhow, my bad, should've done more print debugging.. 😓
This patch moves the invite option to header of members section. We also check if user can send invitation event and we won't show the invite button if it's not allowed.
This patch also added an toggle button to show the member search bar since it won't needed by the user in most of the cases.
Before this patch, the `ssoUrlChanged` signal might emitted before the URL actually get changed. This patch ensure the signal emitted at the correct place, and also disable the Login button before `LoginHelper` done its work.
To test this change, you can simply enter `@a:mozilla.org` (or whatever the account name is) and attempt to login it by click "continue". Then click the "Login" button and see if the first click can let your browser open the SSO login URL.
Work to add the ability to set user power levels and modify the power levels required for certain actions.
Updated

Fix Crtl + F not working by only having the shortcut assigned to a single searchfield.
- Ctrl + F is now for the roomlist search
- The user search in the room drawer is now ctrl + shift + f
- for the emoji picker and qucik switcher these have the shortcut removed and focus is managed by the popup.
BUG: 462524
While it's not *that* useful since we cannot view all the rooms under the space, it can be useful to view all members inside a Space, and invite people to the Space.
- Fix the headers in icons only mode.
- Allow section collapsing
- Show scrollbar when needed
[2022-12-12_19-06-46.mkv](/uploads/e1633058b2b4a24ef7b6144bf5392b9c/2022-12-12_19-06-46.mkv)
BUG: 462576
Improve the initial resizing of an image in the timeline by always looking to see whether sourcesize or image.info is populated first.
This allows the actual size of the image to be calculated as soon as possible while still maintaining the fix fo CCBUG: 460205
May also help CCBUG: 463235 I need help testing this it currently no longer happens for me.
change check to `messageListView.sectionBannerItem != undefined` so that the command line isn't spammed with qrc:/RoomPage.qml:263:13: Unable to assign [undefined] to bool
Otherwise we start loading QML before we attach to an existing instance
Not only is this wasteful but it also breaks raising the existing window on X11 since showing a window clears the startup id
Also make sure that ability to add a keyword or change the global notiifcaiton state is disabled without an active connection as these will cause the same crash.
The CI system already provides these so it doesn't have any effect there, but this allows to generate correct dependency data for kdesrc-build from .kde-ci.yml
* Use Kirigami.Units.gridUnit * 2.5 for normal emoji
* Use Kirigami.Units.gridUnit * 3 for custom emoji
* Add small background padding to delegate
* Add rounded hover effect
Signed-off-by: Carl Schwan <carl@carlschwan.eu>
This converts the emoji dialog in the chatbar to be the same popup as for reactions. This includes:
- EmojiPicker and ReactionPicker were already similar and are made identical, as such ReactionPicker no longer needed
- Emoji dialog used for both reactions and chatbar emojis
- Add some parameters to allow for different use cases (include custom emojis and whether selection closes the popup)

Set the focus to the chatbar after clicking the jump up/down buttons so that they don't stay highlighted.
Also remove messageListView.headerItem.height as part of the down button margin calc as it no longer exists
BUG: 456075
I've made few possible fixes for the typing notification getting stuck for long periods of time.
I could use some help testing these to see if they help others too.
For me the typing notification doesn't linger around that long after these changes.
Change the condition for RoomDrawer handle visibility to pageStack.visibleItems.length > 1 rather than wideMode so that it is always visible when the window is wide enough to have 2 pages shown.
BUG: 455976

This could be helpful for some working use-case: When user want to mute a channel temporary and want to un-mute it later, the icon could help user know the mute status at a glance so they won't forget to un-mute the channel.
This icon will only be shown if the channel is muted, and have no unread message and the item is not hovered, so it won't get in the way when user have unread messages.
Add setting for setting the history visibility.
Note this setting can only be read not set for Quotient version < 0.7 as there is no event definition for a history visibility state event and it doesn't seem worth creating one when not needed with Quotient 0.7.
BUG: 457840
There were some inconsistencies in capitalization and colons, so those were fixed in this MR.
I also rearranged some settings in the appearance section to improve the grouping.
- Update from deprecated readMarkerEventId to lastFullyReadEventId for quotient 0.7.
- Removed duplicate code for marking read from the read marker delegate.
- Make sure that mark as read only trigger at the end of the timeline
- Allow the read marker to be highlighted when jumped to
Make sure that the emote name is added inside the first paragraph rather than as an additional one.
Note alternate to network/neochat!632 because I didn'y realise @tfella had done a patch
CCBUG: 461837
Move the typing indicator out of the listView header so it doesn't resize the view when appearing and disappearing causing all messages to be marked as read
BUG: 457666
Numerous refinements to the new mobileform setting pages
- Ensure left and right padding at the top level is 0 for mobile
- Centre align the avatar in the account editor page and add tooltip to button
- Fix the bubble/compact mode setting so that it fits when thin, i.e on mobile
- Fix the loading placeholder in device settings
As description, also note that the edit device name is now an inline element rather than an overlay.
Normal

Editing Name

Ensure that in the small number of cases where the room page up down buttons overlap messages due to the screen being thin that they are always on top
BUG: 461718
This add the final list of settings in the main setting window as a new page notifications as there are quite a few now. This completes previous work on push rules giving the ability to set the default global rules. Adding keyword rules is also now supported.
This also uses the new mobileform layout. The settings are designed to give some visual feedback as options for whether notifications are on/off, play a sound or are highlighted are chosen. The left icon is designed to mimic the notification dot in the roomlist. The whole mobileform delegate can also be clicked to cycle through the available options.
The rationale for whether an option is available is as follows:
- Highlight is not available if would lead to every message in a room being highlighted
- Keyword notifications cannot be switched off instead the rule is just deleted
- Only keyword rules can be deleted, default rules cannot be touched
There is also rules plumbed in for features that don't exist in neochat yet, i.e. encrypted chats and rooms, calls. I figured I may as well plumb these in and test them my plan was to hide them before merge, they can then be unhidden when the features are complete.

For yet unknown reasons, sometimes invalid mentions are inserted into the list, which will mess up all further messages. While finding those bugs is the better approach, these checks should also be useful.
Resolve https://invent.kde.org/network/neochat/-/issues/547
This patch attempts to add proxy config support to NeoChat so people could set a HTTP or Socks5 proxy for anonymity or privacy/censorship-circumvention reason.
Currently this will only allows setting proxy type, host and port (which should be usable for most of the cases). Settings in that page needs to be applied by clicking the Apply button so the proxy setting won't accidentally get changed.
Proxy is disabled (use System Default option) by default.
Use animated images in imageDelegate and FullScreenImage so that animated images can be viewed.
Note webp animated images don't work this is a bug with qt see https://bugreports.qt.io/browse/QTBUG-70245
Update the base item in the timeline container to be a column layout. This means that all the items can be laid out automatically without the need to set lots of manual settings and anchoring.
The overall height calculation for the delegate is vastly simplified (in fact it is removed) which deals with the fact that there were still instances where the manual calculation didn't work e.g. a delegate with a reaction followed by another message from the same user didn't give the correct bottom margin (see below)
before:

after:

This also improves upon the recently changed hover highlight behaviour. The previous patched moved it to cover the avatar as well as the bubble however it also covered the section and reaction when present which didn't look good. The highlight now only covers the avatar and bubble
before:

after:

This also cleans up some of the margins in both bubble and compact to ensure consistency.
Set max size to gridUnits * 30. The aim is to allow them to be generally bigger than bubble mode but not so huge that they take up the entire screen
BUG: 454878
**Updated**
Add a section label at the top which shows the date label of the next section up. This means that the user will always be able to see the date of all messages on screen.

From the feedback given I've added a background at the top. I also added an underline to the heading which applies both at the top and in the listView since they use the same component. I added it originally for the top because I felt it looked a bit weird having messages appear from behind a heading background the same colour as the listView background.
Note: I know the gaps between messages are not right. I had to set the spacing in the listView to 0 to prevent itemAt returning null. I plan to add it back in as part of the delegate code before it would be merge.
Fixes BUG:454880
Initial work to create a model so that new servers can be added to the list.
The model will also check if the server is valid before allowing it to be added.
Implements network/neochat#11
### TODO
- [x] Add functionality to cache added servers
Replace the RowLayout with a ComboBox. This permits a higher number
of accounts to be used in the application without reducing the
usability.
BUG: 460601
Stop stripping paragraph tags as this is causing line breaks to be removed in the formatted body. Any double new line in the plain text is treated as a paragraph in rich text.
BUG: 458800
The time label now appears below the duration slider when very thin.
Remove unnecessary padding from the audio inner object, including deleting the outer control which added padding but little else.
Ensure that user choice is given precedent for opening/closing the room drawer.
This makes it so that the previous state is restored after one of the menu pages is closed or if the window is dragged thin then wide again.
Fixesnetwork/neochat#196
The aim here is to tidy up the reply component and make it so it sizes automatically without any need to manually set widths or heights. This is achieved by putting the layout in a grid layout. The implicitwidth and height variables are also simplified meaning that the margins are no longer prone to being slightly off because the calculation didn't add up the margins and spacing right.
Also added here is a mime component which is used to provide a nicer representation for files, videos and audio in the reply because trying to put the full component in wouldn't look good.
This also fixes the situation in right to left mode where the layout now mirror properly and everything sits where it should.
New reply elements

This is the start of a significant refactoring of everything related to sending messages, which is roughly:
- the chatbox
- action handling
- message sending on the c++ side
- autocompletion of users/rooms/emojis/commands/things i forgot
Notable changes so far include:
- ChatBox is now a ColumnLayout. As part of this, i removed the height animations for now. <del>as far as i can tell, they were broken anyway.</del> I'll readd them later
- Actions were refactored to live outside of the message sending function and are now each an object; it's mostly a wrapper around a function that is executed when the action is invoked
- Everything that used to live in ChatBoxHelper is now in NeoChatRoom; that means that the exact input status (text, message being replied to, message being edited, attachment) is now saved between room switching).
- To edit/reply an event, set `NeoChatRoom::chatBox{edit,reply}Id` to the desired event id, `NeoChatRoom::chatBox{reply,edit}{User,Message}` will then be updated automatically
- Attachments behave equivalently with `NeoChatRoom::chatBoxAttachmentPath`
- Error message reporting from ActionsHandler has been fixed (same fix as in !517) and moved to NeoChatRoom
Broken at the moment:
- [x] Any kind of autocompletion
- [x] Mentions
- [x] Fancy effects
- [x] sed-style edits
- [x] last-user-message edits and replies
- [x] Some of the actions, probably
- [x] Replies from notifications
- [x] Lots of keyboard shortcuts
- [x] Custom emojis
- [x] ChatBox height animations
TODO:
- [x] User / room mentions based on QTextCursors instead of the hack we currently use
- [x] Refactor autocompletion stuff
- [x] ???
- [x] Profit
2022-10-10 23:10:00 +00:00
689 changed files with 286317 additions and 84611 deletions
Creative Commons Attribution-ShareAlike 4.0 International
Creative Commons Corporation (“Creative Commons”) is not a law firm and does not provide legal services or legal advice. Distribution of Creative Commons public licenses does not create a lawyer-client or other relationship. Creative Commons makes its licenses and related information available on an “as-is” basis. Creative Commons gives no warranties regarding its licenses, any material licensed under their terms and conditions, or any related information. Creative Commons disclaims all liability for damages resulting from their use to the fullest extent possible.
Using Creative Commons Public Licenses
Creative Commons public licenses provide a standard set of terms and conditions that creators and other rights holders may use to share original works of authorship and other material subject to copyright and certain other rights specified in the public license below. The following considerations are for informational purposes only, are not exhaustive, and do not form part of our licenses.
Considerations for licensors: Our public licenses are intended for use by those authorized to give the public permission to use material in ways otherwise restricted by copyright and certain other rights. Our licenses are irrevocable. Licensors should read and understand the terms and conditions of the license they choose before applying it. Licensors should also secure all rights necessary before applying our licenses so that the public can reuse the material as expected. Licensors should clearly mark any material not subject to the license. This includes other CC-licensed material, or material used under an exception or limitation to copyright. More considerations for licensors.
Considerations for the public: By using one of our public licenses, a licensor grants the public permission to use the licensed material under specified terms and conditions. If the licensor’s permission is not necessary for any reason–for example, because of any applicable exception or limitation to copyright–then that use is not regulated by the license. Our licenses grant only permissions under copyright and certain other rights that a licensor has authority to grant. Use of the licensed material may still be restricted for other reasons, including because others have copyright or other rights in the material. A licensor may make special requests, such as asking that all changes be marked or described.
Although not required by our licenses, you are encouraged to respect those requests where reasonable. More considerations for the public.
Creative Commons Attribution-ShareAlike 4.0 International Public License
By exercising the Licensed Rights (defined below), You accept and agree to be bound by the terms and conditions of this Creative Commons Attribution-ShareAlike 4.0 International Public License ("Public License"). To the extent this Public License may be interpreted as a contract, You are granted the Licensed Rights in consideration of Your acceptance of these terms and conditions, and the Licensor grants You such rights in consideration of benefits the Licensor receives from making the Licensed Material available under these terms and conditions.
Section 1 – Definitions.
a. Adapted Material means material subject to Copyright and Similar Rights that is derived from or based upon the Licensed Material and in which the Licensed Material is translated, altered, arranged, transformed, or otherwise modified in a manner requiring permission under the Copyright and Similar Rights held by the Licensor. For purposes of this Public License, where the Licensed Material is a musical work, performance, or sound recording, Adapted Material is always produced where the Licensed Material is synched in timed relation with a moving image.
b. Adapter's License means the license You apply to Your Copyright and Similar Rights in Your contributions to Adapted Material in accordance with the terms and conditions of this Public License.
c. BY-SA Compatible License means a license listed at creativecommons.org/compatiblelicenses, approved by Creative Commons as essentially the equivalent of this Public License.
d. Copyright and Similar Rights means copyright and/or similar rights closely related to copyright including, without limitation, performance, broadcast, sound recording, and Sui Generis Database Rights, without regard to how the rights are labeled or categorized. For purposes of this Public License, the rights specified in Section 2(b)(1)-(2) are not Copyright and Similar Rights.
e. Effective Technological Measures means those measures that, in the absence of proper authority, may not be circumvented under laws fulfilling obligations under Article 11 of the WIPO Copyright Treaty adopted on December 20, 1996, and/or similar international agreements.
f. Exceptions and Limitations means fair use, fair dealing, and/or any other exception or limitation to Copyright and Similar Rights that applies to Your use of the Licensed Material.
g. License Elements means the license attributes listed in the name of a Creative Commons Public License. The License Elements of this Public License are Attribution and ShareAlike.
h. Licensed Material means the artistic or literary work, database, or other material to which the Licensor applied this Public License.
i. Licensed Rights means the rights granted to You subject to the terms and conditions of this Public License, which are limited to all Copyright and Similar Rights that apply to Your use of the Licensed Material and that the Licensor has authority to license.
j. Licensor means the individual(s) or entity(ies) granting rights under this Public License.
k. Share means to provide material to the public by any means or process that requires permission under the Licensed Rights, such as reproduction, public display, public performance, distribution, dissemination, communication, or importation, and to make material available to the public including in ways that members of the public may access the material from a place and at a time individually chosen by them.
l. Sui Generis Database Rights means rights other than copyright resulting from Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, as amended and/or succeeded, as well as other essentially equivalent rights anywhere in the world.
m. You means the individual or entity exercising the Licensed Rights under this Public License. Your has a corresponding meaning.
Section 2 – Scope.
a. License grant.
1. Subject to the terms and conditions of this Public License, the Licensor hereby grants You a worldwide, royalty-free, non-sublicensable, non-exclusive, irrevocable license to exercise the Licensed Rights in the Licensed Material to:
A. reproduce and Share the Licensed Material, in whole or in part; and
B. produce, reproduce, and Share Adapted Material.
2. Exceptions and Limitations. For the avoidance of doubt, where Exceptions and Limitations apply to Your use, this Public License does not apply, and You do not need to comply with its terms and conditions.
3. Term. The term of this Public License is specified in Section 6(a).
4. Media and formats; technical modifications allowed. The Licensor authorizes You to exercise the Licensed Rights in all media and formats whether now known or hereafter created, and to make technical modifications necessary to do so. The Licensor waives and/or agrees not to assert any right or authority to forbid You from making technical modifications necessary to exercise the Licensed Rights, including technical modifications necessary to circumvent Effective Technological Measures. For purposes of this Public License, simply making modifications authorized by this Section 2(a)(4) never produces Adapted Material.
5. Downstream recipients.
A. Offer from the Licensor – Licensed Material. Every recipient of the Licensed Material automatically receives an offer from the Licensor to exercise the Licensed Rights under the terms and conditions of this Public License.
B. Additional offer from the Licensor – Adapted Material. Every recipient of Adapted Material from You automatically receives an offer from the Licensor to exercise the Licensed Rights in the Adapted Material under the conditions of the Adapter’s License You apply.
C. No downstream restrictions. You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, the Licensed Material if doing so restricts exercise of the Licensed Rights by any recipient of the Licensed Material.
6. No endorsement. Nothing in this Public License constitutes or may be construed as permission to assert or imply that You are, or that Your use of the Licensed Material is, connected with, or sponsored, endorsed, or granted official status by, the Licensor or others designated to receive attribution as provided in Section 3(a)(1)(A)(i).
b. Other rights.
1. Moral rights, such as the right of integrity, are not licensed under this Public License, nor are publicity, privacy, and/or other similar personality rights; however, to the extent possible, the Licensor waives and/or agrees not to assert any such rights held by the Licensor to the limited extent necessary to allow You to exercise the Licensed Rights, but not otherwise.
2. Patent and trademark rights are not licensed under this Public License.
3. To the extent possible, the Licensor waives any right to collect royalties from You for the exercise of the Licensed Rights, whether directly or through a collecting society under any voluntary or waivable statutory or compulsory licensing scheme. In all other cases the Licensor expressly reserves any right to collect such royalties.
Section 3 – License Conditions.
Your exercise of the Licensed Rights is expressly made subject to the following conditions.
a. Attribution.
1. If You Share the Licensed Material (including in modified form), You must:
A. retain the following if it is supplied by the Licensor with the Licensed Material:
i. identification of the creator(s) of the Licensed Material and any others designated to receive attribution, in any reasonable manner requested by the Licensor (including by pseudonym if designated);
ii. a copyright notice;
iii. a notice that refers to this Public License;
iv. a notice that refers to the disclaimer of warranties;
v. a URI or hyperlink to the Licensed Material to the extent reasonably practicable;
B. indicate if You modified the Licensed Material and retain an indication of any previous modifications; and
C. indicate the Licensed Material is licensed under this Public License, and include the text of, or the URI or hyperlink to, this Public License.
2. You may satisfy the conditions in Section 3(a)(1) in any reasonable manner based on the medium, means, and context in which You Share the Licensed Material. For example, it may be reasonable to satisfy the conditions by providing a URI or hyperlink to a resource that includes the required information.
3. If requested by the Licensor, You must remove any of the information required by Section 3(a)(1)(A) to the extent reasonably practicable.
b. ShareAlike.In addition to the conditions in Section 3(a), if You Share Adapted Material You produce, the following conditions also apply.
1. The Adapter’s License You apply must be a Creative Commons license with the same License Elements, this version or later, or a BY-SA Compatible License.
2. You must include the text of, or the URI or hyperlink to, the Adapter's License You apply. You may satisfy this condition in any reasonable manner based on the medium, means, and context in which You Share Adapted Material.
3. You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, Adapted Material that restrict exercise of the rights granted under the Adapter's License You apply.
Section 4 – Sui Generis Database Rights.
Where the Licensed Rights include Sui Generis Database Rights that apply to Your use of the Licensed Material:
a. for the avoidance of doubt, Section 2(a)(1) grants You the right to extract, reuse, reproduce, and Share all or a substantial portion of the contents of the database;
b. if You include all or a substantial portion of the database contents in a database in which You have Sui Generis Database Rights, then the database in which You have Sui Generis Database Rights (but not its individual contents) is Adapted Material, including for purposes of Section 3(b); and
c. You must comply with the conditions in Section 3(a) if You Share all or a substantial portion of the contents of the database.
For the avoidance of doubt, this Section 4 supplements and does not replace Your obligations under this Public License where the Licensed Rights include other Copyright and Similar Rights.
Section 5 – Disclaimer of Warranties and Limitation of Liability.
a. Unless otherwise separately undertaken by the Licensor, to the extent possible, the Licensor offers the Licensed Material as-is and as-available, and makes no representations or warranties of any kind concerning the Licensed Material, whether express, implied, statutory, or other. This includes, without limitation, warranties of title, merchantability, fitness for a particular purpose, non-infringement, absence of latent or other defects, accuracy, or the presence or absence of errors, whether or not known or discoverable. Where disclaimers of warranties are not allowed in full or in part, this disclaimer may not apply to You.
b. To the extent possible, in no event will the Licensor be liable to You on any legal theory (including, without limitation, negligence) or otherwise for any direct, special, indirect, incidental, consequential, punitive, exemplary, or other losses, costs, expenses, or damages arising out of this Public License or use of the Licensed Material, even if the Licensor has been advised of the possibility of such losses, costs, expenses, or damages. Where a limitation of liability is not allowed in full or in part, this limitation may not apply to You.
c. The disclaimer of warranties and limitation of liability provided above shall be interpreted in a manner that, to the extent possible, most closely approximates an absolute disclaimer and waiver of all liability.
Section 6 – Term and Termination.
a. This Public License applies for the term of the Copyright and Similar Rights licensed here. However, if You fail to comply with this Public License, then Your rights under this Public License terminate automatically.
b. Where Your right to use the Licensed Material has terminated under Section 6(a), it reinstates:
1. automatically as of the date the violation is cured, provided it is cured within 30 days of Your discovery of the violation; or
2. upon express reinstatement by the Licensor.
c. For the avoidance of doubt, this Section 6(b) does not affect any right the Licensor may have to seek remedies for Your violations of this Public License.
d. For the avoidance of doubt, the Licensor may also offer the Licensed Material under separate terms or conditions or stop distributing the Licensed Material at any time; however, doing so will not terminate this Public License.
e. Sections 1, 5, 6, 7, and 8 survive termination of this Public License.
Section 7 – Other Terms and Conditions.
a. The Licensor shall not be bound by any additional or different terms or conditions communicated by You unless expressly agreed.
b. Any arrangements, understandings, or agreements regarding the Licensed Material not stated herein are separate from and independent of the terms and conditions of this Public License.
Section 8 – Interpretation.
a. For the avoidance of doubt, this Public License does not, and shall not be interpreted to, reduce, limit, restrict, or impose conditions on any use of the Licensed Material that could lawfully be made without permission under this Public License.
b. To the extent possible, if any provision of this Public License is deemed unenforceable, it shall be automatically reformed to the minimum extent necessary to make it enforceable. If the provision cannot be reformed, it shall be severed from this Public License without affecting the enforceability of the remaining terms and conditions.
c. No term or condition of this Public License will be waived and no failure to comply consented to unless expressly agreed to by the Licensor.
d. Nothing in this Public License constitutes or may be interpreted as a limitation upon, or waiver of, any privileges and immunities that apply to the Licensor or You, including from the legal processes of any jurisdiction or authority.
Creative Commons is not a party to its public licenses. Notwithstanding, Creative Commons may elect to apply one of its public licenses to material it publishes and in those instances will be considered the “Licensor.” Except for the limited purpose of indicating that material is shared under a Creative Commons public license or as otherwise permitted by the Creative Commons policies published at creativecommons.org/policies, Creative Commons does not authorize the use of the trademark “Creative Commons” or any other trademark or logo of Creative Commons without its prior written consent including, without limitation, in connection with any unauthorized modifications to any of its public licenses or any other arrangements, understandings, or agreements concerning use of licensed material. For the avoidance of doubt, this paragraph does not form part of the public licenses.
Creative Commons may be contacted at creativecommons.org.
SPDX-FileCopyrightText: 2023 James Graham <james.h.graham@protonmail.com>
SPDX-License-Identifier: CC0-1.0
-->
# NeoChat
NeoChat is a client for Matrix, the decentralized communication protocol for instant
messaging. It is a fork of Spectral, using KDE frameworks, most notably Kirigami,
KConfig and KI18n.
A Qt/QML based Matrix client.
<a href='https://matrix.org'><img src='https://matrix.org/docs/legacy/made-for-matrix.png' alt='Made for Matrix' height=64 target=_blank /></a>
<a href='https://flathub.org/apps/details/org.kde.neochat'><img width='190px' alt='Download on Flathub' src='https://flathub.org/assets/badges/flathub-badge-i-en.png'/></a>
<a href='https://snapcraft.io/neochat'><img width='190px' alt='Download on the Snap Store' src='https://snapcraft.io/static/images/badges/en/snap-store-black.svg'/></a>
## Introduction
## Get it
NeoChat is a client for [Matrix](https://matrix.org), the decentralized communication protocol for instant
messaging.
A stable release [is available](https://apps.kde.org/neochat) for download for Linux distributions.
Along with the stable release, a Flatpak version is available for the nightly
A nightly build is also available for Android in the [KDE nightly F-Droid repo](https://community.kde.org/Android/FDroid)
and can also directly be downloaded from the [binary factory](https://binary-factory.kde.org/view/Android/job/NeoChat_Nightly_android-arm64/).
Nightly builds for [Windows](https://binary-factory.kde.org/job/NeoChat_Nightly_win64/), [MacOS](https://binary-factory.kde.org/job/NeoChat_Nightly_macos/) and [AppImages](https://binary-factory.kde.org/job/NeoChat_Nightly_appimage/) can also be downloaded from the [binary factory](https://binary-factory.kde.org/search/?q=neochat).
NeoChat is based on KDE frameworks and as [libQuotient](https://github.com/quotient-im/libQuotient), a
Qt-based SDK for the [Matrix Protocol](https://spec.matrix.org/).
* Reply to message (right-click on a message to access menu)
* Start a private chat (but not encrypted)
* Show notifications, for the moment there is only a global switch
to disable it. We plan to implement the configuration part of the
specification soon.
* Autocompletion of usernames in chat
* Emoji picker
* Basic room setting page
* Send and accept invitations
* /rainbow <message> (very important)
* /me <message>
NeoChat aims to be a fully featured application for the Matrix specification. As such most parts of the current specification are supported, with the notable exceptions
of VoIP, threads, and some aspects of End-to-End Encryption. There are a few other smaller omissions due to the fact that the Matrix spec is constantly
evolving, but the aim remains to provide eventual support for the entire spec.
NeoChat is still missing a few features to become a full-featured
Matrix client (most notably encryption support and video chat support).
We welcome contributions in this direction.
Due to the nature of the Matrix specification development NeoChat also supports numerous unstable features. Currently these are:
- Polls - MSC3381
- Sticker Packs - MSC2545
- Location Events - MSC3488
## Get it
Details where to find stable releases for NeoChat can be found on its [homepage](https://apps.kde.org/neochat).
Nightly builds for Linux and Windows can be downloaded from [cdn.kde.org](https://cdn.kde.org/ci-builds/network/neochat/).
Nightly builds for Android are available from [KDE's nightly F-Droid repository](https://community.kde.org/Android/F-Droid).
Nightly Flatpaks are available from [KDE's nightly Flatpak repository](https://userbase.kde.org/Tutorials/Flatpak).
## Building NeoChat
The best way to build KDE apps during development is to use `kdesrc-build`. The full instructions for this can be found on
the KDE community website's get involved section under [development](https://community.kde.org/Get_Involved/development). This
is primarily aimed at Linux development.
For Windows and Android [Craft](https://invent.kde.org/packaging/craft) is the primary choice. There are guides for setting up
development environments for [Windows](https://community.kde.org/Get_Involved/development/Windows) and [Android](https://develop.kde.org/docs/packaging/android/building_applications/).
## Running
Just start the executable in your preferred way - either from the build directory or from the installed location.
## Tests
Tests are in the repository under [autotests](autotests) and [appiumtests](appiumtests).
The project has CI setup to test new commits to the repository. All tests are expected to pass for a merge request to
You can reach the maintainers at [#neochat:kde.org](https://matrix.to/#/#neochat:kde.org), if you are already on Matrix.
Development happens in http://invent.kde.org/network/neochat (not in GitHub).
The best place to reach the maintainers is on the KDE Matrix instance in the NeoChat channel, [#neochat:kde.org](https://go.kde.org/matrix/#/#neochat:kde.org). See [Matrix](https://community.kde.org/Matrix) for more details.
## Acknowledgement
This program utilizes [libQuotient](https://github.com/quotient-im/libQuotient/)
library and some C++ models from [Quaternion](https://github.com/quotient-im/Quaternion/).
NeoChat utilizes [libQuotient](https://github.com/quotient-im/libQuotient/) as its Matrix SDK.
This program is a fork of [Spectral](https://gitlab.com/spectral-im/spectral/).
NeoChat is a fork of [Spectral](https://gitlab.com/spectral-im/spectral/).
"formatted_body":"<b>This is an example<br>text message</b>",
"msgtype":"m.text"
},
"event_id":"$153456789:example.org",
"origin_server_ts":1432735824654,
"room_id":"!jEsUZKDJdhlrceRyVU:example.org",
"sender":"@example:example.org",
"type":"m.room.message",
"unsigned":{
"age":1232
}
},
{
"content":{
"avatar_url":"mxc://kde.org/123456",
"displayname":"after",
"membership":"join"
},
"origin_server_ts":1690651134736,
"sender":"@example:example.org",
"state_key":"@example:example.org",
"type":"m.room.member",
"unsigned":{
"replaces_state":"$1234567890:example.org",
"prev_content":{
"avatar_url":"mxc://kde.org/12345",
"displayname":"before",
"membership":"join"
},
"prev_sender":"@example:example.orgg",
"age":1234
},
"event_id":"$143273583553PhrSn:example.org",
"room_id":"!jEsUZKDJdhlrceRyVU:example.org"
},
{
"content":{
"body":"This is a highlight @bob:kde.org and this is a link https://kde.org",
"format":"org.matrix.custom.html",
"msgtype":"m.text"
},
"event_id":"$1532735824654:example.org",
"origin_server_ts":1532735824654,
"room_id":"!jEsUZKDJdhlrceRyVU:example.org",
"sender":"@example:example.org",
"type":"m.room.message",
"unsigned":{
"age":1233
}
},
{
"content":{
"m.relates_to":{
"event_id":"$153456789:example.org",
"key":"👍",
"rel_type":"m.annotation"
}
},
"origin_server_ts":1690322545182,
"room_id":"!jEsUZKDJdhlrceRyVU:example.org",
"sender":"@alice:matrix.org",
"type":"m.reaction",
"unsigned":{
"age":390159120
},
"event_id":"$163456789:example.org",
"age":390159120
},
{
"age":4926305285,
"content":{
"body":"video caption",
"filename":"video.mp4",
"info":{
"duration":10,
"h":1080,
"mimetype":"video/mp4",
"size":62650636,
"w":1920,
"thumbnail_info":{
"h":450,
"mimetype":"image/jpeg",
"size":382249,
"w":800
},
"thumbnail_url":"mxc://kde.org/2234567"
},
"msgtype":"m.video",
"url":"mxc://kde.org/1234567"
},
"event_id":"$263456789:example.org",
"origin_server_ts":1685793783330,
"room_id":"!jEsUZKDJdhlrceRyVU:example.org",
"sender":"@example:example.org",
"type":"m.room.message",
"unsigned":{
"age":4926305285
},
"user_id":"@example:example.org"
},
{
"content":{
"body":"> <@example:example.org> This is an example\ntext message\n\nreply",
"format":"org.matrix.custom.html",
"formatted_body":"<mx-reply><blockquote><a href=\"https://matrix.to/#/!jEsUZKDJdhlrceRyVU:example.org/$153456789:example.org?via=kde.org&via=matrix.org\">In reply to</a> <a href=\"https://matrix.to/#/@example:example.org\">@example:example.org</a><br><b>This is an example<br>text message</b></blockquote></mx-reply>reply",
"m.relates_to":{
"m.in_reply_to":{
"event_id":"$153456789:example.org"
}
},
"msgtype":"m.text"
},
"origin_server_ts":1690725965572,
"sender":"@alice:matrix.org",
"type":"m.room.message",
"unsigned":{
"age":98
},
"event_id":"$154456789:example.org",
"room_id":"!jEsUZKDJdhlrceRyVU:example.org"
},
{
"content":{
"body":"> <@example:example.org> video caption\n\nreply",
<command>neochat</command> is a chat application for the matrix protocol
that work on both desktop and mobile.
</para>
</refsect1>
<refsect1 id="options"><title>Options</title>
<variablelist>
<varlistentry>
<term><option>URI</option></term>
<listitem>
<para>
The matrix uri for an user or a room. e.g matrix:u/user:example.org and
matrix:r/root:example.org. This will makes NeoChat try to open the given
room or conversation.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1 id="bug">
<title>Reporting bugs</title>
<para>You can report bugs and feature requests at <ulink url="https://bugs.kde.org/enter_bug.cgi?product=NeoChat&component=General">https://bugs.kde.org/enter_bug.cgi?product=NeoChat&component=General</ulink></para>
</refsect1>
<refsect1>
<title>See Also</title>
<simplelist>
<member>
A list of frequently asked questions about Matrix <ulink url="https://matrix.org/faq/">https://matrix.org/faq/</ulink>
<para>License: GNU General Public Version 3 or later <<ulink url="https://www.gnu.org/licenses/gpl-3.0.html">https://www.gnu.org/licenses/gpl-3.0.html</ulink>></para>
//property int lineHeight: contentHeight / lineCount
text:inputFieldText
placeholderText:readOnly?i18n("This room is encrypted. Sending encrypted messages is not yet supported."):editEventId.length>0?i18n("Edit Message"):currentRoom.usesEncryption?i18n("Send an encrypted message…"):i18n("Send a message…")
// Provides container to fill the space that isn't taken up by the top controls and clips the image when zooming makes it larger than the available area.
text+=i18nc("Separate the usernames of users"," and ")
}
}
text+=modelData.authors[i].displayName
}
if(modelData.authors.length>3){
text+=i18ncp("%1 is the number of other users"," and %1 other"," and %1 others",modelData.authors.length-3)
}
text=i18ncp("%2 is the users who reacted and %3 the emoji that was given","%2 reacted with %3","%2 reacted with %3",modelData.authors.length,text,modelData.reaction)
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.