linux.x86.linphone/Linphone/view/Page/Main/Meeting/MeetingPage.qml
gaelle 73358b7a25 Conf info fixes :
set default videoconference factory uri

fix conf info message ui

fix conversation infos call action

always update all conf info on conf info received as we don't know which account is concerned

fix #LINQT-1980 display meeting detail

fix #LINQT-1986 force conferenceInfoReceived signal on meeting creation
fix do not add conference if state is cancelled
2025-09-16 17:33:40 +02:00

931 lines
36 KiB
QML

import QtQuick
import QtQuick.Effects
import QtQuick.Layouts
import QtQuick.Controls.Basic as Control
import Linphone
import UtilsCpp
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle
// TODO : spacing
AbstractMainPage {
id: mainItem
property ConferenceInfoGui selectedConference
property int meetingListCount: 0
signal returnRequested()
signal addParticipantsValidated(list<string> selectedParticipants)
//: "Créer une réunion"
noItemButtonText: qsTr("meetings_add")
//: "Aucune réunion"
emptyListText: qsTr("meetings_list_empty")
newItemIconSource: AppIcons.plusCircle
rightPanelColor: selectedConference ? DefaultStyle.grey_0 : DefaultStyle.grey_100
showDefaultItem: leftPanelStackView.currentItem && leftPanelStackView.currentItem.objectName === "listLayout" && meetingListCount === 0
function createPreFilledMeeting(subject, addresses) {
mainItem.selectedConference = Qt.createQmlObject('import Linphone
ConferenceInfoGui{
}', mainItem)
mainItem.selectedConference.core.resetParticipants(addresses)
mainItem.selectedConference.core.subject = subject
var item = leftPanelStackView.push(createConf, {"conferenceInfoGui": mainItem.selectedConference})
item.forceActiveFocus()
}
function editConference(confInfoGui = null) {
var isCreation = !confInfoGui
var item
if (isCreation) {
confInfoGui = Qt.createQmlObject('import Linphone
ConferenceInfoGui{
}', mainItem)
mainItem.selectedConference = confInfoGui
item = leftPanelStackView.push(createConf, {"conferenceInfoGui": mainItem.selectedConference})
item.forceActiveFocus()
} else {
mainItem.selectedConference = confInfoGui
item = overridenRightPanelStackView.push(editConf, {"conferenceInfoGui": mainItem.selectedConference})
item.forceActiveFocus()
}
}
onVisibleChanged: if (!visible) {
leftPanelStackView.clear()
leftPanelStackView.push(leftPanelStackView.initialItem)
}
onSelectedConferenceChanged: {
// While a conference is being edited, we need to stay on the edit page
if (overridenRightPanelStackView.currentItem && (overridenRightPanelStackView.currentItem.objectName === "editConf" || overridenRightPanelStackView.currentItem.objectName === "createConf")) return
overridenRightPanelStackView.clear()
if (selectedConference && selectedConference.core && selectedConference.core.haveModel) {
if (!overridenRightPanelStackView.currentItem || overridenRightPanelStackView.currentItem != meetingDetail) overridenRightPanelStackView.replace(meetingDetail, Control.StackView.Immediate)
}
}
onNoItemButtonPressed: editConference()
Component.onCompleted: rightPanelStackView.push(overridenRightPanel, Control.StackView.Immediate)
leftPanelContent: Control.StackView {
id: leftPanelStackView
Layout.fillWidth: true
Layout.fillHeight: true
Layout.leftMargin: Math.round(45 * DefaultStyle.dp)
initialItem: listLayout
clip: true
}
Dialog {
id: cancelAndDeleteConfDialog
property bool cancel: false
signal cancelRequested()
// width: Math.round(278 * DefaultStyle.dp)
//: "Souhaitez-vous annuler et supprimer cette réunion ?"
text: cancel ? qsTr("meeting_schedule_cancel_dialog_message")
//: Souhaitez-vous supprimer cette réunion ?
: qsTr("meeting_schedule_delete_dialog_message")
buttons: [
BigButton {
visible: cancelAndDeleteConfDialog.cancel
style: ButtonStyle.main
//: "Annuler et supprimer"
text: qsTr("meeting_schedule_cancel_and_delete_action")
onClicked: {
cancelAndDeleteConfDialog.cancelRequested()
cancelAndDeleteConfDialog.accepted()
cancelAndDeleteConfDialog.close()
}
},
BigButton {
//: "Supprimer seulement"
text: cancelAndDeleteConfDialog.cancel ? qsTr("meeting_schedule_delete_only_action")
//: "Supprimer"
: qsTr("meeting_schedule_delete_action")
style: ButtonStyle.main
onClicked: {
cancelAndDeleteConfDialog.accepted()
cancelAndDeleteConfDialog.close()
}
},
BigButton {
//: Retour
text: qsTr("back_action")
style: ButtonStyle.secondary
onClicked: {
cancelAndDeleteConfDialog.rejected()
cancelAndDeleteConfDialog.close()
}
}
]
}
Control.ScrollView {
id: overridenRightPanel
width: Math.round((393 + 10) * DefaultStyle.dp)
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.topMargin: Math.round(58 * DefaultStyle.dp)
anchors.bottomMargin: Math.round(30 * DefaultStyle.dp)
height: parent.height - anchors.topMargin
anchors.horizontalCenter: parent.horizontalCenter
contentHeight: overridenRightPanelStackView.currentItem ? overridenRightPanelStackView.currentItem.childrenRect.height : 0
contentWidth: width
clip: true
Control.ScrollBar.vertical: ScrollBar {
visible: overridenRightPanel.contentHeight > overridenRightPanel.height
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.right: parent.right
}
contentChildren: ColumnLayout {
anchors.fill: parent
anchors.rightMargin: Math.round(10 * DefaultStyle.dp)
width: Math.round(393 * DefaultStyle.dp)
Control.StackView {
id: overridenRightPanelStackView
Layout.fillWidth: true
Layout.fillHeight: true
height: currentItem ? currentItem.height : 0
}
}
}
Component {
id: listLayout
FocusScope{
property string objectName: "listLayout"
Control.StackView.onDeactivated: {
mainItem.selectedConference = null
}
Control.StackView.onActivated: {
mainItem.selectedConference = conferenceList.selectedConference
}
enabled: !overridenRightPanelStackView.currentItem || overridenRightPanelStackView.currentItem.objectName !== "editConf"
ColumnLayout {
anchors.fill: parent
spacing: 0
RowLayout {
Layout.rightMargin: Math.round(38 * DefaultStyle.dp)
Layout.alignment: Qt.AlignTop
Layout.fillWidth: true
spacing: 0
Text {
Layout.fillWidth: true
//: Réunions
text: qsTr("meetings_list_title")
color: DefaultStyle.main2_700
font.pixelSize: Typography.h2.pixelSize
font.weight: Typography.h2.weight
}
Item{Layout.fillWidth: true}
Button {
id: newConfButton
style: ButtonStyle.noBackground
icon.source: AppIcons.plusCircle
Layout.preferredWidth: Math.round(28 * DefaultStyle.dp)
Layout.preferredHeight: Math.round(28 * DefaultStyle.dp)
icon.width: Math.round(28 * DefaultStyle.dp)
icon.height: Math.round(28 * DefaultStyle.dp)
KeyNavigation.down: scrollToCurrentDateButton
onClicked: {
mainItem.editConference()
}
}
}
RowLayout {
visible: conferenceList.count !== 0 || searchBar.text.length !== 0
spacing: Math.round(11 * DefaultStyle.dp)
Layout.topMargin: Math.round(18 * DefaultStyle.dp)
Layout.rightMargin: Math.round(38 * DefaultStyle.dp)
KeyNavigation.up: newConfButton
KeyNavigation.down: searchBar
Button {
id: scrollToCurrentDateButton
Layout.preferredWidth: Math.round(32 * DefaultStyle.dp)
Layout.preferredHeight: Math.round(32 * DefaultStyle.dp)
icon.source: AppIcons.calendar
style: ButtonStyle.noBackground
onClicked: conferenceList.scrollToCurrentDate()
}
SearchBar {
id: searchBar
Layout.fillWidth: true
//: "Rechercher une réunion"
placeholderText: qsTr("meetings_search_hint")
KeyNavigation.up: scrollToCurrentDateButton
KeyNavigation.down: conferenceList
Binding {
target: mainItem
property: "showDefaultItem"
when: searchBar.text.length !== 0
value: false
}
}
}
Text {
visible: conferenceList.count === 0 && !conferenceList.loading
Layout.topMargin: Math.round(137 * DefaultStyle.dp)
Layout.fillHeight: true
Layout.alignment: Qt.AlignHCenter
//: "Aucun résultat…"
text: searchBar.text.length !== 0 ? qsTr("list_filter_no_result_found")
//: "Aucune réunion"
: qsTr("meetings_empty_list")
font {
pixelSize: Typography.h4.pixelSize
weight: Typography.h4.weight
}
}
MeetingListView {
id: conferenceList
// Remove 24 from first section padding because we cannot know that it is the first section. 24 is the margins between sections.
Layout.topMargin: Math.round(38 * DefaultStyle.dp) - Math.round(24 * DefaultStyle.dp)
Layout.fillWidth: true
Layout.fillHeight: true
searchBarText: searchBar.text
onCountChanged: {
mainItem.meetingListCount = count
}
Binding {
target: mainItem
property: "showDefaultItem"
when: conferenceList.loading
value: false
}
onSelectedConferenceChanged: {
mainItem.selectedConference = selectedConference
}
Keys.onPressed: (event) => {
if(event.key == Qt.Key_Escape){
searchBar.forceActiveFocus()
event.accepted = true
}else if(event.key == Qt.Key_Right){
overridenRightPanelStackView.currentItem.forceActiveFocus()
event.accepted = true
}
}
}
}
}
}
Component {
id: createConf
FocusScope{
id: createConfLayout
objectName: "createConf"
property ConferenceInfoGui conferenceInfoGui
ColumnLayout {
spacing: Math.round(33 * DefaultStyle.dp)
anchors.fill: parent
RowLayout {
Layout.rightMargin: Math.round(35 * DefaultStyle.dp)
spacing: Math.round(5 * DefaultStyle.dp)
Button {
id: backButton
style: ButtonStyle.noBackground
icon.source: AppIcons.leftArrow
focus: true
icon.width: Math.round(24 * DefaultStyle.dp)
icon.height: Math.round(24 * DefaultStyle.dp)
KeyNavigation.right: createButton
KeyNavigation.down: meetingSetup
onClicked: {
meetingSetup.conferenceInfoGui.core.undo()
leftPanelStackView.pop()
}
}
Text {
//: "Nouvelle réunion"
text: qsTr("meeting_schedule_title")
color: DefaultStyle.main2_700
font {
pixelSize: Typography.h3.pixelSize
weight: Typography.h3.weight
}
Layout.fillWidth: true
}
Item {Layout.fillWidth: true}
SmallButton {
id: createButton
text: qsTr("create")
style: ButtonStyle.main
KeyNavigation.left: backButton
KeyNavigation.down: meetingSetup
onClicked: {
if (meetingSetup.conferenceInfoGui.core.subject.length === 0 || meetingSetup.conferenceInfoGui.core.participantCount === 0) {
UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"),
//: Veuillez saisir un titre et sélectionner au moins un participant
qsTr("meeting_schedule_mandatory_field_not_filled_toast"), false)
} else if (meetingSetup.conferenceInfoGui.core.duration <= 0) {
UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"),
//: "La fin de la conférence doit être plus récente que son début"
qsTr("meeting_schedule_duration_error_toast"), false)
} else {
meetingSetup.conferenceInfoGui.core.save()
//: "Création de la réunion en cours …"
mainWindow.showLoadingPopup(qsTr("meeting_schedule_creation_in_progress"), true, function () {
meetingSetup.conferenceInfoGui.core.cancelCreation()
})
}
}
}
}
Control.ScrollView {
Layout.fillHeight: true
Layout.fillWidth: true
contentHeight: meetingSetup.height
Control.ScrollBar.vertical: ScrollBar {
visible: parent.contentHeight > parent.height
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.right: parent.right
}
contentChildren: MeetingForm {
id: meetingSetup
conferenceInfoGui: createConfLayout.conferenceInfoGui
isCreation: true
anchors.rightMargin: Math.round(35 * DefaultStyle.dp)
Connections {
target: meetingSetup.conferenceInfoGui ? meetingSetup.conferenceInfoGui.core : null
function onConferenceSchedulerStateChanged() {
var mainWin = UtilsCpp.getMainWindow()
if (meetingSetup.conferenceInfoGui.core.schedulerState == LinphoneEnums.ConferenceSchedulerState.Ready) {
leftPanelStackView.pop()
//: "Nouvelle réunion"
UtilsCpp.showInformationPopup(qsTr("meeting_schedule_title"),
//: "Réunion planifiée avec succès"
qsTr("meeting_info_created_toast"), true)
mainWindow.closeLoadingPopup()
}
else if (meetingSetup.conferenceInfoGui.core.schedulerState == LinphoneEnums.ConferenceSchedulerState.AllocationPending
|| meetingSetup.conferenceInfoGui.core.schedulerState == LinphoneEnums.ConferenceSchedulerState.Updating) {
mainWin.showLoadingPopup(qsTr("meeting_schedule_creation_in_progress"), true, function () {
leftPanelStackView.pop()
})
} else {
if (meetingSetup.conferenceInfoGui.core.schedulerState == LinphoneEnums.ConferenceSchedulerState.Error) {
UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"),
//: "Échec de création de la réunion !"
qsTr("meeting_failed_to_schedule_toast"), false)
}
mainWin.closeLoadingPopup()
}
createConfLayout.enabled = meetingSetup.conferenceInfoGui.core.schedulerState != LinphoneEnums.ConferenceSchedulerState.AllocationPending
}
function onSaveFailed() {
var mainWin = UtilsCpp.getMainWindow()
mainWin.closeLoadingPopup()
}
}
onAddParticipantsRequested: {
leftPanelStackView.push(addParticipants, {"conferenceInfoGui": conferenceInfoGui, "container": leftPanelStackView})
}
Connections {
target: mainItem
onAddParticipantsValidated: (selectedParticipants) => {
meetingSetup.conferenceInfoGui.core.resetParticipants(selectedParticipants)
leftPanelStackView.pop()
}
}
}
}
}
}
}
Component {
id: editConf
FocusScope{
id: editFocusScope
objectName: "editConf"
property ConferenceInfoGui conferenceInfoGui
width: overridenRightPanelStackView.width
ColumnLayout {
id: editLayout
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
height: childrenRect.height
spacing: 0
Section {
Layout.fillWidth: true
content: RowLayout {
spacing: Math.round(16 * DefaultStyle.dp)
Layout.preferredWidth: overridenRightPanelStackView.width
Button {
id: backButton
icon.source: AppIcons.leftArrow
icon.width: Math.round(24 * DefaultStyle.dp)
icon.height: Math.round(24 * DefaultStyle.dp)
style: ButtonStyle.noBackground
KeyNavigation.left: saveButton
KeyNavigation.right: titleText
KeyNavigation.down: conferenceEdit
KeyNavigation.up: conferenceEdit
onClicked: {
conferenceEdit.conferenceInfoGui.core.undo()
overridenRightPanelStackView.pop()
}
}
RowLayout {
spacing: Math.round(8 * DefaultStyle.dp)
EffectImage{
imageSource: AppIcons.usersThree
colorizationColor: DefaultStyle.main2_600
Layout.preferredWidth: Math.round(24 * DefaultStyle.dp)
Layout.preferredHeight: Math.round(24 * DefaultStyle.dp)
}
TextInput {
id: titleText
Layout.fillWidth: true
color: DefaultStyle.main2_600
clip: true
font {
pixelSize: Math.round(20 * DefaultStyle.dp)
weight: Typography.h4.weight
}
KeyNavigation.left: backButton
KeyNavigation.right: saveButton
KeyNavigation.down: conferenceEdit
KeyNavigation.up: conferenceEdit
onActiveFocusChanged: if(activeFocus==true) selectAll()
onTextEdited: mainItem.selectedConference.core.subject = text
Component.onCompleted: {
text = mainItem.selectedConference.core.subject
}
}
SmallButton {
id: saveButton
style: ButtonStyle.main
focus: true
text: qsTr("save")
KeyNavigation.left: titleText
KeyNavigation.right: backButton
KeyNavigation.down: conferenceEdit
KeyNavigation.up: conferenceEdit
onClicked: {
if (mainItem.selectedConference.core.subject.length === 0 || mainItem.selectedConference.core.participantCount === 0) {
UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"),
qsTr("meeting_schedule_mandatory_field_not_filled_toast"), false)
} else if (mainItem.selectedConference.core.duration <= 0) {
UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"),
qsTr("meeting_schedule_duration_error_toast"), false)
} else {
mainItem.selectedConference.core.save()
}
}
}
}
}
}
MeetingForm {
id: conferenceEdit
isCreation: false
conferenceInfoGui: editFocusScope.conferenceInfoGui
Layout.fillWidth: true
Layout.preferredHeight: childrenRect.height
onAddParticipantsRequested: {
overridenRightPanelStackView.push(addParticipants, {"conferenceInfoGui": conferenceInfoGui, "container": overridenRightPanelStackView})
}
Connections {
target: mainItem
function onAddParticipantsValidated(selectedParticipants) {
conferenceEdit.conferenceInfoGui.core.resetParticipants(selectedParticipants)
overridenRightPanelStackView.pop()
}
}
Connections {
target: conferenceEdit.conferenceInfoGui.core
ignoreUnknownSignals: true
function onSaveFailed() {
UtilsCpp.getMainWindow().closeLoadingPopup()
}
function onSchedulerStateChanged() {
editFocusScope.enabled = conferenceInfoGui.core.schedulerState != LinphoneEnums.ConferenceSchedulerState.AllocationPending
if (conferenceEdit.conferenceInfoGui.core.schedulerState == LinphoneEnums.ConferenceSchedulerState.Ready) {
overridenRightPanelStackView.pop()
UtilsCpp.getMainWindow().closeLoadingPopup()
//: "Enregistré"
UtilsCpp.showInformationPopup(qsTr("saved"),
//: "Réunion mise à jour"
qsTr("meeting_info_updated_toast"), true)
}
else if (conferenceEdit.conferenceInfoGui.core.schedulerState == LinphoneEnums.ConferenceSchedulerState.AllocationPending
|| conferenceEdit.conferenceInfoGui.core.schedulerState == LinphoneEnums.ConferenceSchedulerState.Updating) {
//: "Modification de la réunion en cours…"
UtilsCpp.getMainWindow().showLoadingPopup(qsTr("meeting_schedule_edit_in_progress"))
} else if (conferenceEdit.conferenceInfoGui.core.schedulerState == LinphoneEnums.ConferenceSchedulerState.Error) {
UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"),
//: "Échec de la modification de la réunion !"
qsTr("meeting_failed_to_edit_toast"), false)
UtilsCpp.getMainWindow().closeLoadingPopup()
}
}
}
}
}
}
}
Component {
id: addParticipants
FocusScope{
id: addParticipantInItem
property Control.StackView container
property ConferenceInfoGui conferenceInfoGui
ColumnLayout {
id: addParticipantsLayout
spacing: Math.round(18 * DefaultStyle.dp)
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
anchors.bottom: parent.bottom
ColumnLayout {
id: title
Layout.fillWidth: true
Layout.preferredHeight: childrenRect.height
spacing: Math.round(4 * DefaultStyle.dp)
RowLayout {
id: addParticipantsButtons
spacing: Math.round(10 * DefaultStyle.dp)
Button {
id: addParticipantsBackButton
style: ButtonStyle.noBackgroundOrange
icon.source: AppIcons.leftArrow
icon.width: Math.round(24 * DefaultStyle.dp)
icon.height: Math.round(24 * DefaultStyle.dp)
KeyNavigation.right: addButton
KeyNavigation.down: addParticipantLayout
onClicked: container.pop()
}
Text {
//: "Ajouter des participants"
text: qsTr("meeting_schedule_add_participants_title")
color: DefaultStyle.main1_500_main
maximumLineCount: 1
font {
pixelSize: Math.round(18 * DefaultStyle.dp)
weight: Typography.h4.weight
}
Layout.fillWidth: true
}
SmallButton {
id: addButton
enabled: addParticipantLayout.selectedParticipantsCount.length != 0
focus: enabled
style: ButtonStyle.main
text: qsTr("meeting_schedule_add_participants_apply")
KeyNavigation.left: addParticipantsBackButton
KeyNavigation.down: addParticipantLayout
onClicked: {
mainItem.addParticipantsValidated(addParticipantLayout.selectedParticipants)
}
}
}
Text {
//: "%n participant(s) sélectionné(s)"
text: qsTr("group_call_participant_selected", '', addParticipantLayout.selectedParticipantsCount).arg(addParticipantLayout.selectedParticipantsCount)
color: DefaultStyle.main2_500main
Layout.leftMargin: addParticipantsBackButton.width + addParticipantsButtons.spacing
maximumLineCount: 1
font {
pixelSize: Math.round(12 * DefaultStyle.dp)
weight: Math.round(300 * DefaultStyle.dp)
}
Layout.fillWidth: true
}
}
AddParticipantsForm {
id: addParticipantLayout
Layout.fillWidth: true
Layout.fillHeight: true
height: addParticipantInItem.height - title.height
conferenceInfoGui: addParticipantInItem.conferenceInfoGui
participantscSrollBarRightMargin: 0
}
}
}
}
Component {
id: meetingDetail
FocusScope{
width: overridenRightPanelStackView.width
ColumnLayout {
id: meetingDetailsLayout
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
visible: mainItem.selectedConference
spacing: Math.round(25 * DefaultStyle.dp)
Section {
visible: mainItem.selectedConference
Layout.fillWidth: true
content: RowLayout {
spacing: Math.round(8 * DefaultStyle.dp)
EffectImage {
imageSource: AppIcons.usersThree
colorizationColor: DefaultStyle.main2_600
Layout.preferredWidth: Math.round(24 * DefaultStyle.dp)
Layout.preferredHeight: Math.round(24 * DefaultStyle.dp)
}
Text {
Layout.fillWidth: true
text: mainItem.selectedConference && mainItem.selectedConference.core? mainItem.selectedConference.core.subject : ""
maximumLineCount: 1
font {
pixelSize: Math.round(20 * DefaultStyle.dp)
weight: Typography.h4.weight
}
}
Item {
Layout.fillWidth: true
}
RoundButton {
id: editButton
property var isMeObj: UtilsCpp.isMe(mainItem.selectedConference?.core?.organizerAddress)
visible: mainItem.selectedConference && isMeObj && isMeObj.value || false
icon.source: AppIcons.pencil
style: ButtonStyle.noBackgroundOrange
KeyNavigation.left: leftPanelStackView.currentItem
KeyNavigation.right: deletePopup
KeyNavigation.up: joinButton
KeyNavigation.down: shareNetworkButton
Layout.preferredWidth: Math.round(24 * DefaultStyle.dp)
onClicked: mainItem.editConference(mainItem.selectedConference)
}
PopupButton {
id: deletePopup
Layout.preferredWidth: Math.round(24 * DefaultStyle.dp)
Layout.preferredHeight: Math.round(24 * DefaultStyle.dp)
contentImageColor: DefaultStyle.main1_500_main
KeyNavigation.left: editButton.visible ? editButton : leftPanelStackView.currentItem
KeyNavigation.right: leftPanelStackView.currentItem
KeyNavigation.up: joinButton
KeyNavigation.down: shareNetworkButton
popup.contentItem: IconLabelButton {
style: ButtonStyle.hoveredBackgroundRed
property var isMeObj: UtilsCpp.isMe(mainItem.selectedConference?.core?.organizerAddress)
property bool canCancel: isMeObj && isMeObj.value && mainItem.selectedConference?.core?.state !== LinphoneEnums.ConferenceInfoState.Cancelled
icon.source: AppIcons.trashCan
//: "Supprimer la réunion"
text: qsTr("meeting_info_delete")
onClicked: {
if (mainItem.selectedConference) {
cancelAndDeleteConfDialog.cancel = canCancel
cancelAndDeleteConfDialog.open()
// mainItem.contactDeletionRequested(mainItem.selectedConference)
deletePopup.close()
}
}
Connections {
target: cancelAndDeleteConfDialog
function onCancelRequested() {
mainItem.selectedConference.core.lCancelConferenceInfo()
}
function onAccepted() {
mainItem.selectedConference.core.lDeleteConferenceInfo()
}
}
}
}
}
}
Section {
content: ColumnLayout {
spacing: Math.round(15 * DefaultStyle.dp)
width: parent.width
RowLayout {
spacing: Math.round(8 * DefaultStyle.dp)
Layout.fillWidth: true
EffectImage {
Layout.preferredWidth: Math.round(24 * DefaultStyle.dp)
Layout.preferredHeight: Math.round(24 * DefaultStyle.dp)
colorizationColor: DefaultStyle.main2_600
imageSource: AppIcons.videoCamera
}
SmallButton {
id: linkButton
Layout.fillWidth: true
text: mainItem.selectedConference ? mainItem.selectedConference.core?.uri : ""
textSize: Typography.p1.pixelSize
textWeight: Typography.p1.weight
underline: true
style: ButtonStyle.noBackground
Keys.onPressed: (event)=> {
if (event.key == Qt.Key_Space || event.key == Qt.Key_Enter || event.key == Qt.Key_Return) {
clicked(undefined)
event.accepted = true;
}
}
KeyNavigation.left: shareNetworkButton
KeyNavigation.right: shareNetworkButton
KeyNavigation.up: deletePopup
KeyNavigation.down: joinButton
onClicked: {
// TODO : voir si c'est en audio only quand on clique sur le lien
UtilsCpp.createCall(mainItem.selectedConference.core.uri)
}
}
RoundButton {
id: shareNetworkButton
style: ButtonStyle.noBackground
icon.source: AppIcons.shareNetwork
KeyNavigation.left: linkButton
KeyNavigation.right: linkButton
KeyNavigation.up: deletePopup
KeyNavigation.down: joinButton
Layout.preferredWidth: Math.round(24 * DefaultStyle.dp)
onClicked: {
var success = UtilsCpp.copyToClipboard(mainItem.selectedConference.core.uri)
if (success) UtilsCpp.showInformationPopup(qsTr("saved"),
//: "Adresse de la réunion copiée"
qsTr("meeting_address_copied_to_clipboard_toast"))
}
}
}
RowLayout {
spacing: Math.round(8 * DefaultStyle.dp)
EffectImage {
Layout.preferredWidth: Math.round(24 * DefaultStyle.dp)
Layout.preferredHeight: Math.round(24 * DefaultStyle.dp)
imageSource: AppIcons.clock
colorizationColor: DefaultStyle.main2_600
}
Text {
text: mainItem.selectedConference && mainItem.selectedConference.core
? UtilsCpp.toDateString(mainItem.selectedConference.core.dateTime)
+ " | " + UtilsCpp.toDateHourString(mainItem.selectedConference.core.dateTime)
+ " - "
+ UtilsCpp.toDateHourString(mainItem.selectedConference.core.endDateTime)
: ''
font {
pixelSize: Math.round(14 * DefaultStyle.dp)
capitalization: Font.Capitalize
}
}
}
RowLayout {
spacing: Math.round(8 * DefaultStyle.dp)
EffectImage {
Layout.preferredWidth: Math.round(24 * DefaultStyle.dp)
Layout.preferredHeight: Math.round(24 * DefaultStyle.dp)
imageSource: AppIcons.globe
colorizationColor: DefaultStyle.main2_600
}
Text {
Layout.fillWidth: true
//: "Fuseau horaire"
text: "%1: %2".arg(qsTr("meeting_schedule_timezone_title")).arg(mainItem.selectedConference && mainItem.selectedConference.core ? (mainItem.selectedConference.core.timeZoneModel.displayName + ", " + mainItem.selectedConference.core.timeZoneModel.countryName) : "")
font {
pixelSize: Math.round(14 * DefaultStyle.dp)
capitalization: Font.Capitalize
}
}
}
}
}
Section {
visible: mainItem.selectedConference && mainItem.selectedConference.core?.description.length != 0
content: RowLayout {
spacing: Math.round(8 * DefaultStyle.dp)
EffectImage {
Layout.preferredWidth: Math.round(24 * DefaultStyle.dp)
Layout.preferredHeight: Math.round(24 * DefaultStyle.dp)
imageSource: AppIcons.note
colorizationColor: DefaultStyle.main2_600
}
Text {
text: mainItem.selectedConference && mainItem.selectedConference.core ? mainItem.selectedConference.core.description : ""
Layout.fillWidth: true
font {
pixelSize: Math.round(14 * DefaultStyle.dp)
capitalization: Font.Capitalize
}
}
}
}
Section {
content: RowLayout {
spacing: Math.round(8 * DefaultStyle.dp)
EffectImage {
Layout.preferredWidth: Math.round(24 * DefaultStyle.dp)
Layout.preferredHeight: Math.round(24 * DefaultStyle.dp)
imageSource: AppIcons.userRectangle
colorizationColor: DefaultStyle.main2_600
}
Avatar {
Layout.preferredWidth: Math.round(45 * DefaultStyle.dp)
Layout.preferredHeight: Math.round(45 * DefaultStyle.dp)
_address: mainItem.selectedConference && mainItem.selectedConference.core ? mainItem.selectedConference.core.organizerAddress : ""
secured: friendSecurityLevel === LinphoneEnums.SecurityLevel.EndToEndEncryptedAndVerified
}
Text {
text: mainItem.selectedConference && mainItem.selectedConference.core ? mainItem.selectedConference.core.organizerName : ""
font {
pixelSize: Math.round(14 * DefaultStyle.dp)
capitalization: Font.Capitalize
}
}
}
}
Section {
visible: participantList.count > 0
Layout.fillWidth: true
content: RowLayout {
Layout.preferredHeight: participantList.height
width: Math.round(393 * DefaultStyle.dp)
spacing: Math.round(8 * DefaultStyle.dp)
EffectImage {
Layout.preferredWidth: Math.round(24 * DefaultStyle.dp)
Layout.preferredHeight: Math.round(24 * DefaultStyle.dp)
Layout.alignment: Qt.AlignLeft | Qt.AlignTop
Layout.topMargin: Math.round(20 * DefaultStyle.dp)
imageSource: AppIcons.usersTwo
colorizationColor: DefaultStyle.main2_600
}
ListView {
id: participantList
Layout.preferredHeight: Math.min(Math.round(184 * DefaultStyle.dp), contentHeight)
Layout.fillWidth: true
model: mainItem.selectedConference && mainItem.selectedConference.core ? mainItem.selectedConference.core.participants : []
clip: true
Control.ScrollBar.vertical: ScrollBar {
id: participantScrollBar
anchors.right: participantList.right
anchors.top: participantList.top
anchors.bottom: participantList.bottom
visible: participantList.height < participantList.contentHeight
}
delegate: RowLayout {
height: Math.round(56 * DefaultStyle.dp)
width: participantList.width - participantScrollBar.width - Math.round(5 * DefaultStyle.dp)
Avatar {
Layout.preferredWidth: Math.round(45 * DefaultStyle.dp)
Layout.preferredHeight: Math.round(45 * DefaultStyle.dp)
_address: modelData.address
secured: friendSecurityLevel === LinphoneEnums.SecurityLevel.EndToEndEncryptedAndVerified
shadowEnabled: false
}
Text {
property var displayNameObj: UtilsCpp.getDisplayName(modelData.address)
text: displayNameObj?.value || ""
maximumLineCount: 1
Layout.fillWidth: true
font {
pixelSize: Math.round(14 * DefaultStyle.dp)
capitalization: Font.Capitalize
}
}
Text {
//: "Organisateur"
text: qsTr("meeting_info_organizer_label")
visible: mainItem.selectedConference && mainItem.selectedConference.core?.organizerAddress === modelData.address
color: DefaultStyle.main2_400
font {
pixelSize: Math.round(12 * DefaultStyle.dp)
weight: Math.round(300 * DefaultStyle.dp)
}
}
}
}
}
}
BigButton {
id: joinButton
visible: mainItem.selectedConference && mainItem.selectedConference.core?.state !== LinphoneEnums.ConferenceInfoState.Cancelled
Layout.fillWidth: true
Layout.preferredHeight: implicitHeight
Layout.bottomMargin: Math.round(5 * DefaultStyle.dp)
//: "Rejoindre la réunion"
text: qsTr("meeting_info_join_title")
focus: true
KeyNavigation.up: shareNetworkButton
KeyNavigation.down: deletePopup
KeyNavigation.left: leftPanelStackView.currentItem
KeyNavigation.right: leftPanelStackView.currentItem
onClicked: {
console.log(mainItem.selectedConference.core.uri)
var callsWindow = UtilsCpp.getCallsWindow()
callsWindow.setupConference(mainItem.selectedConference)
UtilsCpp.smartShowWindow(callsWindow)
}
}
Item { Layout.fillHeight: true}
}
}
}
}