Fixes#2143.
Methuselah is the a task manager for long-running tasks. It allows fo registration of workers that will each run in their own thead. Each worker can pass messages to and recieve messages from the main thread.
MailserverWoker was also introduced which moves all mailserver model logic to a MethuselahWorker. All communication to/from the model is done via a MethuselahTask. Results of the task are returned to the main thread by way of `signal_handler`, which calls the QtObject slot specified in the task.
Mailsever also provides a way for the model to emit events inside of the worker. These events are forwarded to the main thread via the `receiveEvent` slot of the `MailserverController`.
Co-authored-by: Michael Bradley, Jr <michaelsbradleyjr@gmail.com>
When the profile popup is opened inside the contacts list, it doesn't have
a surrounding window context (`Popup` types should usually be used within `ApplicationWindow`
or `Window` components as per https://doc.qt.io/qt-5/qml-qtquick-controls2-popup.html).
This is problematic when popup are nested, like it's the case with the
nickname popup that will be instantiated by the profile popup.
With no window context, such nested popup can't be opened by the application.
This commit ensures the profile popup is created with a proper context,
fixing the issue that the nickname popup won't open when visting via
contacts list.
Fixes#2216
Prior to this commit, we would only set the translation package for the
application's engine when `appSettings.locale !== "en"`.
This is problematic because it seems that `engine` is already provided with
a system default that may not be `en`. In practice, this means that, initially,
engine is loaded with, say `de`. `appSettings.locale` might be `en` but because
we're only loading the correct translation package when it's **not** `en`,
the application will stay in `de`.
Changing the language to `en` at runtime is fine, however once the application
is restarted, `engine` is again initialized with some other possible system default.
It seems that we should *always* load the translation packge when `appSettings` are
loaded.
When contract addresses that are not ERC-20 or ERC-721 were input, the token would be allowed to be added and would crash the app.
In addition, when an ERC-20 contract was deployed without a name and symbol, “Invalid ERC-20 address” would appear.
This PR adds error checking from the token detail lookup and reports the error back to the user in the modal. This prevents non-ERC-20/721 contracts from being able to be added to the app and prevents a crash.
There was a UI bug in the StatusChatInput where, only in the timeline view,
the scrollview wrapping the textarea would have a weird behaviour in which
it would render the visible text(placeholder) *lower* than how it's actually
positioned. Once the textarea is clicked, it would re-adjust with a smooth
scroll.
Obviously this is undesired behaviour as the text should always render in the
correct position.
This commit finally fixes this weird behaviour by moving the dynamic height
calculation to the wrapping Rectangle and changing the textarea's top- and
bottom paddings dynamically.
Fixes#2018
Alright, this is an interesting one:
As described in #1829, when the profile popup is opened within the chat view,
users are still able to click *through* the popup on message, which then puts them in
an active state.
I've done a bunch of debugging as described [here](https://github.com/status-im/status-desktop/issues/1829#issuecomment-804748148) and after doing some
further debugging, I found out that `isMessageActive` isn't really the culprit here.
What causes this effect is the `HoverHandler` that's attached to the `CompactMessage` item.
`HoverHandler` is a standard QML type that emits `hoverChanged` signals so one can do things like
applying hover effects on elements, which is exactly what we do:
```
HoverHandler {
onHoverChanged: {
root.isHovered = hovered // `root` being the message item
}
}
```
I assume we went with this handler because putting a `MouseArea` in there instead, which fills
the entire message component pretty much eliminates all existing mouse handlers attached to
other child components, such as the profile image or the username of the message, which also
open a message context menu.
It turns out that, having a `HoverHandler` as described above, actually activates it when the
user clicks with the left mouse button as well (not just on hover). That's what causes the "click-through"
effect. This can be verified by setting `acceptedButtons` to `Qt.RightButton`, basically telling
the handler that only right clicks will activate it.
I then tried using `Qt.NoButtons` instead so that no button clicks and only hovers will activate
the handler, but that didn't seem to have any effect at all. It still defaults to `Qt.LeftButton`.
So the last resort was to disable the `HoverHandler` altogether, whenever either the profile popup,
or the message context menu (for emojis etc) is open.
Unfortunately, we don't have access to the profile popup in the compact message component, because it's
detached from the component tree. Therefore, I've introduced a new property `profilePopupOpened` on
the chat layout, which we can read from instead.
Fixes#1829
This commit introduces a `reset()` function so that search results inside
the application can be easily reset. It also introduces a `resultClickable`
flag which allows consumers of this component to decide whether a search result
is clickable and emits a dedicated event.
This is useful when UIs should only allow actions via the result icon button
(as it's the case with the new add-to-contact modal).
There were cases in which this component was used and its `checked` state wasn't
properly emitted to the underlying component.
This commit fixes that by ensuring the `MouseArea` only alters the radio button's
`checked` state and let the radio button handle the event propagation.
This was a regression introduced in https://github.com/status-im/status-desktop/pull/2065.
The new wrapping Rectangle would get the color that is possibily passed down
to Separator. Instead it should get properly bound to the actual separator.
This change aligns the member list's look & feel of the community profile popup
with the designs by implementing the proper member list items styles, hover effects
and fine-tuning the context menu.
This commit also comments some of the actions provided by the context menu,
which aren't implemented yet. There's no point in having UI components that don't or
can't function.
Those will be re-introduced once they are actually implemented.
Closes#1959
We've been implementing such a button in various ways throughout the
application. Sometimes using SVG icons and rectangles, sometimes highjacking
`StyledText` components (which was clever though).
Obviously this resulted in inconsistencies, so this commit introduces
a new dedicated component to render the three-dots button for context menus.
Sometimes, `Separator` is used inside context menus to separate groups
of actions that belong together. The separator in itself doesn't have any
padding or margins in this case because the just gets transcluded as is
in the context menu, between menu items.
There are cases in the design where a padding/margin is desired though.
This change makes that possible by wrapping the separator `Rectangle` with
another `Rectangle` which controls a custom height (if desired). The inner
rectangle is then just always vertically center.
In practice this means, existing usages of `Separator` behave exactly the same,
they don't break. In addtion one can set `Separator { height: x }` while maintaining
a 1px separator line.
Since https://github.com/status-im/status-desktop/commit/93668ff75
we're hiding the setting to change appearance for compact normal mode
of the UI. For now, compact mode is the new default (reasoning is unclear
at this point).
Prior to this change, most likely many users are still using the
normal mode configuration, so we have to enforce compact mode for
those.
The designs for the membership request button look different now, so this
commit makes use of the `StatusSettingsLineButton` to implement that new
look & feel.
Prior to this commit, the community memberlist was represented in a nested modal
which doesn't adhere to the designs. Rather, the section should render inside the
existing modal, requiring it to be refactored using a `StackView`.
This commit refactors the community profile popup so that the different content
sections ("Overview" and "MemberList") are rendered inside of the popup and can
be pushed onto and popped off a stack view.
The content components (newly introduced in this commit) `CommunityProfilePopupMembersList`
and `CommunityProfilePopupOverview` need to define a `headerTitle`, `headerDescription` and
if needed `imageSource` so they can alter the modal's header.
The same pattern might be used in other places of the modal if required.
Partially fixes#1959
In the recent past we've improved our `ModalPopup` to allow for a bit more control
when it comes to rendering a modal footer section with call-to-action items.
The footer section is rendered when there's `footerContent` and when the height
of the footer content is > 0. This means it's possible to also hide the footer content
section from the modal, even when there's footer content children.
However, there's a separator rendered whenver the footer is visible, regardless of its
height. This results in undesired behaviour when rendering footer children of height 0.
To avoid this, this commit adjust the condition so that the separator is only rendered
when the footer visible AND the height of it is > 0.
Allow up to 5 images to be dragged and dropped in to one-on-one chats and in the timeline. Can be combined with the existing upload button. The upload file dialog has been changed to allow multiple selections. Drag and dropped images adhere to the following rules, with corresponding validations messages:
- Max 5 image
- Image size must be 0.5 MB or less
- File extension must be one of [".png", ".jpg", ".jpeg", ".heif", "tif", ".tiff"]
Drag and drop and uploaded images are now also deduplicated.
This was hardcoded into `isAdmin` for some reason. It also seems that the
property isn't actually used anywhere in the profile popup, so we might
as well get rid off it.
The `communityProfilePopup` relies on the currently `activeCommunity` to
get its data. Unfortunately, once read, even when `chatsModel.setActiveCommunity()`
is called which triggers `activeCommunityChanged`, the data in the popup
won't be updated. The next time one would open a community profile page,
it'd have the data that was previously received from the model.
This commit ensures that the popup is hydrated with the most recent data
by explicitly updating its properties right before it's opened.
Prior to this commit there was a scenario where the application would
crash due a memory bug when attempting to (re)join a community.
The scenario is as follows:
1. User creates or has been invited to community with `ON_REQUEST` permissions
2. User leaves community
3. User decides to rejoin, so she selects the community she's been part
of and hits the "Join" button
At this point Status Desktop would send a new `RequestToJoin` request, as the
community has a corresponding permissions setting.
This would then result in an `already a member` error in status-go, because
status-go checks whether the requestee is already part of the members list of
the community. The error isn't handled inside Status Desktop which causes
a crash because we're trying to access data in memory that doesn't exist.
Why is this happening?
While this might be unexpected, when leaving a community (as done on step 2 of
the mentioned scenario), users don't actually lose membership but simply
"unsubscribe" from all channels in the community in question and their `joined`
flag is set to `false`.
From that point on, re-joininng a community is done by sending a `JoinCommunity`
request (instead of `RequestToJoin`), which will then set the `joined` flag to
`true` and doesn't actually check the membership in the database.
This commit ensures we're calling the right API by checking whether not only
whether the community is needs `ON _REQUEST` permissions, but also whether the
user isn't already a member of it.
Fixes#2017
In https://github.com/status-im/status-desktop/commit/a90a30af1 we've introduced the functionality to import
communities through the UI via a community private key.
That private key is being validated before it gets imported.
For some reason, validation has been removed in another refactor
later on in https://github.com/status-im/status-desktop/commit/534cb23e1, rendering the import
functionality broken.
This commit re-introduces the `validate()` method to make importing
communities work again.
Prior to this commit, communities without an image would render invisible
in the navigation bar of the application. To avoid this, we're now falling
back to our StatusLetterIdenticon component, which renders the first letter
of the community name with the color of the community.
When a user is part of a community, write access to any channel of
that community is granted. When the permission allows for it, a community's
channel `canPost` property is `true`, which should be relied on to
render the necessary component for writing into a channel.
This commit makes sure community members with proper access get the
chat input rendered so they can write to channels.
Fixes#1985
Very similar to #1986, we're trying to access the `activeCommunity`
property on the `chatsModel` object, which doesn't have such a property
anymore every since we've moved communities into its own view.
This causes errors when trying to create channels.
This commit fixes this bug by ensuring `activeCommunity` is accessed
from `chatsModel.communities` instead.
When the communities code was moved into its own view in https://github.com/status-im/status-desktop/commit/b38d1df59
it broke the functionality to join communities again.
Qt complains that the Nim API in use `chatsModel.communities.joinCommunity`
expects two parameters, when it's call with just one.
This is unexpected because the API in question set a default value
for its second parameter.
To make this work again, we have to make sure the `setActive`
parameter is supplied every time we call the API from
within QML.
Also, worth noting that this is not the first time we're running into
a scenario like this.
Turns out in https://github.com/status-im/status-desktop/commit/81bb7fcc6 we've introduced a regression where
leaving a communities isn't possible anymore because we're trying
to call an API that doesn't exist on the `chatsModel`.
This commit fixes it by ensuring the API is called from `chatsModel.communities`.
Updated community popup menu btn style. Fixes#1961
Updated community popup menu btn style. Fixes#1961
Updated community popup menu btn style. Fixes#1961
Updated community popup menu btn style. Fixes#1961
For an unknown reason, when the `chatLogView` ListView uses
a `verticalLayoutDirection: BottomToTop`, it prevents the application
from successfully rendering during login and crashes.
From debugging this, we know that this only happens when the above
condition applies *and* when a `DelegateModel` is used.
The delegate doesn't even need proper data, it application would still
crash.
We found out that the crash can be avoided when another `ListView` exists
in this component (however it's unclear why).
For now this commit adds such a placeholder `ListView` until it
we know more about what's going on.
In some cases inside of 1-on-1 chats, the fake messages added to
the beginning of the message list, wouldn't determine the correct
username of the contact in question.
This commit explicitly calls `chatsModel.userNameOrAlias()` instead
of relying on `activeChannel.name` which tries to do the same.
This commit adds a menu item to the message context menu to
copy links that may exist inside of a message.
There are three possible scenarios:
1. There's no link in the message, which causes the menu to not
render the dedicated menu item at all
2. There's one link in the message, which renders an additional
`Action` with a copy-to-clipboard functionality
3. There are multiple links in a single message. This adds a
nested `PopupMenu` in the existing menu with menu items for each
link extracted from the message
To make this work there were some changes in the `PopupMenu` component
needed, as it wasn't take the sub menu's `enabled` state into account
properly. This makde it always render nested menus even when they
should've been invisible.
Closes: #1733
Having the Timeline component loaded eagerly made switching
between channels rather slow because it always tries to read
the current message list from the chats model.
This commit changes the layout so that the timeline layout container
is only loaded conditionally when indeed activated.
This commit checks on bootstrap what the currently configured theme
of the user is and loads the system tray icon in its corresponding
variation.
Unfortunately, MacOS doesn't seem to automatically swap out the icons
based on the system's theme, so we have to do it manually with two
different SVG files.
Another gotcha here is that, it doesn't seem to be possible to change
the system tray icon at runtime. When trying to reassign the `icon.source`
based on a newly selected theme, the icon disappears altogether.
The application also doesn't get notified when a user switches the theme
inside the operating system, requiring her to switch to the same theme
manually unless restarted.
Last but not least, using SVG files instead of PNG doesn't seem to solve
the problem that the icon is rendered blurry. I've looked in the docs
but there doesn't seem to be an option to have any influence on that...
This commit introduces the new design and behaviour of the modal
that opens up when starting a new 1-on-1 chat.
Main changes include:
- New search UI/UX functionality of users and ENS resolutions
- Composed view of existing contacts and contacts to be searched
- Ability to add contacts from within the modal
Closes: #1747