This was caused by the fact that the canPost property was not exposed from the ChatItem model.
I'm actually not sure why it didn't show an error trying to call a function that doesn't exist
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.
Two fake messages are usually added to chat message lists inside a channel or
chat:
- One that imitates a chat identifier
- one that creates a button to fetch older messages
These two fake messages are added so it's ensured they show up at the beginning
of the chat.
The status timeline is also just a list of messages (filtered by a certain message
type), however there's no need to render these fake messages in this scenario.
That's why a `addFakeMessages` flag has been introduced which conditionally adds
those fake messages here: https://github.com/status-im/status-desktop/commit/3f012dbf0#diff-6aa545137319516beb03623bc6a9750e1d14a40c68d8868b5a672320fc4d680aR69
At some point, possibly around here (https://github.com/status-im/status-desktop/commit/8ee5abe57), the fake message for
the fetch more button has been reintroduced as default fake message.
This commit puts it back into the function so that it doesn't show up
inside the timeline view.
refactor: move threadpool task declarations inline with views
Co-authored-by: Michael Bradley Jr. <michaelsbradleyjr@gmail.com>
Co-authored-by: Eric Mastro <eric.mastro@gmail.com>
There was a bug introduced https://github.com/status-im/status-desktop/commit/2ac67f95a where we'd rely on the
possibly resolved public key, which is passed to `generateAlias()`.
The public key is never guaranteed to be an actual key (if resolution fails,
it's a an empty string). Passing an empty string to `generateAlias()` causes
`status-go` to crash and we don't handle that error.
This commit ensures that we only attempt to generate an alias when we
indeed have a successfully resolved public key.
Move the remaining stickers spawnAndSend (obtainAvailableStickerPacks) into a threadpool task.
refactor: create a base class for tasks models to inherit from
NOTE: this branch is based off of `experiment/tasks-3` and should be rebased on master once that branch is merged.
The `TaskManager` threadpool is a memory-safe replacement for the `spawnAndSend` operations that are currently causing memory issues in status-desktop.
From a fundamental memory management point of view, `libstatus/settings`, `libstatus/contracts`, and `libstatus/tokens` (custom tokens) have all been converted to `{.threadvar.}`s and `Atomic[bool]`s to maintain the cache and `dirty` flag across threads, respectively, eliminating the need for thread locks and incorrect `{.gcsafe.}` compiler overrides.
The successful [recyclable threadpool experiment from `nim-task-runner`](https://github.com/status-im/nim-task-runner/blob/test/use-cases/test/use_cases/test_sync.nim) using `AsyncChannel[ThreadSafeString]`s was brought over to `status-desktop` and implemented in somewhat of a hardcoded manner, as we knew this would save some time instead of trying to create a fully fleshed out `nim-task-runner` API and build a miraculous macro that may or may not be able to generate the needed API.
The threadpool is started by the `TaskManager` and both the `TaskManager` and the `TaskManager`'s threadpool are started as early as possible in the application lifecycle (in `nim_status_client.nim`). The `TaskManager` creates a thread to run the threadpool. During its initialization, the threadpool then spools up all the threads it will manage and puts them in an idle thread sequence. This is to prevent expensive thread creation and teardown happening during the app's lifetime as it is quite expensive and blocks the main thread. When tasks comes in to the pool, the task is sent to an idle thread, or put in a queue if all threads are busy. The idle thread is moved to the busy thread sequence. When a task is completed, the thread is taken out of the busy threads sequence and moved back in to the sequence of idle threads, effectively recycling it.
The first `spawnAndSend` we were able to change over to the new threadpool was `estimate`, which estimates the gas of a sticker purchase transaction.
From the consumer point of view, the existing `spawnAndSend` to achieve this looks like:
```nim
proc estimate*(self: StickersView, packId: int, address: string, price: string, uuid: string) {.slot.} =
let status_stickers = self.status.stickers
spawnAndSend(self, "setGasEstimate") do:
var success: bool
var estimate = status_stickers.estimateGas(packId, address, price, success)
if not success:
estimate = 325000
let result: tuple[estimate: int, uuid: string] = (estimate, uuid)
Json.encode(result)
```
And the new syntax looks like this:
```nim
proc estimate*(self: StickersView, packId: int, address: string, price: string, uuid: string) {.slot.} =
self.status.taskManager.threadPool.stickers.stickerPackPurchaseGasEstimate(cast[pointer](self.vptr), "setGasEstimate", packId, address, price, uuid)
```
The logic inside the `spawnAndSend` body was moved to [src/status/tasks/stickers.nim](https://github.com/status-im/status-desktop/compare/experiment/tasks-3?expand=1#diff-09e57eef00b0cee5c4abdb9039f948d8372e7003e09e934a9b4c7e9167d47658).
This is just the first migration of `spawnAndSend`, however moving the majority of the remaining `spawnAndSend`s will likely just be an exercise in copy/pasta. There will be one or two that may require a bit more thinking, depending how they rely on data from the model.
Once the `spawnAndSend`s have been converted to the threadpool, we can start implementing the [long-running process from the task runner use case experiments](https://github.com/status-im/nim-task-runner/blob/test/use-cases/test/use_cases/test_long_running.nim).
And finally, we can then implement the [async tasks](https://github.com/status-im/nim-task-runner/blob/test/use-cases/test/use_cases/test_async.nim) if needed.
@michaelsbradleyjr and I spent many hours digging in to the depths of nim's memory management in an attempt to understand it. We have created [a presentation with our task runner experiment findings](https://docs.google.com/presentation/d/1ItCxAfsVTcIoH_E4bgvmHljhbU-tC3T6K2A6ahwAedk/edit?usp=sharing), and @michaelsbradleyjr has spent time [answering questions off the back of that presentation.](https://gist.github.com/michaelsbradleyjr/1eaa9937b3fbb4ffff3fb814f0dd82a9).
We have created a fork of `edn.nim` at `status-im/edn.nim` and we need the PR to be merged and the commit hash updated before we can merge this PR in to `status-desktop`.
We've introduced a regression in https://github.com/status-im/status-desktop/commit/f1e83f74b#diff-f35edd413addd14c1f81816d6b5ee2bcbdf85fa0e3295d324cb78c98e26d4327L364 where we check whether an RPC's `error` is `null`
and its `result` is not `null`.
This breaks the application with an illegal storage access,
as in case of a successful API call, the response will have only a `result` key
(even when it's `null`).
Since we haven't done anything with a possible `error` in the reponse even before
that change was made, this commit removes the `error` check and safe guards around
whether `result` exists.
Fixes#2062
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.
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.
In https://github.com/status-im/status-desktop/commit/31a9d1a6f we've fixed
a bug where a contact's thumbnail hasn't been passed to the `saveContact`
API.
Unfortunately, that fix wasn't memory safe. There are cases when a contact's
`identityImage` is `nil`, resulting in illegal storage access when accessing
a contact's thumbnail.
This commit fixes the issue by safe guarding around `identityImage` possibly
being `nil`.
Turns out message reactions weren't functional in 1 on 1 chats.
Reaction signals come with a `chatId` that they correspond to, which is
then used to determine to channel and message list to apply/remove
the reaction to.
Inside of a 1 on 1 chat, the `chatId` of a reaction coming from the
will always be the pubKey of the the user that receives it.
A user however, usually doesn't store a chat item for her own pubKey
unless it's of type `Profile`.
This results in an illega storage access as reported in #1828
This commit fixes this bug by checking whether the reaction `chatId`
matches the user's `pubKey`. If that's the case, we know that the reaction
corresponds to the reaction's `fromAuthor` chat.
Fixes#1828
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
This commit does a bunch of things:
- First and foremost, it removes the active channel dependency.
This is needed to have it operate on the correct channel object,
without forcing us to change the active channel (e.g. right-clicking
on a channel item that's not active, will make it active eventually)
- To make that work, this commit changes the `ChannelContextMenu`
to receive a `ChatItemView`, so it can be used for things like determining
what menu options are shown, what members are in a group, whether
someone is admin of a group etc.
- This also required a new `QtProperty` called `contextChannel`.
The reason this is required, is because in some cases, like receiving
members count of groups, we need a complete `ChatItemView` object
as we don't have access to certain APIs otherwise.
- Unfortunately, we can't pass down `activeChannel` every where for that
because sometimes the context menu should not actually operate on
the active channel.
Fixes: #1755
fixes#935
A bug occurs when someone requests a large amount of funds from you since the gas estimation will fail and there isn't a way of handling errors in the source yet.
This PR handles the error appropriatley for both `estimateGas` and `estimateTokenGas` where the response is only converted from hex to int if the RPC call was successful. Otherwise return the error message as the response and let the UI decide how to display it.
Currently the error for gas estimation in transaction bubbles is displayed in a popup however, ive come to realize that 2 popups open instead of one. This is a new bug of which I can't pinpoint the root cause at the moment and have opted to file a separate issue for it.
As reported in #1584 the message that asks users to backup their seed phrase
is shown even when the seed phrase was imported in the first place, implying that
the mnemonic is already backed (it has to come from somewhere, right?).
This commit introduces a new `appSettings` property that is temporarily set to
determine whether or not the backup message should be shown.
It's set only temporarily because we actualy determine whether we want to show the
backup message, by checking if the account's mnemonic is still stored in the settings.
When a backup is done, Status removes the mnemonic from the profile settings.
So in order to get the right behaviour we need to make sure to remove the mnemonic
from the profile settings after the account has logged-in and originated from
an imported seed phrase. This is done by setting the mentioned property.
Closes#1584
This commit makes reactions in the status timeline work.
There are two things prior to this commit that are broken:
1. The logic that opens the reaction context menu always expects
and instance of `chatsView` because it tries to calculate a users
nickname. Such an instance isn't always available in that context, so
the nickname logic has been moved to `appMain` for now, removing that
dependency and therefore making it work in both, the chat view as well
as the status view.
2. While 1) makes the context menu work, it turns out that adding and
removing reactions inside the status timeline is still not working.
The reason for that is, that the reactions component maintains its own
`messageList`, which isn't aware of the fact that reactions for messages
coming from chats of `ChatType.Profile`, need to go into a dedicated
message list for `ChatType.Timeline`.
In other words, reactions are sent and removed from message in messagelists
that don't actually exist.
This commit fixes both of these things by ensuring the message lists
maintained by reactions are timeline aware. Also ensuring updates are
done correctly.
The `messageList` model used for rendering messages gets notified by the
`activeChannelChanged()` signal. That signal is not immediately emitted inside
the timeline when new messages are received.
This causes the underlying view data to be out of sync with the model,
causing UI bugs, such as rendering the `EmptyTimeline` component when in fact,
the timeline is not empty.
To fix this, there are two options:
1. Change the signal from `activeChannelChanged` to `messagePushed` signal, which
is for sure emitted when messages are received
2. Ensure `activeChannelChanged` is emitted when messages are pushed and the
active channel is indeed the timeline
Since the application has been relying on `activeChannelChanged` so far, I decided
to go with option 2 as I'm not sure whether option 1 would introduce other unwanted
side effects.