mirror of
https://github.com/status-im/status-desktop.git
synced 2025-01-25 14:00:00 +00:00
e0c53b7012
From now on we are able to access local settings (settings and global settings) on the nim side, not only through the qml. This change is required as part of the feature issue-2675.
780 lines
30 KiB
QML
780 lines
30 KiB
QML
import QtQuick 2.13
|
|
import QtQuick.Controls 2.13
|
|
import QtQuick.Layouts 1.13
|
|
import QtMultimedia 5.13
|
|
import "../imports"
|
|
import "../sounds"
|
|
import "../shared"
|
|
import "../shared/status"
|
|
import "./AppLayouts"
|
|
import "./AppLayouts/Timeline"
|
|
import "./AppLayouts/Wallet"
|
|
import "./AppLayouts/WalletV2"
|
|
import "./AppLayouts/Chat/components"
|
|
import "./AppLayouts/Chat/CommunityComponents"
|
|
import "./AppLayouts/Profile/Sections"
|
|
|
|
import Qt.labs.platform 1.1
|
|
import Qt.labs.settings 1.0
|
|
|
|
import StatusQ.Core.Theme 0.1
|
|
import StatusQ.Controls 0.1
|
|
import StatusQ.Layout 0.1
|
|
import StatusQ.Popups 0.1
|
|
|
|
|
|
Item {
|
|
id: appMain
|
|
anchors.fill: parent
|
|
|
|
property alias appLayout: appLayout
|
|
property var newVersionJSON: JSON.parse(utilsModel.newVersion)
|
|
property bool profilePopupOpened: false
|
|
property bool networkGuarded: profileModel.network.current === Constants.networkMainnet || (profileModel.network.current === Constants.networkRopsten && appSettings.stickersEnsRopsten)
|
|
|
|
signal settingsLoaded()
|
|
signal openContactsPopup()
|
|
|
|
function changeAppSection(section) {
|
|
chatsModel.communities.activeCommunity.active = false
|
|
appView.currentIndex = Utils.getAppSectionIndex(section)
|
|
}
|
|
|
|
function getProfileImage(pubkey, isCurrentUser, useLargeImage) {
|
|
if (isCurrentUser || (isCurrentUser === undefined && pubkey === profileModel.profile.pubKey)) {
|
|
return profileModel.profile.thumbnailImage
|
|
}
|
|
|
|
const index = profileModel.contacts.list.getContactIndexByPubkey(pubkey)
|
|
if (index === -1) {
|
|
return
|
|
}
|
|
|
|
if (appSettings.onlyShowContactsProfilePics) {
|
|
const isContact = profileModel.contacts.list.rowData(index, "isContact")
|
|
if (isContact === "false") {
|
|
return
|
|
}
|
|
}
|
|
|
|
return profileModel.contacts.list.rowData(index, useLargeImage ? "largeImage" : "thumbnailImage")
|
|
}
|
|
|
|
function openPopup(popupComponent, params = {}) {
|
|
const popup = popupComponent.createObject(appMain, params);
|
|
popup.open()
|
|
return popup
|
|
}
|
|
|
|
function getContactListObject(dataModel) {
|
|
const nbContacts = profileModel.contacts.list.rowCount()
|
|
const contacts = []
|
|
let contact
|
|
for (let i = 0; i < nbContacts; i++) {
|
|
if (profileModel.contacts.list.rowData(i, "isBlocked") === "true") {
|
|
continue
|
|
}
|
|
|
|
contact = {
|
|
name: profileModel.contacts.list.rowData(i, "name"),
|
|
localNickname: profileModel.contacts.list.rowData(i, "localNickname"),
|
|
pubKey: profileModel.contacts.list.rowData(i, "pubKey"),
|
|
address: profileModel.contacts.list.rowData(i, "address"),
|
|
identicon: profileModel.contacts.list.rowData(i, "identicon"),
|
|
thumbnailImage: profileModel.contacts.list.rowData(i, "thumbnailImage"),
|
|
isUser: false,
|
|
isContact: profileModel.contacts.list.rowData(i, "isContact") !== "false"
|
|
}
|
|
|
|
contacts.push(contact)
|
|
if (dataModel) {
|
|
dataModel.append(contact);
|
|
}
|
|
}
|
|
return contacts
|
|
}
|
|
|
|
function getUserNickname(pubKey) {
|
|
// Get contact nickname
|
|
const contactList = profileModel.contacts.list
|
|
const contactCount = contactList.rowCount()
|
|
for (let i = 0; i < contactCount; i++) {
|
|
if (contactList.rowData(i, 'pubKey') === pubKey) {
|
|
return contactList.rowData(i, 'localNickname')
|
|
}
|
|
}
|
|
return ""
|
|
}
|
|
|
|
function openLink(link) {
|
|
if (appSettings.showBrowserSelector) {
|
|
appMain.openPopup(chooseBrowserPopupComponent, {link: link})
|
|
} else {
|
|
if (appSettings.openLinksInStatus) {
|
|
appMain.changeAppSection(Constants.browser)
|
|
browserLayoutContainer.item.openUrlInNewTab(link)
|
|
} else {
|
|
Qt.openUrlExternally(link)
|
|
}
|
|
}
|
|
}
|
|
|
|
function openProfilePopup(userNameParam, fromAuthorParam, identiconParam, textParam, nicknameParam, parentPopup){
|
|
var popup = profilePopupComponent.createObject(appMain);
|
|
if(parentPopup){
|
|
popup.parentPopup = parentPopup;
|
|
}
|
|
popup.openPopup(profileModel.profile.pubKey !== fromAuthorParam, userNameParam, fromAuthorParam, identiconParam, textParam, nicknameParam);
|
|
profilePopupOpened = true
|
|
}
|
|
|
|
property Component profilePopupComponent: ProfilePopup {
|
|
id: profilePopup
|
|
onClosed: {
|
|
if(profilePopup.parentPopup){
|
|
profilePopup.parentPopup.close();
|
|
}
|
|
profilePopupOpened = false
|
|
destroy()
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: downloadModalComponent
|
|
DownloadModal {
|
|
onClosed: {
|
|
destroy();
|
|
}
|
|
}
|
|
}
|
|
|
|
ErrorSound {
|
|
id: errorSound
|
|
}
|
|
|
|
Audio {
|
|
id: sendMessageSound
|
|
audioRole: Audio.NotificationRole
|
|
source: "../../../../sounds/send_message.wav"
|
|
volume: appSettings.volume
|
|
muted: !appSettings.notificationSoundsEnabled
|
|
}
|
|
|
|
Audio {
|
|
id: notificationSound
|
|
audioRole: Audio.NotificationRole
|
|
source: "../../../../sounds/notification.wav"
|
|
volume: appSettings.volume
|
|
muted: !appSettings.notificationSoundsEnabled
|
|
}
|
|
|
|
ModuleWarning {
|
|
id: versionWarning
|
|
width: parent.width
|
|
visible: newVersionJSON.available
|
|
color: Style.current.green
|
|
btnWidth: 100
|
|
text: qsTr("A new version of Status (%1) is available").arg(newVersionJSON.version)
|
|
btnText: qsTr("Download")
|
|
onClick: function(){
|
|
openPopup(downloadModalComponent, {newVersionAvailable: newVersionJSON.available, downloadURL: newVersionJSON.url})
|
|
}
|
|
}
|
|
|
|
ModuleWarning {
|
|
id: mnemonicBackupWarning
|
|
width: parent.width
|
|
visible: appSettings.isWalletEnabled && !profileModel.mnemonic.isBackedUp && appView.currentIndex == Utils.getAppSectionIndex(Constants.wallet)
|
|
color: Style.current.red
|
|
//% "Back up your seed phrase"
|
|
text: qsTrId("back-up-your-seed-phrase")
|
|
btnText: qsTr("Back up")
|
|
onClick: function() {
|
|
openPopup(backupSeedModalComponent);
|
|
}
|
|
}
|
|
|
|
StatusAppLayout {
|
|
id: appLayout
|
|
|
|
width: parent.width
|
|
anchors.top: parent.top
|
|
anchors.topMargin: (versionWarning.visible || mnemonicBackupWarning.visible) ? 32 : 0
|
|
anchors.bottom: parent.bottom
|
|
|
|
appNavBar: StatusAppNavBar {
|
|
height: appMain.height
|
|
|
|
navBarChatButton: StatusNavBarTabButton {
|
|
icon.name: "chat"
|
|
checked: !chatsModel.communities.activeCommunity.active && appView.currentIndex === Utils.getAppSectionIndex(Constants.chat)
|
|
//% "Chat"
|
|
tooltip.text: qsTrId("chat")
|
|
badge.value: chatsModel.messageView.unreadDirectMessagesAndMentionsCount + profileModel.contacts.contactRequests.count
|
|
badge.visible: badge.value > 0 || (chatsModel.messageView.unreadMessagesCount > 0 && !checked)
|
|
badge.anchors.rightMargin: badge.value > 0 ? 0 : 4
|
|
badge.anchors.topMargin: badge.value > 0 ? 4 : 5
|
|
badge.border.color: hovered ? Theme.palette.statusBadge.hoverBorderColor : Theme.palette.statusAppNavBar.backgroundColor
|
|
badge.border.width: 2
|
|
onClicked: {
|
|
if (chatsModel.communities.activeCommunity.active) {
|
|
chatLayoutContainer.chatColumn.input.hideExtendedArea();
|
|
chatsModel.communities.activeCommunity.active = false
|
|
}
|
|
appMain.changeAppSection(Constants.chat)
|
|
}
|
|
}
|
|
|
|
navBarCommunityTabButtons.model: appSettings.communitiesEnabled && chatsModel.communities.joinedCommunities
|
|
navBarCommunityTabButtons.delegate: StatusNavBarTabButton {
|
|
onClicked: {
|
|
appMain.changeAppSection(Constants.chat)
|
|
chatsModel.communities.setActiveCommunity(model.id)
|
|
}
|
|
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
|
|
checked: chatsModel.communities.activeCommunity.active && chatsModel.communities.activeCommunity.id === model.id
|
|
name: model.name
|
|
tooltip.text: model.name
|
|
icon.color: model.communityColor
|
|
icon.source: model.thumbnailImage
|
|
|
|
badge.value: model.unviewedMentionsCount + model.requestsCount
|
|
badge.visible: badge.value > 0 || (!checked && model.unviewedMessagesCount > 0)
|
|
badge.border.color: hovered ? Theme.palette.statusBadge.hoverBorderColor : Theme.palette.statusBadge.borderColor
|
|
badge.border.width: 2
|
|
badge.anchors.rightMargin: 4
|
|
badge.anchors.topMargin: 5
|
|
|
|
popupMenu: StatusPopupMenu {
|
|
id: communityContextMenu
|
|
|
|
openHandler: function () {
|
|
chatsModel.communities.setObservedCommunity(model.id)
|
|
}
|
|
|
|
StatusMenuItem {
|
|
//% "Invite People"
|
|
text: qsTrId("invite-people")
|
|
icon.name: "share-ios"
|
|
enabled: chatsModel.communities.observedCommunity.canManageUsers
|
|
onTriggered: openPopup(inviteFriendsToCommunityPopup, {
|
|
community: chatsModel.communities.observedCommunity
|
|
})
|
|
}
|
|
|
|
StatusMenuItem {
|
|
//% "View Community"
|
|
text: qsTrId("view-community")
|
|
icon.name: "group-chat"
|
|
onTriggered: openPopup(communityProfilePopup, {
|
|
community: chatsModel.communities.observedCommunity
|
|
})
|
|
}
|
|
|
|
StatusMenuItem {
|
|
enabled: chatsModel.communities.observedCommunity.admin
|
|
//% "Edit Community"
|
|
text: qsTrId("edit-community")
|
|
icon.name: "edit"
|
|
onTriggered: openPopup(editCommunityPopup, {community: chatsModel.communities.observedCommunity})
|
|
}
|
|
|
|
StatusMenuSeparator {}
|
|
|
|
StatusMenuItem {
|
|
//% "Leave Community"
|
|
text: qsTrId("leave-community")
|
|
icon.name: "arrow-right"
|
|
icon.width: 14
|
|
iconRotation: 180
|
|
type: StatusMenuItem.Type.Danger
|
|
onTriggered: chatsModel.communities.leaveCommunity(model.id)
|
|
}
|
|
}
|
|
}
|
|
|
|
navBarTabButtons: [
|
|
StatusNavBarTabButton {
|
|
icon.name: "wallet"
|
|
//% "Wallet"
|
|
tooltip.text: qsTrId("wallet")
|
|
visible: enabled
|
|
enabled: isExperimental === "1" || appSettings.isWalletEnabled
|
|
checked: appView.currentIndex == Utils.getAppSectionIndex(Constants.wallet)
|
|
onClicked: appMain.changeAppSection(Constants.wallet)
|
|
},
|
|
|
|
StatusNavBarTabButton {
|
|
//TODO temporary icon name, switch back to wallet
|
|
icon.name: "cancel"
|
|
tooltip.text: qsTr("Wallet v2 - do not use, under active development")
|
|
visible: enabled
|
|
enabled: isExperimental === "1" || appSettings.isWalletV2Enabled
|
|
checked: appView.currentIndex == Utils.getAppSectionIndex(Constants.walletv2)
|
|
onClicked: appMain.changeAppSection(Constants.walletv2)
|
|
},
|
|
|
|
StatusNavBarTabButton {
|
|
enabled: isExperimental === "1" || appSettings.isBrowserEnabled
|
|
visible: enabled
|
|
//% "Browser"
|
|
tooltip.text: qsTrId("browser")
|
|
icon.name: "browser"
|
|
checked: appView.currentIndex == Utils.getAppSectionIndex(Constants.browser)
|
|
onClicked: appMain.changeAppSection(Constants.browser)
|
|
},
|
|
|
|
StatusNavBarTabButton {
|
|
enabled: isExperimental === "1" || appSettings.timelineEnabled
|
|
visible: enabled
|
|
//% "Timeline"
|
|
tooltip.text: qsTrId("timeline")
|
|
icon.name: "status-update"
|
|
checked: appView.currentIndex == Utils.getAppSectionIndex(Constants.timeline)
|
|
onClicked: appMain.changeAppSection(Constants.timeline)
|
|
},
|
|
|
|
StatusNavBarTabButton {
|
|
enabled: isExperimental === "1" || appSettings.nodeManagementEnabled
|
|
visible: enabled
|
|
tooltip.text: qsTr("Node Management")
|
|
icon.name: "node"
|
|
checked: appView.currentIndex == Utils.getAppSectionIndex(Constants.node)
|
|
onClicked: appMain.changeAppSection(Constants.node)
|
|
},
|
|
|
|
StatusNavBarTabButton {
|
|
id: profileBtn
|
|
//% "Settings"
|
|
tooltip.text: qsTrId("settings")
|
|
icon.name: "profile"
|
|
checked: appView.currentIndex == Utils.getAppSectionIndex(Constants.profile)
|
|
onClicked: appMain.changeAppSection(Constants.profile)
|
|
|
|
badge.visible: !profileModel.mnemonic.isBackedUp
|
|
badge.anchors.rightMargin: 4
|
|
badge.anchors.topMargin: 5
|
|
badge.border.color: hovered ? Theme.palette.statusBadge.hoverBorderColor : Theme.palette.statusAppNavBar.backgroundColor
|
|
badge.border.width: 2
|
|
}
|
|
]
|
|
|
|
navBarProfileButton: StatusNavBarTabButton {
|
|
id: profileButton
|
|
icon.source: profileModel.profile.thumbnailImage || ""
|
|
badge.visible: true
|
|
badge.anchors.rightMargin: 4
|
|
badge.anchors.topMargin: 25
|
|
badge.implicitHeight: 15
|
|
badge.implicitWidth: 15
|
|
badge.border.color: hovered ? Theme.palette.statusBadge.hoverBorderColor : Theme.palette.statusAppNavBar.backgroundColor
|
|
badge.color: {
|
|
return profileModel.profile.sendUserStatus ? Style.current.green : Style.current.midGrey
|
|
/*
|
|
// Use this code once support for custom user status is added
|
|
switch(profileModel.profile.currentUserStatus){
|
|
case Constants.statusType_Online:
|
|
return Style.current.green;
|
|
case Constants.statusType_DoNotDisturb:
|
|
return Style.current.red;
|
|
default:
|
|
return Style.current.midGrey;
|
|
}*/
|
|
}
|
|
badge.border.width: 3
|
|
onClicked: userStatusContextMenu.open()
|
|
|
|
UserStatusContextMenu {
|
|
id: userStatusContextMenu
|
|
y: profileButton.y - userStatusContextMenu.height
|
|
}
|
|
}
|
|
}
|
|
|
|
appView: StackLayout {
|
|
id: appView
|
|
anchors.fill: parent
|
|
currentIndex: 0
|
|
onCurrentIndexChanged: {
|
|
var obj = this.children[currentIndex];
|
|
if(!obj)
|
|
return
|
|
|
|
if (obj.onActivated && typeof obj.onActivated === "function") {
|
|
this.children[currentIndex].onActivated()
|
|
}
|
|
|
|
if(obj === browserLayoutContainer && browserLayoutContainer.active == false){
|
|
browserLayoutContainer.active = true;
|
|
}
|
|
|
|
timelineLayoutContainer.active = obj === timelineLayoutContainer
|
|
|
|
if(obj === walletLayoutContainer){
|
|
walletLayoutContainer.showSigningPhrasePopup();
|
|
}
|
|
|
|
if(obj === walletV2LayoutContainer){
|
|
walletV2LayoutContainer.showSigningPhrasePopup();
|
|
}
|
|
}
|
|
|
|
ChatLayout {
|
|
id: chatLayoutContainer
|
|
Layout.fillWidth: true
|
|
Layout.alignment: Qt.AlignLeft | Qt.AlignTop
|
|
Layout.fillHeight: true
|
|
onProfileButtonClicked: {
|
|
appMain.changeAppSection(Constants.profile);
|
|
}
|
|
}
|
|
|
|
WalletLayout {
|
|
id: walletLayoutContainer
|
|
Layout.fillWidth: true
|
|
Layout.alignment: Qt.AlignLeft | Qt.AlignTop
|
|
Layout.fillHeight: true
|
|
}
|
|
|
|
Component {
|
|
id: browserLayoutComponent
|
|
BrowserLayout { }
|
|
}
|
|
|
|
Loader {
|
|
id: browserLayoutContainer
|
|
sourceComponent: browserLayoutComponent
|
|
active: false
|
|
Layout.fillWidth: true
|
|
Layout.alignment: Qt.AlignLeft | Qt.AlignTop
|
|
Layout.fillHeight: true
|
|
// Loaders do not have access to the context, so props need to be set
|
|
// Adding a "_" to avoid a binding loop
|
|
property var _chatsModel: chatsModel.messageView
|
|
property var _walletModel: walletModel
|
|
property var _utilsModel: utilsModel
|
|
property var _web3Provider: web3Provider
|
|
}
|
|
|
|
Loader {
|
|
id: timelineLayoutContainer
|
|
sourceComponent: Component {
|
|
TimelineLayout {}
|
|
}
|
|
onLoaded: timelineLayoutContainer.item.onActivated()
|
|
active: false
|
|
Layout.fillWidth: true
|
|
Layout.alignment: Qt.AlignLeft | Qt.AlignTop
|
|
Layout.fillHeight: true
|
|
}
|
|
|
|
ProfileLayout {
|
|
id: profileLayoutContainer
|
|
Layout.fillWidth: true
|
|
Layout.alignment: Qt.AlignLeft | Qt.AlignTop
|
|
Layout.fillHeight: true
|
|
}
|
|
|
|
NodeLayout {
|
|
id: nodeLayoutContainer
|
|
Layout.fillWidth: true
|
|
Layout.alignment: Qt.AlignLeft | Qt.AlignTop
|
|
Layout.fillHeight: true
|
|
}
|
|
|
|
UIComponents {
|
|
Layout.fillWidth: true
|
|
Layout.alignment: Qt.AlignLeft | Qt.AlignTop
|
|
Layout.fillHeight: true
|
|
}
|
|
|
|
WalletV2Layout {
|
|
id: walletV2LayoutContainer
|
|
Layout.fillWidth: true
|
|
Layout.alignment: Qt.AlignLeft | Qt.AlignTop
|
|
Layout.fillHeight: true
|
|
}
|
|
}
|
|
|
|
|
|
Connections {
|
|
target: profileModel
|
|
|
|
onSettingsFileChanged: {
|
|
// 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.
|
|
//
|
|
// Prior to this change, most likely many users are still using the
|
|
// normal mode configuration, so we have to enforce compact mode for
|
|
// those.
|
|
if (!appSettings.useCompactMode) {
|
|
appSettings.useCompactMode = true
|
|
}
|
|
|
|
const whitelist = profileModel.getLinkPreviewWhitelist()
|
|
try {
|
|
const whiteListedSites = JSON.parse(whitelist)
|
|
let settingsUpdated = false
|
|
|
|
// Add Status links to whitelist
|
|
whiteListedSites.push({title: "Status", address: Constants.deepLinkPrefix, imageSite: false})
|
|
whiteListedSites.push({title: "Status", address: Constants.joinStatusLink, imageSite: false})
|
|
const settings = appSettings.whitelistedUnfurlingSites
|
|
|
|
// Set Status links as true. We intercept thoseURLs so it is privacy-safe
|
|
if (!settings[Constants.deepLinkPrefix] || !settings[Constants.joinStatusLink]) {
|
|
settings[Constants.deepLinkPrefix] = true
|
|
settings[Constants.joinStatusLink] = true
|
|
settingsUpdated = true
|
|
}
|
|
|
|
const whitelistedHostnames = []
|
|
|
|
// Add whitelisted sites in to app settings that are not already there
|
|
whiteListedSites.forEach(site => {
|
|
if (!settings.hasOwnProperty(site.address)) {
|
|
settings[site.address] = false
|
|
settingsUpdated = true
|
|
}
|
|
whitelistedHostnames.push(site.address)
|
|
})
|
|
// Remove any whitelisted sites from app settings that don't exist in the
|
|
// whitelist from status-go
|
|
Object.keys(settings).forEach(settingsHostname => {
|
|
if (!whitelistedHostnames.includes(settingsHostname)) {
|
|
delete settings[settingsHostname]
|
|
settingsUpdated = true
|
|
}
|
|
})
|
|
if (settingsUpdated) {
|
|
appSettings.whitelistedUnfurlingSites = settings
|
|
}
|
|
} catch (e) {
|
|
console.error('Could not parse the whitelist for sites', e)
|
|
}
|
|
appMain.settingsLoaded()
|
|
}
|
|
}
|
|
|
|
Connections {
|
|
target: chatsModel
|
|
onNotificationClicked: {
|
|
applicationWindow.makeStatusAppActive()
|
|
|
|
switch(notificationType){
|
|
case Constants.osNotificationType.newContactRequest:
|
|
appView.currentIndex = Utils.getAppSectionIndex(Constants.chat)
|
|
appMain.openContactsPopup()
|
|
break
|
|
case Constants.osNotificationType.acceptedContactRequest:
|
|
appView.currentIndex = Utils.getAppSectionIndex(Constants.chat)
|
|
break
|
|
case Constants.osNotificationType.joinCommunityRequest:
|
|
case Constants.osNotificationType.acceptedIntoCommunity:
|
|
case Constants.osNotificationType.rejectedByCommunity:
|
|
appView.currentIndex = Utils.getAppSectionIndex(Constants.community)
|
|
break
|
|
case Constants.osNotificationType.newMessage:
|
|
appView.currentIndex = Utils.getAppSectionIndex(Constants.chat)
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
Connections {
|
|
target: profileModel
|
|
ignoreUnknownSignals: true
|
|
enabled: removeMnemonicAfterLogin
|
|
onInitialized: {
|
|
profileModel.mnemonic.remove()
|
|
}
|
|
}
|
|
|
|
Connections {
|
|
target: profileModel.contacts
|
|
onContactRequestAdded: {
|
|
if (!appSettings.notifyOnNewRequests) {
|
|
return
|
|
}
|
|
|
|
const isContact = profileModel.contacts.isAdded(address)
|
|
|
|
// Note:
|
|
// Whole this Connection object should be moved to the nim side.
|
|
// Left here only cause we don't have a way to deal with translations on the nim side.
|
|
|
|
//% "Contact request accepted"
|
|
profileModel.showOSNotification(isContact ? qsTrId("contact-request-accepted") :
|
|
//% "New contact request"
|
|
qsTrId("new-contact-request"),
|
|
//% "You can now chat with %1"
|
|
isContact ? qsTrId("you-can-now-chat-with--1").arg(Utils.removeStatusEns(name)) :
|
|
//% "%1 requests to become contacts"
|
|
qsTrId("-1-requests-to-become-contacts").arg(Utils.removeStatusEns(name)),
|
|
isContact? Constants.osNotificationType.acceptedContactRequest :
|
|
Constants.osNotificationType.newContactRequest,
|
|
appSettings.useOSNotifications)
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: chooseBrowserPopupComponent
|
|
ChooseBrowserPopup {
|
|
onClosed: {
|
|
destroy()
|
|
}
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: inviteFriendsToCommunityPopup
|
|
InviteFriendsToCommunityPopup {
|
|
anchors.centerIn: parent
|
|
onClosed: {
|
|
destroy()
|
|
}
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: communityProfilePopup
|
|
|
|
CommunityProfilePopup {
|
|
id: communityProfilePopup
|
|
anchors.centerIn: parent
|
|
|
|
onClosed: {
|
|
destroy()
|
|
}
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: editCommunityPopup
|
|
CreateCommunityPopup {
|
|
anchors.centerIn: parent
|
|
isEdit: true
|
|
onClosed: {
|
|
destroy()
|
|
}
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: editChannelPopup
|
|
CreateChannelPopup {
|
|
anchors.centerIn: parent
|
|
isEdit: true
|
|
pinnedMessagesPopupComponent: chatLayoutContainer.chatColumn.pinnedMessagesPopupComponent
|
|
onClosed: {
|
|
destroy()
|
|
}
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: genericConfirmationDialog
|
|
ConfirmationDialog {
|
|
onClosed: {
|
|
destroy()
|
|
}
|
|
}
|
|
}
|
|
|
|
ToastMessage {
|
|
id: toastMessage
|
|
}
|
|
|
|
// Add SendModal here as it is used by the Wallet as well as the Browser
|
|
Loader {
|
|
id: sendModal
|
|
active: false
|
|
|
|
function open() {
|
|
this.active = true
|
|
this.item.open()
|
|
}
|
|
function closed() {
|
|
// this.sourceComponent = undefined // kill an opened instance
|
|
this.active = false
|
|
}
|
|
sourceComponent: SendModal {
|
|
onOpened: {
|
|
walletModel.gasView.getGasPrice()
|
|
}
|
|
onClosed: {
|
|
sendModal.closed()
|
|
}
|
|
}
|
|
}
|
|
|
|
Action {
|
|
shortcut: "Ctrl+1"
|
|
onTriggered: changeAppSection(Constants.chat)
|
|
}
|
|
Action {
|
|
shortcut: "Ctrl+2"
|
|
onTriggered: changeAppSection(Constants.browser)
|
|
}
|
|
Action {
|
|
shortcut: "Ctrl+3"
|
|
onTriggered: changeAppSection(Constants.wallet)
|
|
}
|
|
Action {
|
|
shortcut: "Ctrl+4, Ctrl+,"
|
|
onTriggered: changeAppSection(Constants.profile)
|
|
}
|
|
Action {
|
|
shortcut: "Ctrl+K"
|
|
onTriggered: {
|
|
if (channelPicker.opened) {
|
|
channelPicker.close()
|
|
} else {
|
|
channelPicker.open()
|
|
}
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: statusIdenticonComponent
|
|
StatusIdenticon {}
|
|
}
|
|
|
|
StatusInputListPopup {
|
|
id: channelPicker
|
|
//% "Where do you want to go?"
|
|
title: qsTrId("where-do-you-want-to-go-")
|
|
showSearchBox: true
|
|
width: 350
|
|
x: parent.width / 2 - width / 2
|
|
y: parent.height / 2 - height / 2
|
|
modelList: chatsModel.channelView.chats
|
|
getText: function (modelData) {
|
|
return modelData.name
|
|
}
|
|
getImageComponent: function (parent, modelData) {
|
|
return statusIdenticonComponent.createObject(parent, {
|
|
width: channelPicker.imageWidth,
|
|
height: channelPicker.imageHeight,
|
|
chatName: modelData.name,
|
|
chatType: modelData.chatType,
|
|
identicon: modelData.identicon
|
|
});
|
|
}
|
|
onClicked: function (index) {
|
|
appMain.changeAppSection(Constants.chat)
|
|
chatsModel.channelView.setActiveChannelByIndex(index)
|
|
channelPicker.close()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
/*##^##
|
|
Designer {
|
|
D{i:0;formeditorZoom:1.75;height:770;width:1232}
|
|
}
|
|
##^##*/
|