mirror of
https://github.com/status-im/status-desktop.git
synced 2025-01-11 14:54:48 +00:00
refactor: load gifs asynchronously
Instead of loading recent gifs right on startup eagerly, we postpone the task to when it's actually needed (when the gif popup is opened and the recent gifs tab is activated), and on top of that we also load the data asynchronously to keep the amount of work that needs to be done in a single tick as short as possible. This needs: status-im/status-go#3170 Closes #9437
This commit is contained in:
parent
2ac1216b68
commit
919f3dc6f7
@ -209,7 +209,7 @@ proc newAppController*(statusFoundation: StatusFoundation): AppController =
|
|||||||
result.mailserversService = mailservers_service.newService(statusFoundation.events, statusFoundation.threadpool,
|
result.mailserversService = mailservers_service.newService(statusFoundation.events, statusFoundation.threadpool,
|
||||||
result.settingsService, result.nodeConfigurationService, statusFoundation.fleetConfiguration)
|
result.settingsService, result.nodeConfigurationService, statusFoundation.fleetConfiguration)
|
||||||
result.nodeService = node_service.newService(statusFoundation.events, result.settingsService, result.nodeConfigurationService)
|
result.nodeService = node_service.newService(statusFoundation.events, result.settingsService, result.nodeConfigurationService)
|
||||||
result.gifService = gif_service.newService(result.settingsService)
|
result.gifService = gif_service.newService(result.settingsService, statusFoundation.events, statusFoundation.threadpool)
|
||||||
result.ensService = ens_service.newService(statusFoundation.events, statusFoundation.threadpool,
|
result.ensService = ens_service.newService(statusFoundation.events, statusFoundation.threadpool,
|
||||||
result.settingsService, result.walletAccountService, result.transactionService,
|
result.settingsService, result.walletAccountService, result.transactionService,
|
||||||
result.networkService, result.tokenService)
|
result.networkService, result.tokenService)
|
||||||
|
@ -4,11 +4,13 @@ import ../../../../../../app_service/service/community/service as community_serv
|
|||||||
import ../../../../../../app_service/service/chat/service as chat_service
|
import ../../../../../../app_service/service/chat/service as chat_service
|
||||||
import ../../../../../../app_service/service/gif/service as gif_service
|
import ../../../../../../app_service/service/gif/service as gif_service
|
||||||
import ../../../../../../app_service/service/gif/dto
|
import ../../../../../../app_service/service/gif/dto
|
||||||
|
import ../../../../../core/eventemitter
|
||||||
|
|
||||||
type
|
type
|
||||||
Controller* = ref object of RootObj
|
Controller* = ref object of RootObj
|
||||||
delegate: io_interface.AccessInterface
|
delegate: io_interface.AccessInterface
|
||||||
sectionId: string
|
sectionId: string
|
||||||
|
events: EventEmitter
|
||||||
chatId: string
|
chatId: string
|
||||||
belongsToCommunity: bool
|
belongsToCommunity: bool
|
||||||
communityService: community_service.Service
|
communityService: community_service.Service
|
||||||
@ -17,6 +19,7 @@ type
|
|||||||
|
|
||||||
proc newController*(
|
proc newController*(
|
||||||
delegate: io_interface.AccessInterface,
|
delegate: io_interface.AccessInterface,
|
||||||
|
events: EventEmitter,
|
||||||
sectionId: string,
|
sectionId: string,
|
||||||
chatId: string,
|
chatId: string,
|
||||||
belongsToCommunity: bool,
|
belongsToCommunity: bool,
|
||||||
@ -26,6 +29,7 @@ proc newController*(
|
|||||||
): Controller =
|
): Controller =
|
||||||
result = Controller()
|
result = Controller()
|
||||||
result.delegate = delegate
|
result.delegate = delegate
|
||||||
|
result.events = events
|
||||||
result.sectionId = chatId
|
result.sectionId = chatId
|
||||||
result.chatId = chatId
|
result.chatId = chatId
|
||||||
result.belongsToCommunity = belongsToCommunity
|
result.belongsToCommunity = belongsToCommunity
|
||||||
@ -37,7 +41,13 @@ proc delete*(self: Controller) =
|
|||||||
discard
|
discard
|
||||||
|
|
||||||
proc init*(self: Controller) =
|
proc init*(self: Controller) =
|
||||||
discard
|
self.events.on(SIGNAL_LOAD_RECENT_GIFS_DONE) do(e:Args):
|
||||||
|
let args = GifsArgs(e)
|
||||||
|
self.delegate.loadRecentGifsDone(args.gifs)
|
||||||
|
|
||||||
|
self.events.on(SIGNAL_LOAD_FAVORITE_GIFS_DONE) do(e:Args):
|
||||||
|
let args = GifsArgs(e)
|
||||||
|
self.delegate.loadFavoriteGifsDone(args.gifs)
|
||||||
|
|
||||||
proc getChatId*(self: Controller): string =
|
proc getChatId*(self: Controller): string =
|
||||||
return self.chatId
|
return self.chatId
|
||||||
@ -84,6 +94,12 @@ proc getTrendingsGifs*(self: Controller): seq[GifDto] =
|
|||||||
proc getRecentsGifs*(self: Controller): seq[GifDto] =
|
proc getRecentsGifs*(self: Controller): seq[GifDto] =
|
||||||
return self.gifService.getRecents()
|
return self.gifService.getRecents()
|
||||||
|
|
||||||
|
proc loadRecentGifs*(self: Controller) =
|
||||||
|
self.gifService.asyncLoadRecentGifs()
|
||||||
|
|
||||||
|
proc loadFavoriteGifs*(self: Controller) =
|
||||||
|
self.gifService.asyncLoadFavoriteGifs()
|
||||||
|
|
||||||
proc getFavoritesGifs*(self: Controller): seq[GifDto] =
|
proc getFavoritesGifs*(self: Controller): seq[GifDto] =
|
||||||
return self.gifService.getFavorites()
|
return self.gifService.getFavorites()
|
||||||
|
|
||||||
|
@ -50,9 +50,21 @@ method getTrendingsGifs*(self: AccessInterface): seq[GifDto] {.base.} =
|
|||||||
method getRecentsGifs*(self: AccessInterface): seq[GifDto] {.base.} =
|
method getRecentsGifs*(self: AccessInterface): seq[GifDto] {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method loadRecentGifs*(self: AccessInterface) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method loadRecentGifsDone*(self: AccessInterface, gifs: seq[GifDto]) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
method getFavoritesGifs*(self: AccessInterface): seq[GifDto] {.base.} =
|
method getFavoritesGifs*(self: AccessInterface): seq[GifDto] {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method loadFavoriteGifs*(self: AccessInterface) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method loadFavoriteGifsDone*(self: AccessInterface, gifs: seq[GifDto]) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
method toggleFavoriteGif*(self: AccessInterface, item: GifDto) {.base.} =
|
method toggleFavoriteGif*(self: AccessInterface, item: GifDto) {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ import io_interface
|
|||||||
import ../io_interface as delegate_interface
|
import ../io_interface as delegate_interface
|
||||||
import view, controller
|
import view, controller
|
||||||
import ../../../../../global/global_singleton
|
import ../../../../../global/global_singleton
|
||||||
|
import ../../../../../core/eventemitter
|
||||||
|
|
||||||
import ../../../../../../app_service/service/chat/service as chat_service
|
import ../../../../../../app_service/service/chat/service as chat_service
|
||||||
import ../../../../../../app_service/service/community/service as community_service
|
import ../../../../../../app_service/service/community/service as community_service
|
||||||
@ -21,6 +22,7 @@ type
|
|||||||
|
|
||||||
proc newModule*(
|
proc newModule*(
|
||||||
delegate: delegate_interface.AccessInterface,
|
delegate: delegate_interface.AccessInterface,
|
||||||
|
events: EventEmitter,
|
||||||
sectionId: string,
|
sectionId: string,
|
||||||
chatId: string,
|
chatId: string,
|
||||||
belongsToCommunity: bool,
|
belongsToCommunity: bool,
|
||||||
@ -33,7 +35,7 @@ proc newModule*(
|
|||||||
result.delegate = delegate
|
result.delegate = delegate
|
||||||
result.view = view.newView(result)
|
result.view = view.newView(result)
|
||||||
result.viewVariant = newQVariant(result.view)
|
result.viewVariant = newQVariant(result.view)
|
||||||
result.controller = controller.newController(result, sectionId, chatId, belongsToCommunity, chatService, communityService, gifService)
|
result.controller = controller.newController(result, events, sectionId, chatId, belongsToCommunity, chatService, communityService, gifService)
|
||||||
result.moduleLoaded = false
|
result.moduleLoaded = false
|
||||||
|
|
||||||
method delete*(self: Module) =
|
method delete*(self: Module) =
|
||||||
@ -98,9 +100,21 @@ method getTrendingsGifs*(self: Module): seq[GifDto] =
|
|||||||
method getRecentsGifs*(self: Module): seq[GifDto] =
|
method getRecentsGifs*(self: Module): seq[GifDto] =
|
||||||
return self.controller.getRecentsGifs()
|
return self.controller.getRecentsGifs()
|
||||||
|
|
||||||
|
method loadRecentGifs*(self: Module) =
|
||||||
|
self.controller.loadRecentGifs()
|
||||||
|
|
||||||
|
method loadRecentGifsDone*(self: Module, gifs: seq[GifDto]) =
|
||||||
|
self.view.updateGifColumns(gifs)
|
||||||
|
|
||||||
method getFavoritesGifs*(self: Module): seq[GifDto] =
|
method getFavoritesGifs*(self: Module): seq[GifDto] =
|
||||||
return self.controller.getFavoritesGifs()
|
return self.controller.getFavoritesGifs()
|
||||||
|
|
||||||
|
method loadFavoriteGifs*(self: Module) =
|
||||||
|
self.controller.loadFavoriteGifs()
|
||||||
|
|
||||||
|
method loadFavoriteGifsDone*(self: Module, gifs: seq[GifDto]) =
|
||||||
|
self.view.updateGifColumns(gifs)
|
||||||
|
|
||||||
method toggleFavoriteGif*(self: Module, item: GifDto) =
|
method toggleFavoriteGif*(self: Module, item: GifDto) =
|
||||||
self.controller.toggleFavoriteGif(item)
|
self.controller.toggleFavoriteGif(item)
|
||||||
|
|
||||||
|
@ -80,7 +80,7 @@ QtObject:
|
|||||||
read = getGifColumnC
|
read = getGifColumnC
|
||||||
notify = gifLoaded
|
notify = gifLoaded
|
||||||
|
|
||||||
proc updateGifColumns(self: View, data: seq[GifDto]) =
|
proc updateGifColumns*(self: View, data: seq[GifDto]) =
|
||||||
var columnAData: seq[GifDto] = @[]
|
var columnAData: seq[GifDto] = @[]
|
||||||
var columnAHeight = 0
|
var columnAHeight = 0
|
||||||
var columnBData: seq[GifDto] = @[]
|
var columnBData: seq[GifDto] = @[]
|
||||||
@ -115,11 +115,21 @@ QtObject:
|
|||||||
|
|
||||||
proc getRecentsGifs*(self: View) {.slot.} =
|
proc getRecentsGifs*(self: View) {.slot.} =
|
||||||
let data = self.delegate.getRecentsGifs()
|
let data = self.delegate.getRecentsGifs()
|
||||||
self.updateGifColumns(data)
|
if data.len > 0:
|
||||||
|
self.updateGifColumns(data)
|
||||||
|
return
|
||||||
|
|
||||||
|
# recent gifs were not loaded yet, so we do it now
|
||||||
|
self.delegate.loadRecentGifs()
|
||||||
|
|
||||||
proc getFavoritesGifs*(self: View) {.slot.} =
|
proc getFavoritesGifs*(self: View) {.slot.} =
|
||||||
let data = self.delegate.getFavoritesGifs()
|
let data = self.delegate.getFavoritesGifs()
|
||||||
self.updateGifColumns(data)
|
if data.len > 0:
|
||||||
|
self.updateGifColumns(data)
|
||||||
|
return
|
||||||
|
|
||||||
|
# favorite gifs were not loaded yet, so we do it now
|
||||||
|
self.delegate.loadFavoriteGifs()
|
||||||
|
|
||||||
proc findGifDto(self: View, id: string): GifDto =
|
proc findGifDto(self: View, id: string): GifDto =
|
||||||
for item in self.gifColumnAModel.gifs:
|
for item in self.gifColumnAModel.gifs:
|
||||||
|
@ -52,7 +52,7 @@ proc newModule*(delegate: delegate_interface.AccessInterface, events: EventEmitt
|
|||||||
isUsersListAvailable, settingsService, nodeConfigurationService, contactService, chatService, communityService, messageService)
|
isUsersListAvailable, settingsService, nodeConfigurationService, contactService, chatService, communityService, messageService)
|
||||||
result.moduleLoaded = false
|
result.moduleLoaded = false
|
||||||
|
|
||||||
result.inputAreaModule = input_area_module.newModule(result, sectionId, chatId, belongsToCommunity, chatService, communityService, gifService)
|
result.inputAreaModule = input_area_module.newModule(result, events, sectionId, chatId, belongsToCommunity, chatService, communityService, gifService)
|
||||||
result.messagesModule = messages_module.newModule(result, events, sectionId, chatId, belongsToCommunity,
|
result.messagesModule = messages_module.newModule(result, events, sectionId, chatId, belongsToCommunity,
|
||||||
contactService, communityService, chatService, messageService, mailserversService)
|
contactService, communityService, chatService, messageService, mailserversService)
|
||||||
result.usersModule =
|
result.usersModule =
|
||||||
|
19
src/app_service/service/gif/async_tasks.nim
Normal file
19
src/app_service/service/gif/async_tasks.nim
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
include ../../common/json_utils
|
||||||
|
include ../../../app/core/tasks/common
|
||||||
|
import ../../../backend/gifs as status_go
|
||||||
|
|
||||||
|
type
|
||||||
|
AsyncGetRecentGifsTaskArg = ref object of QObjectTaskArg
|
||||||
|
|
||||||
|
const asyncGetRecentGifsTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||||
|
let arg = decode[AsyncGetRecentGifsTaskArg](argEncoded)
|
||||||
|
let response = status_go.getRecentGifs()
|
||||||
|
arg.finish(response)
|
||||||
|
|
||||||
|
type
|
||||||
|
AsyncGetFavoriteGifsTaskArg = ref object of QObjectTaskArg
|
||||||
|
|
||||||
|
const asyncGetFavoriteGifsTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||||
|
let arg = decode[AsyncGetFavoriteGifsTaskArg](argEncoded)
|
||||||
|
let response = status_go.getFavoriteGifs()
|
||||||
|
arg.finish(response)
|
@ -4,11 +4,17 @@ import os
|
|||||||
import uri
|
import uri
|
||||||
import chronicles
|
import chronicles
|
||||||
import sequtils
|
import sequtils
|
||||||
|
import NimQml
|
||||||
|
|
||||||
import ../settings/service as settings_service
|
import ../settings/service as settings_service
|
||||||
|
import ../../../app/core/eventemitter
|
||||||
import ../../../backend/backend
|
import ../../../backend/backend
|
||||||
|
import ../../../app/core/tasks/[qt, threadpool]
|
||||||
|
import ../../../app/core/[main]
|
||||||
import ./dto
|
import ./dto
|
||||||
|
|
||||||
|
include ./async_tasks
|
||||||
|
|
||||||
logScope:
|
logScope:
|
||||||
topics = "gif-service"
|
topics = "gif-service"
|
||||||
|
|
||||||
@ -23,127 +29,192 @@ let TENOR_API_KEY_RESOLVED =
|
|||||||
else:
|
else:
|
||||||
TENOR_API_KEY
|
TENOR_API_KEY
|
||||||
|
|
||||||
|
const SIGNAL_LOAD_RECENT_GIFS_STARTED* = "loadRecentGifsStarted"
|
||||||
|
const SIGNAL_LOAD_RECENT_GIFS_DONE* = "loadRecentGifsDone"
|
||||||
|
|
||||||
|
const SIGNAL_LOAD_FAVORITE_GIFS_STARTED* = "loadFavoriteGifsStarted"
|
||||||
|
const SIGNAL_LOAD_FAVORITE_GIFS_DONE* = "loadFavoriteGifsDone"
|
||||||
|
|
||||||
type
|
type
|
||||||
Service* = ref object of RootObj
|
GifsArgs* = ref object of Args
|
||||||
settingsService: settings_service.Service
|
gifs*: seq[GifDto]
|
||||||
favorites: seq[GifDto]
|
error*: string
|
||||||
recents: seq[GifDto]
|
|
||||||
|
|
||||||
proc delete*(self: Service) =
|
QtObject:
|
||||||
discard
|
type
|
||||||
|
Service* = ref object of QObject
|
||||||
|
threadpool: ThreadPool
|
||||||
|
settingsService: settings_service.Service
|
||||||
|
favorites: seq[GifDto]
|
||||||
|
recents: seq[GifDto]
|
||||||
|
events: EventEmitter
|
||||||
|
|
||||||
proc newService*(settingsService: settings_service.Service): Service =
|
proc delete*(self: Service) =
|
||||||
result = Service()
|
discard
|
||||||
result.settingsService = settingsService
|
|
||||||
result.favorites = @[]
|
|
||||||
result.recents = @[]
|
|
||||||
|
|
||||||
proc setTenorAPIKey(self: Service) =
|
proc newService*(settingsService: settings_service.Service, events: EventEmitter, threadpool: ThreadPool): Service =
|
||||||
try:
|
result = Service()
|
||||||
let response = backend.setTenorAPIKey(TENOR_API_KEY_RESOLVED)
|
result.QObject.setup
|
||||||
if(not response.error.isNil):
|
result.settingsService = settingsService
|
||||||
error "error setTenorAPIKey: ", errDescription = response.error.message
|
result.events = events
|
||||||
|
result.threadpool = threadpool
|
||||||
|
result.favorites = @[]
|
||||||
|
result.recents = @[]
|
||||||
|
|
||||||
except Exception as e:
|
proc setTenorAPIKey(self: Service) =
|
||||||
error "error: ", procName="setTenorAPIKey", errName = e.name, errDesription = e.msg
|
try:
|
||||||
|
let response = backend.setTenorAPIKey(TENOR_API_KEY_RESOLVED)
|
||||||
|
if(not response.error.isNil):
|
||||||
|
error "error setTenorAPIKey: ", errDescription = response.error.message
|
||||||
|
|
||||||
proc getRecentGifs(self: Service) =
|
except Exception as e:
|
||||||
try:
|
error "error: ", procName="setTenorAPIKey", errName = e.name, errDesription = e.msg
|
||||||
let response = backend.getRecentGifs()
|
|
||||||
|
|
||||||
if(not response.error.isNil):
|
proc getRecentGifs(self: Service) =
|
||||||
error "error getRecentGifs: ", errDescription = response.error.message
|
try:
|
||||||
|
let response = backend.getRecentGifs()
|
||||||
|
|
||||||
self.recents = map(response.result.getElems(), settingToGifDto)
|
if(not response.error.isNil):
|
||||||
|
error "error getRecentGifs: ", errDescription = response.error.message
|
||||||
|
|
||||||
except Exception as e:
|
self.recents = map(response.result.getElems(), settingToGifDto)
|
||||||
error "error: ", procName="getRecentGifs", errName = e.name, errDesription = e.msg
|
|
||||||
|
|
||||||
proc getFavoriteGifs(self: Service) =
|
except Exception as e:
|
||||||
try:
|
error "error: ", procName="getRecentGifs", errName = e.name, errDesription = e.msg
|
||||||
let response = backend.getFavoriteGifs()
|
|
||||||
|
|
||||||
if(not response.error.isNil):
|
proc getFavoriteGifs(self: Service) =
|
||||||
error "error getFavoriteGifs: ", errDescription = response.error.message
|
try:
|
||||||
|
let response = backend.getFavoriteGifs()
|
||||||
|
|
||||||
self.favorites = map(response.result.getElems(), settingToGifDto)
|
if(not response.error.isNil):
|
||||||
|
error "error getFavoriteGifs: ", errDescription = response.error.message
|
||||||
|
|
||||||
except Exception as e:
|
self.favorites = map(response.result.getElems(), settingToGifDto)
|
||||||
error "error: ", procName="getFavoriteGifs", errName = e.name, errDesription = e.msg
|
|
||||||
|
|
||||||
proc init*(self: Service) =
|
except Exception as e:
|
||||||
# set Tenor API Key
|
error "error: ", procName="getFavoriteGifs", errName = e.name, errDesription = e.msg
|
||||||
self.setTenorAPIKey()
|
|
||||||
|
|
||||||
# get recent and favorite gifs on the database
|
proc asyncLoadRecentGifs*(self: Service) =
|
||||||
self.getRecentGifs()
|
self.events.emit(SIGNAL_LOAD_RECENT_GIFS_STARTED, Args())
|
||||||
self.getFavoriteGifs()
|
try:
|
||||||
|
let arg = AsyncGetRecentGifsTaskArg(
|
||||||
|
tptr: cast[ByteAddress](asyncGetRecentGifsTask),
|
||||||
|
vptr: cast[ByteAddress](self.vptr),
|
||||||
|
slot: "onAsyncGetRecentGifsDone"
|
||||||
|
)
|
||||||
|
self.threadpool.start(arg)
|
||||||
|
except Exception as e:
|
||||||
|
error "Error loading recent gifs", msg = e.msg
|
||||||
|
|
||||||
proc tenorQuery(self: Service, path: string): seq[GifDto] =
|
proc onAsyncGetRecentGifsDone*(self: Service, response: string) {.slot.} =
|
||||||
try:
|
try:
|
||||||
let response = backend.fetchGifs(path)
|
let rpcResponseObj = response.parseJson
|
||||||
let doc = response.result.str.parseJson()
|
if (rpcResponseObj{"error"}.kind != JNull):
|
||||||
|
let error = Json.decode($rpcResponseObj["error"], RpcError)
|
||||||
|
error "error loading recent gifs", msg = error.message
|
||||||
|
return
|
||||||
|
|
||||||
var items: seq[GifDto] = @[]
|
self.recents = map(rpcResponseObj{"result"}.getElems(), settingToGifDto)
|
||||||
for json in doc["results"]:
|
self.events.emit(SIGNAL_LOAD_RECENT_GIFS_DONE, GifsArgs(gifs: self.recents))
|
||||||
items.add(tenorToGifDto(json))
|
except Exception as e:
|
||||||
|
let errMsg = e.msg
|
||||||
|
error "error: ", errMsg
|
||||||
|
|
||||||
return items
|
proc asyncLoadFavoriteGifs*(self: Service) =
|
||||||
except:
|
self.events.emit(SIGNAL_LOAD_FAVORITE_GIFS_STARTED, Args())
|
||||||
return @[]
|
try:
|
||||||
|
let arg = AsyncGetFavoriteGifsTaskArg(
|
||||||
|
tptr: cast[ByteAddress](asyncGetFavoriteGifsTask),
|
||||||
|
vptr: cast[ByteAddress](self.vptr),
|
||||||
|
slot: "onAsyncGetFavoriteGifsDone"
|
||||||
|
)
|
||||||
|
self.threadpool.start(arg)
|
||||||
|
except Exception as e:
|
||||||
|
error "Error loading favorite gifs", msg = e.msg
|
||||||
|
|
||||||
proc search*(self: Service, query: string): seq[GifDto] =
|
proc onAsyncGetFavoriteGifsDone*(self: Service, response: string) {.slot.} =
|
||||||
return self.tenorQuery(fmt("search?q={encodeUrl(query)}"))
|
try:
|
||||||
|
let rpcResponseObj = response.parseJson
|
||||||
|
if (rpcResponseObj{"error"}.kind != JNull):
|
||||||
|
let error = Json.decode($rpcResponseObj["error"], RpcError)
|
||||||
|
error "error loading favorite gifs", msg = error.message
|
||||||
|
return
|
||||||
|
|
||||||
proc getTrendings*(self: Service): seq[GifDto] =
|
self.favorites = map(rpcResponseObj{"result"}.getElems(), settingToGifDto)
|
||||||
return self.tenorQuery("trending?")
|
self.events.emit(SIGNAL_LOAD_FAVORITE_GIFS_DONE, GifsArgs(gifs: self.favorites))
|
||||||
|
except Exception as e:
|
||||||
|
let errMsg = e.msg
|
||||||
|
error "error: ", errMsg
|
||||||
|
|
||||||
proc getRecents*(self: Service): seq[GifDto] =
|
proc init*(self: Service) =
|
||||||
return self.recents
|
# set Tenor API Key
|
||||||
|
self.setTenorAPIKey()
|
||||||
|
|
||||||
proc addToRecents*(self: Service, gifDto: GifDto) =
|
proc tenorQuery(self: Service, path: string): seq[GifDto] =
|
||||||
let recents = self.getRecents()
|
try:
|
||||||
var newRecents: seq[GifDto] = @[gifDto]
|
let response = backend.fetchGifs(path)
|
||||||
var idx = 0
|
let doc = response.result.str.parseJson()
|
||||||
|
|
||||||
while idx < MAX_RECENT - 1:
|
var items: seq[GifDto] = @[]
|
||||||
if idx >= recents.len:
|
for json in doc["results"]:
|
||||||
break
|
items.add(tenorToGifDto(json))
|
||||||
|
|
||||||
if recents[idx].id == gifDto.id:
|
return items
|
||||||
|
except:
|
||||||
|
return @[]
|
||||||
|
|
||||||
|
proc search*(self: Service, query: string): seq[GifDto] =
|
||||||
|
return self.tenorQuery(fmt("search?q={encodeUrl(query)}"))
|
||||||
|
|
||||||
|
proc getTrendings*(self: Service): seq[GifDto] =
|
||||||
|
return self.tenorQuery("trending?")
|
||||||
|
|
||||||
|
proc getRecents*(self: Service): seq[GifDto] =
|
||||||
|
return self.recents
|
||||||
|
|
||||||
|
proc addToRecents*(self: Service, gifDto: GifDto) =
|
||||||
|
let recents = self.getRecents()
|
||||||
|
var newRecents: seq[GifDto] = @[gifDto]
|
||||||
|
var idx = 0
|
||||||
|
|
||||||
|
while idx < MAX_RECENT - 1:
|
||||||
|
if idx >= recents.len:
|
||||||
|
break
|
||||||
|
|
||||||
|
if recents[idx].id == gifDto.id:
|
||||||
|
idx += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
newRecents.add(recents[idx])
|
||||||
idx += 1
|
idx += 1
|
||||||
continue
|
|
||||||
|
|
||||||
newRecents.add(recents[idx])
|
self.recents = newRecents
|
||||||
idx += 1
|
let recent = %*{"items": map(newRecents, toJsonNode)}
|
||||||
|
discard backend.updateRecentGifs(recent)
|
||||||
|
|
||||||
self.recents = newRecents
|
proc getFavorites*(self: Service): seq[GifDto] =
|
||||||
let recent = %*{"items": map(newRecents, toJsonNode)}
|
return self.favorites
|
||||||
discard backend.updateRecentGifs(recent)
|
|
||||||
|
|
||||||
proc getFavorites*(self: Service): seq[GifDto] =
|
proc isFavorite*(self: Service, gifDto: GifDto): bool =
|
||||||
return self.favorites
|
for favorite in self.favorites:
|
||||||
|
if favorite.id == gifDto.id:
|
||||||
|
return true
|
||||||
|
return false
|
||||||
|
|
||||||
proc isFavorite*(self: Service, gifDto: GifDto): bool =
|
proc toggleFavorite*(self: Service, gifDto: GifDto) =
|
||||||
for favorite in self.favorites:
|
var newFavorites: seq[GifDto] = @[]
|
||||||
if favorite.id == gifDto.id:
|
var found = false
|
||||||
return true
|
|
||||||
return false
|
|
||||||
|
|
||||||
proc toggleFavorite*(self: Service, gifDto: GifDto) =
|
for favoriteGif in self.getFavorites():
|
||||||
var newFavorites: seq[GifDto] = @[]
|
if favoriteGif.id == gifDto.id:
|
||||||
var found = false
|
found = true
|
||||||
|
continue
|
||||||
|
|
||||||
for favoriteGif in self.getFavorites():
|
newFavorites.add(favoriteGif)
|
||||||
if favoriteGif.id == gifDto.id:
|
|
||||||
found = true
|
|
||||||
continue
|
|
||||||
|
|
||||||
newFavorites.add(favoriteGif)
|
if not found:
|
||||||
|
newFavorites.add(gifDto)
|
||||||
|
|
||||||
if not found:
|
self.favorites = newFavorites
|
||||||
newFavorites.add(gifDto)
|
let favorites = %*{"items": map(newFavorites, toJsonNode)}
|
||||||
|
discard backend.updateFavoriteGifs(favorites)
|
||||||
self.favorites = newFavorites
|
|
||||||
let favorites = %*{"items": map(newFavorites, toJsonNode)}
|
|
||||||
discard backend.updateFavoriteGifs(favorites)
|
|
||||||
|
13
src/backend/gifs.nim
Normal file
13
src/backend/gifs.nim
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import json, strutils
|
||||||
|
import core
|
||||||
|
import response_type
|
||||||
|
|
||||||
|
export response_type
|
||||||
|
|
||||||
|
proc getRecentGifs*(): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||||
|
let payload = %* []
|
||||||
|
result = callPrivateRPC("gif_getRecentGifs", payload)
|
||||||
|
|
||||||
|
proc getFavoriteGifs*(): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||||
|
let payload = %* []
|
||||||
|
result = callPrivateRPC("gif_getFavoriteGifs", payload)
|
Loading…
x
Reference in New Issue
Block a user