feat: Add recent stickers to stickers popup

This commit is contained in:
emizzle 2020-06-26 16:43:03 +10:00 committed by Iuri Matias
parent cd061895c2
commit 88e5f1a46d
11 changed files with 115 additions and 43 deletions

View File

@ -1,4 +1,4 @@
import NimQml, eventemitter, chronicles import NimQml, eventemitter, chronicles, tables
import ../../status/chat as chat_model import ../../status/chat as chat_model
import ../../status/mailservers as mailserver_model import ../../status/mailservers as mailserver_model
import ../../signals/types import ../../signals/types
@ -76,8 +76,12 @@ proc init*(self: ChatController) =
let currAcct = status_wallet.getWalletAccounts()[0] # TODO: make generic let currAcct = status_wallet.getWalletAccounts()[0] # TODO: make generic
let currAddr = parseAddress(currAcct.address) let currAddr = parseAddress(currAcct.address)
let installedStickers = self.status.chat.getInstalledStickers(currAddr) let installedStickers = self.status.chat.getInstalledStickers(currAddr)
for stickerPack in installedStickers: for packId, stickerPack in installedStickers.pairs:
self.view.addStickerPackToList(stickerPack) self.view.addStickerPackToList(stickerPack)
let recentStickers = self.status.chat.getRecentStickers()
for sticker in recentStickers:
self.view.addRecentStickerToList(sticker)
self.status.chat.addStickerToRecent(sticker)
proc handleMessage(self: ChatController, data: MessageSignal) = proc handleMessage(self: ChatController, data: MessageSignal) =
self.status.chat.update(data.chats, data.messages) self.status.chat.update(data.chats, data.messages)

View File

@ -12,6 +12,8 @@ import views/channels_list, views/message_list, views/chat_item, views/sticker_p
logScope: logScope:
topics = "chats-view" topics = "chats-view"
const RECENT_STICKERS = -1
QtObject: QtObject:
type type
ChatsView* = ref object of QAbstractListModel ChatsView* = ref object of QAbstractListModel
@ -41,10 +43,12 @@ QtObject:
result.status = status result.status = status
result.chats = newChannelsList() result.chats = newChannelsList()
result.activeChannel = newChatItemView(status) result.activeChannel = newChatItemView(status)
result.activeStickerPackId = -1 result.activeStickerPackId = RECENT_STICKERS
result.messageList = initTable[string, ChatMessageList]() result.messageList = initTable[string, ChatMessageList]()
result.stickerPacks = newStickerPackList() result.stickerPacks = newStickerPackList()
result.stickers = initTable[int, StickerList]() result.stickers = [
(RECENT_STICKERS, newStickerList())
].toTable
result.emptyStickerList = newStickerList() result.emptyStickerList = newStickerList()
result.setup() result.setup()
@ -98,8 +102,6 @@ QtObject:
self.activeStickerPackChanged() self.activeStickerPackChanged()
proc getStickerList*(self: ChatsView): QVariant {.slot.} = proc getStickerList*(self: ChatsView): QVariant {.slot.} =
if self.activeStickerPackId <= 0:
return newQVariant(self.emptyStickerList)
result = newQVariant(self.stickers[self.activeStickerPackId]) result = newQVariant(self.stickers[self.activeStickerPackId])
QtProperty[QVariant] stickers: QtProperty[QVariant] stickers:
@ -158,9 +160,14 @@ QtObject:
proc sendMessage*(self: ChatsView, message: string) {.slot.} = proc sendMessage*(self: ChatsView, message: string) {.slot.} =
discard self.status.chat.sendMessage(self.activeChannel.id, message) discard self.status.chat.sendMessage(self.activeChannel.id, message)
proc addRecentStickerToList*(self: ChatsView, sticker: Sticker) =
self.stickers[RECENT_STICKERS].addStickerToList(sticker)
proc sendSticker*(self: ChatsView, hash: string, pack: int) {.slot.} = proc sendSticker*(self: ChatsView, hash: string, pack: int) {.slot.} =
self.status.chat.sendSticker(self.activeChannel.id, hash, pack) let sticker = Sticker(hash: hash, packId: pack)
self.addRecentStickerToList(sticker)
self.status.chat.sendSticker(self.activeChannel.id, sticker)
proc joinChat*(self: ChatsView, channel: string, chatTypeInt: int): int {.slot.} = proc joinChat*(self: ChatsView, channel: string, chatTypeInt: int): int {.slot.} =
self.status.chat.join(channel, ChatType(chatTypeInt)) self.status.chat.join(channel, ChatType(chatTypeInt))

View File

@ -1,6 +1,5 @@
import NimQml, Tables import NimQml, Tables, sequtils
import ../../../status/chat/stickers import ../../../status/chat/stickers
import ../../../status/libstatus/types import ../../../status/libstatus/types
type type
@ -41,3 +40,10 @@ QtObject:
StickerRoles.Url.int:"url", StickerRoles.Url.int:"url",
StickerRoles.Hash.int:"hash" StickerRoles.Hash.int:"hash"
}.toTable }.toTable
proc addStickerToList*(self: StickerList, sticker: Sticker) =
if(self.stickers.any(proc(existingSticker: Sticker): bool = return existingSticker.hash == sticker.hash)):
return
self.beginInsertRows(newQModelIndex(), 0, 0)
self.stickers.insert(sticker, 0)
self.endInsertRows()

View File

@ -34,6 +34,7 @@ type
contacts*: Table[string, Profile] contacts*: Table[string, Profile]
channels*: Table[string, Chat] channels*: Table[string, Chat]
msgCursor*: Table[string, string] msgCursor*: Table[string, string]
recentStickers*: seq[Sticker]
include chat/utils include chat/utils
@ -43,6 +44,7 @@ proc newChatModel*(events: EventEmitter): ChatModel =
result.contacts = initTable[string, Profile]() result.contacts = initTable[string, Profile]()
result.channels = initTable[string, Chat]() result.channels = initTable[string, Chat]()
result.msgCursor = initTable[string, string]() result.msgCursor = initTable[string, string]()
result.recentStickers = @[]
proc delete*(self: ChatModel) = proc delete*(self: ChatModel) =
discard discard
@ -81,13 +83,16 @@ proc join*(self: ChatModel, chatId: string, chatType: ChatType) =
self.events.emit("channelJoined", ChannelArgs(chat: chat)) self.events.emit("channelJoined", ChannelArgs(chat: chat))
proc getInstalledStickers*(self: ChatModel, address: EthAddress): seq[StickerPack] = proc getInstalledStickers*(self: ChatModel, address: EthAddress): Table[int, StickerPack] =
# TODO: needs more fleshing out to determine which sticker packs # TODO: needs more fleshing out to determine which sticker packs
# we own -- owned sticker packs will simply allowed them to be installed # we own -- owned sticker packs will simply allowed them to be installed
discard status_stickers.getBalance(address) discard status_stickers.getBalance(address)
result = status_stickers.getInstalledStickers() result = status_stickers.getInstalledStickers()
proc getRecentStickers*(self: ChatModel): seq[Sticker] =
result = status_stickers.getRecentStickers()
proc init*(self: ChatModel) = proc init*(self: ChatModel) =
let chatList = status_chat.loadChats() let chatList = status_chat.loadChats()
@ -148,8 +153,16 @@ proc sendMessage*(self: ChatModel, chatId: string, msg: string): string =
self.emitUpdate(sentMessage) self.emitUpdate(sentMessage)
sentMessage sentMessage
proc sendSticker*(self: ChatModel, chatId: string, hash: string, pack: int) = proc addStickerToRecent*(self: ChatModel, sticker: Sticker) =
var response = status_chat.sendStickerMessage(chatId, hash, pack) self.recentStickers.insert(sticker, 0)
self.recentStickers = self.recentStickers.deduplicate()
if self.recentStickers.len > 24:
self.recentStickers = self.recentStickers[0..23] # take top 24 most recent
status_stickers.saveRecentStickers(self.recentStickers)
proc sendSticker*(self: ChatModel, chatId: string, sticker: Sticker) =
var response = status_chat.sendStickerMessage(chatId, sticker)
self.addStickerToRecent(sticker)
self.emitUpdate(response) self.emitUpdate(response)
proc chatMessages*(self: ChatModel, chatId: string, initialLoad:bool = true) = proc chatMessages*(self: ChatModel, chatId: string, initialLoad:bool = true) =

View File

@ -21,7 +21,7 @@ proc decodeContentHash*(value: string): string =
# ipfs-ns # ipfs-ns
if value[0] & value[1] != "e3": if value[0] & value[1] != "e3":
warn "Could not decode sticker. It may still be valid, but requires a different codec to be used" warn "Could not decode sticker. It may still be valid, but requires a different codec to be used", hash=value
return "" return ""
try: try:

View File

@ -2,6 +2,7 @@ import json, times, strutils, sequtils, chronicles
import core, utils import core, utils
import ../chat/[chat, message] import ../chat/[chat, message]
import ../../signals/messages import ../../signals/messages
import ./types
proc buildFilter*(chat: Chat):JsonNode = proc buildFilter*(chat: Chat):JsonNode =
if chat.chatType == ChatType.PrivateGroupChat: if chat.chatType == ChatType.PrivateGroupChat:
@ -82,7 +83,7 @@ proc sendChatMessage*(chatId: string, msg: string): string =
} }
]) ])
proc sendStickerMessage*(chatId: string, hash: string, pack: int): string = proc sendStickerMessage*(chatId: string, sticker: Sticker): string =
callPrivateRPC("sendChatMessage".prefix, %* [ callPrivateRPC("sendChatMessage".prefix, %* [
{ {
"chatId": chatId, "chatId": chatId,
@ -90,8 +91,8 @@ proc sendStickerMessage*(chatId: string, hash: string, pack: int): string =
"responseTo": nil, "responseTo": nil,
"ensName": nil, "ensName": nil,
"sticker": { "sticker": {
"hash": hash, "hash": sticker.hash,
"pack": pack "pack": sticker.packId
}, },
"contentType": ContentType.Sticker.int "contentType": ContentType.Sticker.int
} }

View File

@ -1,9 +1,10 @@
import core import core, ./types
import json import json, tables
import json_serialization
proc saveSettings*(key: string, value: string): string = proc saveSettings*(key: string, value: string | JsonNode): string =
callPrivateRPC("settings_saveSetting", %* [ callPrivateRPC("settings_saveSetting", %* [
key, $value key, value
]) ])
proc getWeb3ClientVersion*(): string = proc getWeb3ClientVersion*(): string =
@ -13,6 +14,9 @@ proc getSettings*(): JsonNode =
callPrivateRPC("settings_getSettings").parseJSON()["result"] callPrivateRPC("settings_getSettings").parseJSON()["result"]
# TODO: return an Table/Object instead # TODO: return an Table/Object instead
proc getSetting*(name: string): string =
proc getSetting*[T](name: string, defaultValue: T): T =
let settings: JsonNode = getSettings() let settings: JsonNode = getSettings()
result = settings{name}.getStr if not settings.contains(name):
return defaultValue
result = Json.decode($settings{name}, T)

File diff suppressed because one or more lines are too long

View File

@ -102,10 +102,11 @@ type
type type
RpcException* = object of Exception RpcException* = object of Exception
type Sticker* = ref object type Sticker* = object
hash*: string hash*: string
packId*: int
type StickerPack* = ref object type StickerPack* = object
author*: string author*: string
id*: int id*: int
name*: string name*: string

View File

@ -50,7 +50,7 @@ proc sendTransaction*(self: WalletModel, from_value: string, to: string, value:
proc getDefaultCurrency*(self: WalletModel): string = proc getDefaultCurrency*(self: WalletModel): string =
# TODO: this should come from a model? It is going to be used too in the # TODO: this should come from a model? It is going to be used too in the
# profile section and ideally we should not call the settings more than once # profile section and ideally we should not call the settings more than once
status_settings.getSetting("currency") status_settings.getSetting[string]("currency", "")
proc setDefaultCurrency*(self: WalletModel, currency: string) = proc setDefaultCurrency*(self: WalletModel, currency: string) =
discard status_settings.saveSettings("currency", currency) discard status_settings.saveSettings("currency", currency)

View File

@ -41,9 +41,9 @@ Popup {
Layout.preferredHeight: 400 - 4 Layout.preferredHeight: 400 - 4
Item { Item {
id: stickerHistory id: noStickerPacks
anchors.fill: parent anchors.fill: parent
visible: true visible: stickerGrid.count <= 0 || stickerPackListView.count <= 0
Image { Image {
id: imgNoStickers id: imgNoStickers
@ -55,19 +55,38 @@ Popup {
source: "../../../img/stickers_sad_icon.svg" source: "../../../img/stickers_sad_icon.svg"
} }
Text { Item {
id: lblNoStickers id: noStickersContainer
width: parent.width width: parent.width
font.pixelSize: 15 height: 22
text: qsTr("You don't have any stickers yet")
horizontalAlignment: Text.AlignHCenter
anchors.top: imgNoStickers.bottom anchors.top: imgNoStickers.bottom
anchors.topMargin: 8 anchors.topMargin: 8
Text {
id: lblNoStickersYet
visible: stickerPackListView.count <= 0
anchors.fill: parent
font.pixelSize: 15
text: qsTr("You don't have any stickers yet")
lineHeight: 22
horizontalAlignment: Text.AlignHCenter
}
Text {
id: lblNoRecentStickers
visible: stickerPackListView.count > 0 && stickerGrid.count <= 0
anchors.fill: parent
font.pixelSize: 15
text: qsTr("Recently used stickers will appear here")
lineHeight: 22
horizontalAlignment: Text.AlignHCenter
}
} }
StyledButton { StyledButton {
visible: stickerPackListView.count <= 0
label: qsTr("Get Stickers") label: qsTr("Get Stickers")
anchors.top: lblNoStickers.bottom anchors.top: noStickersContainer.bottom
anchors.topMargin: Theme.padding anchors.topMargin: Theme.padding
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
} }
@ -75,7 +94,7 @@ Popup {
GridView { GridView {
id: stickerGrid id: stickerGrid
visible: false visible: count > 0
anchors.fill: parent anchors.fill: parent
cellWidth: 88 cellWidth: 88
cellHeight: 88 cellHeight: 88
@ -134,9 +153,8 @@ Popup {
anchors.left: btnAddStickerPack.right anchors.left: btnAddStickerPack.right
anchors.leftMargin: Theme.padding anchors.leftMargin: Theme.padding
onClicked: { onClicked: {
chatsModel.setActiveStickerPackById(-1)
packIndicator.updatePosition(-1) packIndicator.updatePosition(-1)
stickerGrid.visible = false;
stickerHistory.visible = true;
} }
} }
@ -160,8 +178,6 @@ Popup {
chatsModel.setActiveStickerPackById(id) chatsModel.setActiveStickerPackById(id)
popup.selectedPackId = id popup.selectedPackId = id
packIndicator.updatePosition(index) packIndicator.updatePosition(index)
stickerGrid.visible = true;
stickerHistory.visible = false;
} }
} }
} }