feat(Community): Community messaging statistics chart (#11696)
* feat(Community): Community messaging statistics chart Close 11152 - Use se `collectCommunityMessageMetrics` for messaging statistics chart in community overview * feat(Community): Transfer community metrics with dto objects * feat: impl simple string-based model for community metrics * fix(Community): Review fixes and fix for changing community when chat is open * Update src/app/modules/main/chat_section/controller.nim Co-authored-by: Jonathan Rainville <rainville.jonathan@gmail.com> --------- Co-authored-by: Jonathan Rainville <rainville.jonathan@gmail.com>
This commit is contained in:
parent
dd346319ff
commit
edba946a71
|
@ -169,6 +169,16 @@ proc init*(self: Controller) =
|
||||||
self.nodeConfigurationService, self.contactService, self.chatService, self.communityService,
|
self.nodeConfigurationService, self.contactService, self.chatService, self.communityService,
|
||||||
self.messageService, self.gifService, self.mailserversService, setChatAsActive = true)
|
self.messageService, self.gifService, self.mailserversService, setChatAsActive = true)
|
||||||
|
|
||||||
|
self.events.on(SIGNAL_COMMUNITY_METRICS_UPDATED) do(e: Args):
|
||||||
|
let args = CommunityMetricsArgs(e)
|
||||||
|
if args.communityId == self.sectionId:
|
||||||
|
let metrics = self.communityService.getCommunityMetrics(args.communityId, args.metricsType)
|
||||||
|
var strings: seq[string]
|
||||||
|
for interval in metrics.intervals:
|
||||||
|
for timestamp in interval.timestamps:
|
||||||
|
strings.add($timestamp)
|
||||||
|
self.delegate.setOverviewChartData("[" & join(strings, ", ") & "]")
|
||||||
|
|
||||||
self.events.on(SIGNAL_COMMUNITY_CHANNEL_DELETED) do(e:Args):
|
self.events.on(SIGNAL_COMMUNITY_CHANNEL_DELETED) do(e:Args):
|
||||||
let args = CommunityChatIdArgs(e)
|
let args = CommunityChatIdArgs(e)
|
||||||
if (args.communityId == self.sectionId):
|
if (args.communityId == self.sectionId):
|
||||||
|
@ -652,3 +662,6 @@ proc getContractAddressesForToken*(self: Controller, symbol: string): Table[int,
|
||||||
|
|
||||||
proc getCommunityTokenList*(self: Controller): seq[CommunityTokenDto] =
|
proc getCommunityTokenList*(self: Controller): seq[CommunityTokenDto] =
|
||||||
return self.communityTokensService.getCommunityTokens(self.getMySectionId())
|
return self.communityTokensService.getCommunityTokens(self.getMySectionId())
|
||||||
|
|
||||||
|
proc collectCommunityMetricsMessagesTimestamps*(self: Controller, intervals: string) =
|
||||||
|
self.communityService.collectCommunityMetricsMessagesTimestamps(self.getMySectionId(), intervals)
|
|
@ -349,6 +349,12 @@ method createOrEditCommunityTokenPermission*(self: AccessInterface, communityId:
|
||||||
method deleteCommunityTokenPermission*(self: AccessInterface, communityId: string, permissionId: string) {.base.} =
|
method deleteCommunityTokenPermission*(self: AccessInterface, communityId: string, permissionId: string) {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method collectCommunityMetricsMessagesTimestamps*(self: AccessInterface, intervals: string) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method setOverviewChartData*(self: AccessInterface, metrics: string) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
method onCommunityTokenPermissionCreated*(self: AccessInterface, communityId: string, tokenPermission: CommunityTokenPermissionDto) {.base.} =
|
method onCommunityTokenPermissionCreated*(self: AccessInterface, communityId: string, tokenPermission: CommunityTokenPermissionDto) {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
|
|
@ -1322,3 +1322,9 @@ method deleteCommunityTokenPermission*(self: Module, communityId: string, permis
|
||||||
|
|
||||||
method onDeactivateChatLoader*(self: Module, chatId: string) =
|
method onDeactivateChatLoader*(self: Module, chatId: string) =
|
||||||
self.view.chatsModel().disableChatLoader(chatId)
|
self.view.chatsModel().disableChatLoader(chatId)
|
||||||
|
|
||||||
|
method collectCommunityMetricsMessagesTimestamps*(self: Module, intervals: string) =
|
||||||
|
self.controller.collectCommunityMetricsMessagesTimestamps(intervals)
|
||||||
|
|
||||||
|
method setOverviewChartData*(self: Module, metrics: string) =
|
||||||
|
self.view.setOverviewChartData(metrics)
|
||||||
|
|
|
@ -27,6 +27,8 @@ QtObject:
|
||||||
requiresTokenPermissionToJoin: bool
|
requiresTokenPermissionToJoin: bool
|
||||||
amIMember: bool
|
amIMember: bool
|
||||||
chatsLoaded: bool
|
chatsLoaded: bool
|
||||||
|
communityMetrics: string # NOTE: later this should be replaced with QAbstractListModel-based model
|
||||||
|
|
||||||
|
|
||||||
proc delete*(self: View) =
|
proc delete*(self: View) =
|
||||||
self.model.delete
|
self.model.delete
|
||||||
|
@ -64,6 +66,7 @@ QtObject:
|
||||||
result.amIMember = false
|
result.amIMember = false
|
||||||
result.requiresTokenPermissionToJoin = false
|
result.requiresTokenPermissionToJoin = false
|
||||||
result.chatsLoaded = false
|
result.chatsLoaded = false
|
||||||
|
result.communityMetrics = "[]"
|
||||||
|
|
||||||
proc load*(self: View) =
|
proc load*(self: View) =
|
||||||
self.delegate.viewDidLoad()
|
self.delegate.viewDidLoad()
|
||||||
|
@ -409,3 +412,19 @@ QtObject:
|
||||||
QtProperty[bool] allTokenRequirementsMet:
|
QtProperty[bool] allTokenRequirementsMet:
|
||||||
read = getAllTokenRequirementsMet
|
read = getAllTokenRequirementsMet
|
||||||
notify = allTokenRequirementsMetChanged
|
notify = allTokenRequirementsMetChanged
|
||||||
|
|
||||||
|
proc getOverviewChartData*(self: View): QVariant {.slot.} =
|
||||||
|
return newQVariant(self.communityMetrics)
|
||||||
|
|
||||||
|
proc overviewChartDataChanged*(self: View) {.signal.}
|
||||||
|
|
||||||
|
QtProperty[QVariant] overviewChartData:
|
||||||
|
read = getOverviewChartData
|
||||||
|
notify = overviewChartDataChanged
|
||||||
|
|
||||||
|
proc setOverviewChartData*(self: View, communityMetrics: string) =
|
||||||
|
self.communityMetrics = communityMetrics
|
||||||
|
self.overviewChartDataChanged()
|
||||||
|
|
||||||
|
proc collectCommunityMetricsMessagesTimestamps*(self: View, intervals: string) {.slot.} =
|
||||||
|
self.delegate.collectCommunityMetricsMessagesTimestamps(intervals)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import stint
|
import stint, std/strutils
|
||||||
import ./io_interface
|
import ./io_interface
|
||||||
|
|
||||||
import ../../../core/signals/types
|
import ../../../core/signals/types
|
||||||
|
|
|
@ -24,6 +24,29 @@ const asyncLoadCommunitiesDataTask: Task = proc(argEncoded: string) {.gcsafe, ni
|
||||||
"error": e.msg,
|
"error": e.msg,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
type
|
||||||
|
AsyncCollectCommunityMetricsTaskArg = ref object of QObjectTaskArg
|
||||||
|
communityId: string
|
||||||
|
metricsType: CommunityMetricsType
|
||||||
|
intervals: JsonNode
|
||||||
|
|
||||||
|
const asyncCollectCommunityMetricsTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||||
|
let arg = decode[AsyncCollectCommunityMetricsTaskArg](argEncoded)
|
||||||
|
try:
|
||||||
|
let response = status_go.collectCommunityMetrics(arg.communityId, arg.metricsType.int, arg.intervals)
|
||||||
|
arg.finish(%* {
|
||||||
|
"communityId": arg.communityId,
|
||||||
|
"metricsType": arg.metricsType,
|
||||||
|
"response": response,
|
||||||
|
"error": "",
|
||||||
|
})
|
||||||
|
except Exception as e:
|
||||||
|
arg.finish(%* {
|
||||||
|
"communityId": arg.communityId,
|
||||||
|
"metricsType": arg.metricsType,
|
||||||
|
"error": e.msg,
|
||||||
|
})
|
||||||
|
|
||||||
type
|
type
|
||||||
AsyncRequestCommunityInfoTaskArg = ref object of QObjectTaskArg
|
AsyncRequestCommunityInfoTaskArg = ref object of QObjectTaskArg
|
||||||
communityId: string
|
communityId: string
|
||||||
|
|
|
@ -25,6 +25,13 @@ type MutedType* {.pure.}= enum
|
||||||
For1min = 6,
|
For1min = 6,
|
||||||
Unmuted = 7
|
Unmuted = 7
|
||||||
|
|
||||||
|
type
|
||||||
|
CommunityMetricsType* {.pure.} = enum
|
||||||
|
MessagesTimestamps = 0,
|
||||||
|
MessagesCount,
|
||||||
|
Members,
|
||||||
|
ControlNodeUptime
|
||||||
|
|
||||||
type CommunityMembershipRequestDto* = object
|
type CommunityMembershipRequestDto* = object
|
||||||
id*: string
|
id*: string
|
||||||
publicKey*: string
|
publicKey*: string
|
||||||
|
@ -88,6 +95,17 @@ type CheckPermissionsToJoinResponseDto* = object
|
||||||
permissions*: Table[string, CheckPermissionsResultDto]
|
permissions*: Table[string, CheckPermissionsResultDto]
|
||||||
validCombinations*: seq[AccountChainIDsCombinationDto]
|
validCombinations*: seq[AccountChainIDsCombinationDto]
|
||||||
|
|
||||||
|
type MetricsIntervalDto* = object
|
||||||
|
startTimestamp*: uint64
|
||||||
|
endTimestamp*: uint64
|
||||||
|
timestamps*: seq[uint64]
|
||||||
|
count*: int
|
||||||
|
|
||||||
|
type CommunityMetricsDto* = object
|
||||||
|
communityId*: string
|
||||||
|
metricsType*: CommunityMetricsType
|
||||||
|
intervals*: seq[MetricsIntervalDto]
|
||||||
|
|
||||||
type CommunityDto* = object
|
type CommunityDto* = object
|
||||||
id*: string
|
id*: string
|
||||||
memberRole*: MemberRole
|
memberRole*: MemberRole
|
||||||
|
@ -301,6 +319,34 @@ proc toCheckAllChannelsPermissionsResponseDto*(jsonObj: JsonNode): CheckAllChann
|
||||||
for channelId, permissionResponse in channelsObj:
|
for channelId, permissionResponse in channelsObj:
|
||||||
result.channels[channelId] = permissionResponse.toCheckChannelPermissionsResponseDto()
|
result.channels[channelId] = permissionResponse.toCheckChannelPermissionsResponseDto()
|
||||||
|
|
||||||
|
proc toMetricsIntervalDto*(jsonObj: JsonNode): MetricsIntervalDto =
|
||||||
|
result = MetricsIntervalDto()
|
||||||
|
discard jsonObj.getProp("startTimestamp", result.startTimestamp)
|
||||||
|
discard jsonObj.getProp("endTimestamp", result.endTimestamp)
|
||||||
|
|
||||||
|
var timestampsObj: JsonNode
|
||||||
|
if (jsonObj.getProp("timestamps", timestampsObj) and timestampsObj.kind == JArray):
|
||||||
|
for timestamp in timestampsObj:
|
||||||
|
result.timestamps.add(uint64(timestamp.getInt))
|
||||||
|
|
||||||
|
discard jsonObj.getProp("count", result.count)
|
||||||
|
|
||||||
|
proc toCommunityMetricsDto*(jsonObj: JsonNode): CommunityMetricsDto =
|
||||||
|
result = CommunityMetricsDto()
|
||||||
|
|
||||||
|
discard jsonObj.getProp("communityId", result.communityId)
|
||||||
|
|
||||||
|
result.metricsType = CommunityMetricsType.MessagesTimestamps
|
||||||
|
var metricsTypeInt: int
|
||||||
|
if (jsonObj.getProp("metricsType", metricsTypeInt) and (metricsTypeInt >= ord(low(CommunityMetricsType)) and
|
||||||
|
metricsTypeInt <= ord(high(CommunityMetricsType)))):
|
||||||
|
result.metricsType = CommunityMetricsType(metricsTypeInt)
|
||||||
|
|
||||||
|
var intervalsObj: JsonNode
|
||||||
|
if (jsonObj.getProp("intervals", intervalsObj) and intervalsObj.kind == JArray):
|
||||||
|
for interval in intervalsObj:
|
||||||
|
result.intervals.add(interval.toMetricsIntervalDto)
|
||||||
|
|
||||||
proc toCommunityDto*(jsonObj: JsonNode): CommunityDto =
|
proc toCommunityDto*(jsonObj: JsonNode): CommunityDto =
|
||||||
result = CommunityDto()
|
result = CommunityDto()
|
||||||
discard jsonObj.getProp("id", result.id)
|
discard jsonObj.getProp("id", result.id)
|
||||||
|
|
|
@ -121,6 +121,10 @@ type
|
||||||
communityId*: string
|
communityId*: string
|
||||||
checkPermissionsToJoinResponse*: CheckPermissionsToJoinResponseDto
|
checkPermissionsToJoinResponse*: CheckPermissionsToJoinResponseDto
|
||||||
|
|
||||||
|
CommunityMetricsArgs* = ref object of Args
|
||||||
|
communityId*: string
|
||||||
|
metricsType*: CommunityMetricsType
|
||||||
|
|
||||||
# Signals which may be emitted by this service:
|
# Signals which may be emitted by this service:
|
||||||
const SIGNAL_COMMUNITY_DATA_LOADED* = "communityDataLoaded"
|
const SIGNAL_COMMUNITY_DATA_LOADED* = "communityDataLoaded"
|
||||||
const SIGNAL_COMMUNITY_JOINED* = "communityJoined"
|
const SIGNAL_COMMUNITY_JOINED* = "communityJoined"
|
||||||
|
@ -189,6 +193,8 @@ const SIGNAL_CHECK_PERMISSIONS_TO_JOIN_RESPONSE* = "checkPermissionsToJoinRespon
|
||||||
|
|
||||||
const SIGNAL_COMMUNITY_PRIVATE_KEY_REMOVED* = "communityPrivateKeyRemoved"
|
const SIGNAL_COMMUNITY_PRIVATE_KEY_REMOVED* = "communityPrivateKeyRemoved"
|
||||||
|
|
||||||
|
const SIGNAL_COMMUNITY_METRICS_UPDATED* = "communityMetricsUpdated"
|
||||||
|
|
||||||
QtObject:
|
QtObject:
|
||||||
type
|
type
|
||||||
Service* = ref object of QObject
|
Service* = ref object of QObject
|
||||||
|
@ -202,6 +208,7 @@ QtObject:
|
||||||
myCommunityRequests*: seq[CommunityMembershipRequestDto]
|
myCommunityRequests*: seq[CommunityMembershipRequestDto]
|
||||||
historyArchiveDownloadTaskCommunityIds*: HashSet[string]
|
historyArchiveDownloadTaskCommunityIds*: HashSet[string]
|
||||||
requestedCommunityIds*: HashSet[string]
|
requestedCommunityIds*: HashSet[string]
|
||||||
|
communityMetrics: Table[string, CommunityMetricsDto]
|
||||||
|
|
||||||
# Forward declaration
|
# Forward declaration
|
||||||
proc asyncLoadCuratedCommunities*(self: Service)
|
proc asyncLoadCuratedCommunities*(self: Service)
|
||||||
|
@ -237,6 +244,7 @@ QtObject:
|
||||||
result.myCommunityRequests = @[]
|
result.myCommunityRequests = @[]
|
||||||
result.historyArchiveDownloadTaskCommunityIds = initHashSet[string]()
|
result.historyArchiveDownloadTaskCommunityIds = initHashSet[string]()
|
||||||
result.requestedCommunityIds = initHashSet[string]()
|
result.requestedCommunityIds = initHashSet[string]()
|
||||||
|
result.communityMetrics = initTable[string, CommunityMetricsDto]()
|
||||||
|
|
||||||
proc getFilteredJoinedCommunities(self: Service): Table[string, CommunityDto] =
|
proc getFilteredJoinedCommunities(self: Service): Table[string, CommunityDto] =
|
||||||
result = initTable[string, CommunityDto]()
|
result = initTable[string, CommunityDto]()
|
||||||
|
@ -1359,6 +1367,18 @@ QtObject:
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
error "Error reordering category channel", msg = e.msg, communityId, categoryId, position
|
error "Error reordering category channel", msg = e.msg, communityId, categoryId, position
|
||||||
|
|
||||||
|
proc asyncCommunityMetricsLoaded*(self: Service, rpcResponse: string) {.slot.} =
|
||||||
|
let rpcResponseObj = rpcResponse.parseJson
|
||||||
|
if rpcResponseObj{"error"}.kind != JNull and rpcResponseObj{"error"}.getStr != "":
|
||||||
|
error "Error collecting community metrics", msg = rpcResponseObj{"error"}
|
||||||
|
return
|
||||||
|
|
||||||
|
let communityId = rpcResponseObj{"communityId"}.getStr()
|
||||||
|
let metricsType = rpcResponseObj{"metricsType"}.getInt()
|
||||||
|
|
||||||
|
var metrics = rpcResponseObj{"response"}{"result"}.toCommunityMetricsDto()
|
||||||
|
self.communityMetrics[communityId] = metrics
|
||||||
|
self.events.emit(SIGNAL_COMMUNITY_METRICS_UPDATED, CommunityMetricsArgs(communityId: communityId, metricsType: metrics.metricsType))
|
||||||
|
|
||||||
proc asyncCommunityInfoLoaded*(self: Service, communityIdAndRpcResponse: string) {.slot.} =
|
proc asyncCommunityInfoLoaded*(self: Service, communityIdAndRpcResponse: string) {.slot.} =
|
||||||
let rpcResponseObj = communityIdAndRpcResponse.parseJson
|
let rpcResponseObj = communityIdAndRpcResponse.parseJson
|
||||||
|
@ -1551,6 +1571,34 @@ QtObject:
|
||||||
error "error loading curated communities: ", errMsg
|
error "error loading curated communities: ", errMsg
|
||||||
self.events.emit(SIGNAL_CURATED_COMMUNITIES_LOADING_FAILED, Args())
|
self.events.emit(SIGNAL_CURATED_COMMUNITIES_LOADING_FAILED, Args())
|
||||||
|
|
||||||
|
proc getCommunityMetrics*(self: Service, communityId: string, metricsType: CommunityMetricsType): CommunityMetricsDto =
|
||||||
|
# NOTE: use metricsType when other metrics types added
|
||||||
|
if self.communityMetrics.hasKey(communityId):
|
||||||
|
return self.communityMetrics[communityId]
|
||||||
|
return CommunityMetricsDto()
|
||||||
|
|
||||||
|
proc collectCommunityMetricsMessagesTimestamps*(self: Service, communityId: string, intervals: string) =
|
||||||
|
let arg = AsyncCollectCommunityMetricsTaskArg(
|
||||||
|
tptr: cast[ByteAddress](asyncCollectCommunityMetricsTask),
|
||||||
|
vptr: cast[ByteAddress](self.vptr),
|
||||||
|
slot: "asyncCommunityMetricsLoaded",
|
||||||
|
communityId: communityId,
|
||||||
|
metricsType: CommunityMetricsType.MessagesTimestamps,
|
||||||
|
intervals: parseJson(intervals)
|
||||||
|
)
|
||||||
|
self.threadpool.start(arg)
|
||||||
|
|
||||||
|
proc collectCommunityMetricsMessagesCount*(self: Service, communityId: string, intervals: string) =
|
||||||
|
let arg = AsyncCollectCommunityMetricsTaskArg(
|
||||||
|
tptr: cast[ByteAddress](asyncCollectCommunityMetricsTask),
|
||||||
|
vptr: cast[ByteAddress](self.vptr),
|
||||||
|
slot: "asyncCommunityMetricsLoaded",
|
||||||
|
communityId: communityId,
|
||||||
|
metricsType: CommunityMetricsType.MessagesCount,
|
||||||
|
intervals: parseJson(intervals)
|
||||||
|
)
|
||||||
|
self.threadpool.start(arg)
|
||||||
|
|
||||||
proc requestCommunityInfo*(self: Service, communityId: string, importing = false) =
|
proc requestCommunityInfo*(self: Service, communityId: string, importing = false) =
|
||||||
|
|
||||||
if communityId in self.requestedCommunityIds:
|
if communityId in self.requestedCommunityIds:
|
||||||
|
|
|
@ -352,6 +352,15 @@ proc deleteCommunityCategory*(
|
||||||
"categoryId": categoryId
|
"categoryId": categoryId
|
||||||
}])
|
}])
|
||||||
|
|
||||||
|
proc collectCommunityMetrics*(communityId: string, metricsType: int, intervals: JsonNode
|
||||||
|
):RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||||
|
result = callPrivateRPC("collectCommunityMetrics".prefix, %*[
|
||||||
|
{
|
||||||
|
"communityId": communityId,
|
||||||
|
"type": metricsType,
|
||||||
|
"intervals": intervals
|
||||||
|
}])
|
||||||
|
|
||||||
proc requestCommunityInfo*(communityId: string): RpcResponse[JsonNode] {.raises: [Exception].} =
|
proc requestCommunityInfo*(communityId: string): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||||
result = callPrivateRPC("requestCommunityInfoFromMailserver".prefix, %*[communityId])
|
result = callPrivateRPC("requestCommunityInfoFromMailserver".prefix, %*[communityId])
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,8 @@ QtObject {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
readonly property string overviewChartData: chatCommunitySectionModule.overviewChartData
|
||||||
|
|
||||||
readonly property bool isUserAllowedToSendMessage: _d.isUserAllowedToSendMessage
|
readonly property bool isUserAllowedToSendMessage: _d.isUserAllowedToSendMessage
|
||||||
readonly property string chatInputPlaceHolderText: _d.chatInputPlaceHolderText
|
readonly property string chatInputPlaceHolderText: _d.chatInputPlaceHolderText
|
||||||
readonly property var oneToOneChatContact: _d.oneToOneChatContact
|
readonly property var oneToOneChatContact: _d.oneToOneChatContact
|
||||||
|
@ -416,6 +418,11 @@ QtObject {
|
||||||
return communitiesList.getSectionByIdJson(id)
|
return communitiesList.getSectionByIdJson(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// intervals is a string containing json array [{startTimestamp: 1690548852, startTimestamp: 1690547684}, {...}]
|
||||||
|
function collectCommunityMetricsMessagesTimestamps(intervals) {
|
||||||
|
chatCommunitySectionModule.collectCommunityMetricsMessagesTimestamps(intervals)
|
||||||
|
}
|
||||||
|
|
||||||
function requestCommunityInfo(id, importing = false) {
|
function requestCommunityInfo(id, importing = false) {
|
||||||
communitiesModuleInst.requestCommunityInfo(id, importing)
|
communitiesModuleInst.requestCommunityInfo(id, importing)
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,20 @@ StatusChartPanel {
|
||||||
*/
|
*/
|
||||||
property var model: []
|
property var model: []
|
||||||
|
|
||||||
|
signal collectCommunityMetricsMessagesTimestamps(var intervals)
|
||||||
|
|
||||||
|
function requestCommunityMetrics() {
|
||||||
|
let intervals = d.selectedTabInfo.modelItems.map(item => {
|
||||||
|
return {
|
||||||
|
startTimestamp: item.start,
|
||||||
|
endTimestamp: item.end
|
||||||
|
}
|
||||||
|
})
|
||||||
|
collectCommunityMetricsMessagesTimestamps(JSON.stringify(intervals))
|
||||||
|
}
|
||||||
|
|
||||||
|
onVisibleChanged: if (visible) requestCommunityMetrics()
|
||||||
|
|
||||||
QtObject {
|
QtObject {
|
||||||
id: d
|
id: d
|
||||||
|
|
||||||
|
@ -219,6 +233,8 @@ StatusChartPanel {
|
||||||
return leftPositon ? Qt.point(relativeMousePoint.x - toolTip.width - 15, relativeMousePoint.y - 5)
|
return leftPositon ? Qt.point(relativeMousePoint.x - toolTip.width - 15, relativeMousePoint.y - 5)
|
||||||
: Qt.point(relativeMousePoint.x + 15, relativeMousePoint.y - 5)
|
: Qt.point(relativeMousePoint.x + 15, relativeMousePoint.y - 5)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onSelectedTabInfoChanged: root.requestCommunityMetrics()
|
||||||
}
|
}
|
||||||
headerLeftPadding: 0
|
headerLeftPadding: 0
|
||||||
headerBottomPadding: Style.current.bigPadding
|
headerBottomPadding: Style.current.bigPadding
|
||||||
|
|
|
@ -40,6 +40,8 @@ StackLayout {
|
||||||
property int loginType: Constants.LoginType.Password
|
property int loginType: Constants.LoginType.Password
|
||||||
property bool communitySettingsDisabled
|
property bool communitySettingsDisabled
|
||||||
|
|
||||||
|
property string overviewChartData: ""
|
||||||
|
|
||||||
function navigateBack() {
|
function navigateBack() {
|
||||||
if (editSettingsPanelLoader.item.dirty)
|
if (editSettingsPanelLoader.item.dirty)
|
||||||
settingsDirtyToastMessage.notifyDirty()
|
settingsDirtyToastMessage.notifyDirty()
|
||||||
|
@ -47,6 +49,8 @@ StackLayout {
|
||||||
root.currentIndex = 0
|
root.currentIndex = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
signal collectCommunityMetricsMessagesTimestamps(var intervals)
|
||||||
|
|
||||||
signal edited(Item item) // item containing edited fields (name, description, logoImagePath, color, options, etc..)
|
signal edited(Item item) // item containing edited fields (name, description, logoImagePath, color, options, etc..)
|
||||||
|
|
||||||
signal inviteNewPeopleClicked
|
signal inviteNewPeopleClicked
|
||||||
|
@ -113,11 +117,21 @@ StackLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
OverviewSettingsChart {
|
OverviewSettingsChart {
|
||||||
|
model: JSON.parse(root.overviewChartData)
|
||||||
|
onCollectCommunityMetricsMessagesTimestamps: {
|
||||||
|
root.collectCommunityMetricsMessagesTimestamps(intervals)
|
||||||
|
}
|
||||||
Layout.topMargin: 16
|
Layout.topMargin: 16
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
Layout.bottomMargin: 16
|
Layout.bottomMargin: 16
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: root
|
||||||
|
onCommunityIdChanged: requestCommunityMetrics()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
|
|
@ -176,6 +176,11 @@ StatusSectionLayout {
|
||||||
loginType: root.rootStore.loginType
|
loginType: root.rootStore.loginType
|
||||||
isControlNode: root.isControlNode
|
isControlNode: root.isControlNode
|
||||||
communitySettingsDisabled: root.communitySettingsDisabled
|
communitySettingsDisabled: root.communitySettingsDisabled
|
||||||
|
overviewChartData: rootStore.overviewChartData
|
||||||
|
|
||||||
|
onCollectCommunityMetricsMessagesTimestamps: {
|
||||||
|
rootStore.collectCommunityMetricsMessagesTimestamps(intervals)
|
||||||
|
}
|
||||||
|
|
||||||
onEdited: {
|
onEdited: {
|
||||||
const error = root.chatCommunitySectionModule.editCommunity(
|
const error = root.chatCommunitySectionModule.editCommunity(
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 0ae7aa44f00bff345539c1e288705057e7e4574c
|
Subproject commit 4ad84d80cc7b0363f3c8da589d7bb8930fb8a629
|
Loading…
Reference in New Issue