Add button to export ICS of meeting in meetings and chat views

This commit is contained in:
Christophe Deschamps 2025-12-03 21:55:58 +01:00
parent ed57ec1ea5
commit a9a1249ecd
6 changed files with 50 additions and 6 deletions

View file

@ -21,12 +21,15 @@
#include "ConferenceInfoCore.hpp" #include "ConferenceInfoCore.hpp"
#include "core/App.hpp" #include "core/App.hpp"
#include "core/path/Paths.hpp"
#include "core/proxy/ListProxy.hpp" #include "core/proxy/ListProxy.hpp"
#include "model/object/VariantObject.hpp" #include "model/object/VariantObject.hpp"
#include "model/tool/ToolModel.hpp" #include "model/tool/ToolModel.hpp"
#include "tool/Utils.hpp" #include "tool/Utils.hpp"
#include "tool/thread/SafeConnection.hpp" #include "tool/thread/SafeConnection.hpp"
#include <QDesktopServices>
DEFINE_ABSTRACT_OBJECT(ConferenceInfoCore) DEFINE_ABSTRACT_OBJECT(ConferenceInfoCore)
QSharedPointer<ConferenceInfoCore> QSharedPointer<ConferenceInfoCore>
@ -69,6 +72,7 @@ ConferenceInfoCore::ConferenceInfoCore(std::shared_ptr<linphone::ConferenceInfo>
mUri = address && address->isValid() && !address->getDomain().empty() mUri = address && address->isValid() && !address->getDomain().empty()
? Utils::coreStringToAppString(address->asStringUriOnly()) ? Utils::coreStringToAppString(address->asStringUriOnly())
: ""; : "";
mIcalendarString = Utils::coreStringToAppString(conferenceInfo->getIcalendarString());
mDateTime = QDateTime::fromMSecsSinceEpoch(conferenceInfo->getDateTime() * 1000); mDateTime = QDateTime::fromMSecsSinceEpoch(conferenceInfo->getDateTime() * 1000);
mDuration = conferenceInfo->getDuration(); mDuration = conferenceInfo->getDuration();
mEndDateTime = mDateTime.addSecs(mDuration * 60); mEndDateTime = mDateTime.addSecs(mDuration * 60);
@ -123,6 +127,7 @@ ConferenceInfoCore::ConferenceInfoCore(const ConferenceInfoCore &conferenceInfoC
mIsEnded = conferenceInfoCore.mIsEnded; mIsEnded = conferenceInfoCore.mIsEnded;
mInviteEnabled = conferenceInfoCore.mInviteEnabled; mInviteEnabled = conferenceInfoCore.mInviteEnabled;
mConferenceInfoState = conferenceInfoCore.mConferenceInfoState; mConferenceInfoState = conferenceInfoCore.mConferenceInfoState;
mIcalendarString = conferenceInfoCore.mIcalendarString;
} }
ConferenceInfoCore::~ConferenceInfoCore() { ConferenceInfoCore::~ConferenceInfoCore() {
@ -653,3 +658,14 @@ bool ConferenceInfoCore::isAllDayConf() const {
return mDateTime.time().hour() == 0 && mDateTime.time().minute() == 0 && mEndDateTime.time().hour() == 23 && return mDateTime.time().hour() == 0 && mDateTime.time().minute() == 0 && mEndDateTime.time().hour() == 23 &&
mEndDateTime.time().minute() == 59; mEndDateTime.time().minute() == 59;
} }
void ConferenceInfoCore::exportConferenceToICS() const {
QString filePath(Paths::getAppLocalDirPath() + "conference.ics");
QFile file(filePath);
if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
QTextStream out(&file);
out << mIcalendarString;
file.close();
}
QDesktopServices::openUrl(QUrl::fromLocalFile(filePath));
}

View file

@ -1,4 +1,4 @@
/* /*
* Copyright (c) 2022 Belledonne Communications SARL. * Copyright (c) 2022 Belledonne Communications SARL.
* *
* This file is part of linphone-desktop * This file is part of linphone-desktop
@ -135,6 +135,8 @@ public:
Q_INVOKABLE bool isAllDayConf() const; Q_INVOKABLE bool isAllDayConf() const;
Q_INVOKABLE void exportConferenceToICS() const;
signals: signals:
void dateTimeChanged(); void dateTimeChanged();
void endDateTimeChanged(); void endDateTimeChanged();
@ -177,6 +179,7 @@ private:
QString mSubject; QString mSubject;
QString mDescription; QString mDescription;
QString mUri; QString mUri;
QString mIcalendarString;
QVariantList mParticipants; QVariantList mParticipants;
QSharedPointer<TimeZoneModel> mTimeZoneModel; QSharedPointer<TimeZoneModel> mTimeZoneModel;
LinphoneEnums::ConferenceSchedulerState mConferenceSchedulerState; LinphoneEnums::ConferenceSchedulerState mConferenceSchedulerState;

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="#000000" viewBox="0 0 256 256"><path d="M208,32H184V24a8,8,0,0,0-16,0v8H88V24a8,8,0,0,0-16,0v8H48A16,16,0,0,0,32,48V208a16,16,0,0,0,16,16H208a16,16,0,0,0,16-16V48A16,16,0,0,0,208,32ZM72,48v8a8,8,0,0,0,16,0V48h80v8a8,8,0,0,0,16,0V48h24V80H48V48ZM208,208H48V96H208V208Zm-48-56a8,8,0,0,1-8,8H136v16a8,8,0,0,1-16,0V160H104a8,8,0,0,1,0-16h16V128a8,8,0,0,1,16,0v16h16A8,8,0,0,1,160,152Z"></path></svg>

After

Width:  |  Height:  |  Size: 464 B

View file

@ -158,11 +158,22 @@ ColumnLayout {
} }
} }
RowLayout {
spacing: Utils.getSizeWithScreenRatio(8)
Text { Text {
text: conferenceInfo.dateTime.toLocaleString(Qt.locale(), "dddd d MMMM yyyy") text: conferenceInfo.dateTime.toLocaleString(Qt.locale(), "dddd d MMMM yyyy")
font: Typography.p4 font: Typography.p4
color: DefaultStyle.main2_500_main color: DefaultStyle.main2_500_main
} }
RoundButton {
id: calendarPlusButton
style: ButtonStyle.noBackground
icon.source: AppIcons.calendarPlus
onClicked: {
conferenceInfo.exportConferenceToICS()
}
}
}
Text { Text {
//: from %1 to %2 (UTC%3) //: from %1 to %2 (UTC%3)
property string offsetFromUtc: conferenceInfo.timeZoneModel.offsetFromUtc > 0 property string offsetFromUtc: conferenceInfo.timeZoneModel.offsetFromUtc > 0

View file

@ -738,7 +738,7 @@ AbstractMainPage {
KeyNavigation.left: linkButton KeyNavigation.left: linkButton
KeyNavigation.right: linkButton KeyNavigation.right: linkButton
KeyNavigation.up: deletePopup KeyNavigation.up: deletePopup
KeyNavigation.down: joinButton KeyNavigation.down: calendarPlusButton
onClicked: { onClicked: {
var success = UtilsCpp.copyToClipboard(mainItem.selectedConference.core.uri) var success = UtilsCpp.copyToClipboard(mainItem.selectedConference.core.uri)
if (success) UtilsCpp.showInformationPopup(qsTr("saved"), if (success) UtilsCpp.showInformationPopup(qsTr("saved"),
@ -767,6 +767,18 @@ AbstractMainPage {
capitalization: Font.Capitalize capitalization: Font.Capitalize
} }
} }
RoundButton {
id: calendarPlusButton
style: ButtonStyle.noBackground
icon.source: AppIcons.calendarPlus
KeyNavigation.left: calendarPlusButton
KeyNavigation.right: calendarPlusButton
KeyNavigation.up: shareNetworkButton
KeyNavigation.down: joinButton
onClicked: {
mainItem.selectedConference.core.exportConferenceToICS()
}
}
} }
RowLayout { RowLayout {
spacing: Utils.getSizeWithScreenRatio(8) spacing: Utils.getSizeWithScreenRatio(8)

View file

@ -160,4 +160,5 @@ QtObject {
property string ephemeralSettings: "image://internal/ephemeral-settings.svg" property string ephemeralSettings: "image://internal/ephemeral-settings.svg"
property string hourglass: "image://internal/hourglass-simple.svg" property string hourglass: "image://internal/hourglass-simple.svg"
property string qtLogo: "image://internal/qt-logo.png" property string qtLogo: "image://internal/qt-logo.png"
property string calendarPlus: "image://internal/calendar-plus.svg"
} }