}
header: ColumnLayout {
- spacing: root.intendedPadding
+ spacing: root.padding
GridLayout {
id: headerGridLayout
}
}
- ColumnLayout {
- id: moreMenu
+ contentItem: ColumnLayout {
+ ScrollView {
+ Layout.fillWidth: true
+ Layout.fillHeight: true
- property int rowIconWidth: 16
- property int indicatorItemWidth: 20
- property int indicatorSpacing: Style.standardSpacing
- property int itemPadding: Style.smallSpacing
+ contentWidth: availableWidth
- RowLayout {
- anchors.left: parent.left
- anchors.leftMargin: moreMenu.itemPadding
- anchors.right: parent.right
- anchors.rightMargin: moreMenu.itemPadding
- height: visible ? implicitHeight : 0
- spacing: moreMenu.indicatorSpacing
+ clip: true
- visible: root.isLinkShare
+ ColumnLayout {
+ id: moreMenu
- Image {
- Layout.preferredWidth: moreMenu.indicatorItemWidth
- Layout.fillHeight: true
+ property int rowIconWidth: 16
+ property int indicatorItemWidth: 20
+ property int indicatorSpacing: Style.standardSpacing
+ property int itemPadding: Style.smallSpacing
- verticalAlignment: Image.AlignVCenter
- horizontalAlignment: Image.AlignHCenter
- fillMode: Image.Pad
+ width: parent.width
- source: "image://svgimage-custom-color/edit.svg/" + Style.menuBorder
- sourceSize.width: moreMenu.rowIconWidth
- sourceSize.height: moreMenu.rowIconWidth
- }
+ RowLayout {
+ Layout.fillWidth: true
+ height: visible ? implicitHeight : 0
+ spacing: moreMenu.indicatorSpacing
- NCInputTextField {
- id: linkShareLabelTextField
+ visible: root.isLinkShare
- Layout.fillWidth: true
- height: visible ? implicitHeight : 0
+ Image {
+ Layout.preferredWidth: moreMenu.indicatorItemWidth
+ Layout.fillHeight: true
- text: root.linkShareLabel
- placeholderText: qsTr("Share label")
+ verticalAlignment: Image.AlignVCenter
+ horizontalAlignment: Image.AlignHCenter
+ fillMode: Image.Pad
- enabled: root.isLinkShare &&
- !root.waitingForLinkShareLabelChange
-
- onAccepted: if(text !== root.linkShareLabel) {
- root.setLinkShareLabel(text);
- root.waitingForLinkShareLabelChange = true;
- }
-
- NCBusyIndicator {
- anchors.fill: parent
- visible: root.waitingForLinkShareLabelChange
- running: visible
- z: 1
- }
- }
- }
-
- // On these checkables, the clicked() signal is called after
- // the check state changes.
- CheckBox {
- id: editingAllowedMenuItem
-
- spacing: moreMenu.indicatorSpacing
- padding: moreMenu.itemPadding
- indicator.width: moreMenu.indicatorItemWidth
- indicator.height: moreMenu.indicatorItemWidth
+ source: "image://svgimage-custom-color/edit.svg/" + Style.menuBorder
+ sourceSize.width: moreMenu.rowIconWidth
+ sourceSize.height: moreMenu.rowIconWidth
+ }
- checkable: true
- checked: root.editingAllowed
- text: qsTr("Allow editing")
- enabled: !root.waitingForEditingAllowedChange
+ NCInputTextField {
+ id: linkShareLabelTextField
- onClicked: {
- root.toggleAllowEditing(checked);
- root.waitingForEditingAllowedChange = true;
- }
+ Layout.fillWidth: true
+ height: visible ? implicitHeight : 0
- NCBusyIndicator {
- anchors.fill: parent
- visible: root.waitingForEditingAllowedChange
- running: visible
- z: 1
- }
- }
+ text: root.linkShareLabel
+ placeholderText: qsTr("Share label")
- CheckBox {
- id: passwordProtectEnabledMenuItem
+ enabled: root.isLinkShare &&
+ !root.waitingForLinkShareLabelChange
- spacing: moreMenu.indicatorSpacing
- padding: moreMenu.itemPadding
- indicator.width: moreMenu.indicatorItemWidth
- indicator.height: moreMenu.indicatorItemWidth
+ onAccepted: if(text !== root.linkShareLabel) {
+ root.setLinkShareLabel(text);
+ root.waitingForLinkShareLabelChange = true;
+ }
- checkable: true
- checked: root.passwordProtectEnabled
- text: qsTr("Password protect")
- enabled: !root.waitingForPasswordProtectEnabledChange && !root.passwordEnforced
+ NCBusyIndicator {
+ anchors.fill: parent
+ visible: root.waitingForLinkShareLabelChange
+ running: visible
+ z: 1
+ }
+ }
+ }
- onClicked: {
- root.togglePasswordProtect(checked);
- root.waitingForPasswordProtectEnabledChange = true;
- }
+ // On these checkables, the clicked() signal is called after
+ // the check state changes.
+ CheckBox {
+ id: editingAllowedMenuItem
- NCBusyIndicator {
- anchors.fill: parent
- visible: root.waitingForPasswordProtectEnabledChange
- running: visible
- z: 1
- }
- }
+ Layout.fillWidth: true
- RowLayout {
- anchors.left: parent.left
- anchors.leftMargin: moreMenu.itemPadding
- anchors.right: parent.right
- anchors.rightMargin: moreMenu.itemPadding
- height: visible ? implicitHeight : 0
- spacing: moreMenu.indicatorSpacing
+ spacing: moreMenu.indicatorSpacing
+ padding: moreMenu.itemPadding
+ indicator.width: moreMenu.indicatorItemWidth
+ indicator.height: moreMenu.indicatorItemWidth
- visible: root.passwordProtectEnabled
+ checkable: true
+ checked: root.editingAllowed
+ text: qsTr("Allow editing")
+ enabled: !root.waitingForEditingAllowedChange
- Image {
- Layout.preferredWidth: moreMenu.indicatorItemWidth
- Layout.fillHeight: true
+ onClicked: {
+ root.toggleAllowEditing(checked);
+ root.waitingForEditingAllowedChange = true;
+ }
- verticalAlignment: Image.AlignVCenter
- horizontalAlignment: Image.AlignHCenter
- fillMode: Image.Pad
+ NCBusyIndicator {
+ anchors.fill: parent
+ visible: root.waitingForEditingAllowedChange
+ running: visible
+ z: 1
+ }
+ }
- source: "image://svgimage-custom-color/lock-https.svg/" + Style.menuBorder
- sourceSize.width: moreMenu.rowIconWidth
- sourceSize.height: moreMenu.rowIconWidth
- }
+ CheckBox {
+ id: passwordProtectEnabledMenuItem
- NCInputTextField {
- id: passwordTextField
+ Layout.fillWidth: true
- Layout.fillWidth: true
- height: visible ? implicitHeight : 0
+ spacing: moreMenu.indicatorSpacing
+ padding: moreMenu.itemPadding
+ indicator.width: moreMenu.indicatorItemWidth
+ indicator.height: moreMenu.indicatorItemWidth
- text: root.password !== "" ? root.password : root.passwordPlaceholder
- enabled: root.passwordProtectEnabled &&
- !root.waitingForPasswordChange &&
- !root.waitingForPasswordProtectEnabledChange
+ checkable: true
+ checked: root.passwordProtectEnabled
+ text: qsTr("Password protect")
+ enabled: !root.waitingForPasswordProtectEnabledChange && !root.passwordEnforced
- onAccepted: if(text !== root.password && text !== root.passwordPlaceholder) {
- passwordErrorBoxLoader.message = "";
- root.setPassword(text);
- root.waitingForPasswordChange = true;
- }
+ onClicked: {
+ root.togglePasswordProtect(checked);
+ root.waitingForPasswordProtectEnabledChange = true;
+ }
- NCBusyIndicator {
- anchors.fill: parent
- visible: root.waitingForPasswordChange ||
- root.waitingForPasswordProtectEnabledChange
- running: visible
- z: 1
+ NCBusyIndicator {
+ anchors.fill: parent
+ visible: root.waitingForPasswordProtectEnabledChange
+ running: visible
+ z: 1
+ }
}
- }
- }
- Loader {
- id: passwordErrorBoxLoader
+ RowLayout {
+ Layout.fillWidth: true
- property string message: ""
+ height: visible ? implicitHeight : 0
+ spacing: moreMenu.indicatorSpacing
- anchors.left: parent.left
- anchors.right: parent.right
- height: message !== "" ? implicitHeight : 0
+ visible: root.passwordProtectEnabled
- active: message !== ""
- visible: active
+ Image {
+ Layout.preferredWidth: moreMenu.indicatorItemWidth
+ Layout.fillHeight: true
- sourceComponent: Item {
- anchors.top: parent.top
- anchors.left: parent.left
- anchors.right: parent.right
- // Artificially add vertical padding
- implicitHeight: passwordErrorBox.implicitHeight + (Style.smallSpacing * 2)
+ verticalAlignment: Image.AlignVCenter
+ horizontalAlignment: Image.AlignHCenter
+ fillMode: Image.Pad
- ErrorBox {
- id: passwordErrorBox
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.verticalCenter: parent.verticalCenter
+ source: "image://svgimage-custom-color/lock-https.svg/" + Style.menuBorder
+ sourceSize.width: moreMenu.rowIconWidth
+ sourceSize.height: moreMenu.rowIconWidth
+ }
- text: passwordErrorBoxLoader.message
+ NCInputTextField {
+ id: passwordTextField
+
+ Layout.fillWidth: true
+ height: visible ? implicitHeight : 0
+
+ text: root.password !== "" ? root.password : root.passwordPlaceholder
+ enabled: root.passwordProtectEnabled &&
+ !root.waitingForPasswordChange &&
+ !root.waitingForPasswordProtectEnabledChange
+
+ onAccepted: if(text !== root.password && text !== root.passwordPlaceholder) {
+ passwordErrorBoxLoader.message = "";
+ root.setPassword(text);
+ root.waitingForPasswordChange = true;
+ }
+
+ NCBusyIndicator {
+ anchors.fill: parent
+ visible: root.waitingForPasswordChange ||
+ root.waitingForPasswordProtectEnabledChange
+ running: visible
+ z: 1
+ }
+ }
}
- }
- }
- CheckBox {
- id: expireDateEnabledMenuItem
+ Loader {
+ id: passwordErrorBoxLoader
- spacing: moreMenu.indicatorSpacing
- padding: moreMenu.itemPadding
- indicator.width: moreMenu.indicatorItemWidth
- indicator.height: moreMenu.indicatorItemWidth
+ property string message: ""
- checkable: true
- checked: root.expireDateEnabled
- text: qsTr("Set expiration date")
- enabled: !root.waitingForExpireDateEnabledChange && !root.expireDateEnforced
+ Layout.fillWidth: true
+ height: message !== "" ? implicitHeight : 0
- onClicked: {
- root.toggleExpirationDate(checked);
- root.waitingForExpireDateEnabledChange = true;
- }
+ active: message !== ""
+ visible: active
- NCBusyIndicator {
- anchors.fill: parent
- visible: root.waitingForExpireDateEnabledChange
- running: visible
- z: 1
- }
- }
+ sourceComponent: Item {
+ anchors.top: parent.top
+ anchors.left: parent.left
+ anchors.right: parent.right
+ // Artificially add vertical padding
+ implicitHeight: passwordErrorBox.implicitHeight + (Style.smallSpacing * 2)
- RowLayout {
- anchors.left: parent.left
- anchors.leftMargin: moreMenu.itemPadding
- anchors.right: parent.right
- anchors.rightMargin: moreMenu.itemPadding
- height: visible ? implicitHeight : 0
- spacing: moreMenu.indicatorSpacing
+ ErrorBox {
+ id: passwordErrorBox
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.verticalCenter: parent.verticalCenter
- visible: root.expireDateEnabled
+ text: passwordErrorBoxLoader.message
+ }
+ }
+ }
- Image {
- Layout.preferredWidth: moreMenu.indicatorItemWidth
- Layout.fillHeight: true
+ CheckBox {
+ id: expireDateEnabledMenuItem
- verticalAlignment: Image.AlignVCenter
- horizontalAlignment: Image.AlignHCenter
- fillMode: Image.Pad
+ Layout.fillWidth: true
- source: "image://svgimage-custom-color/calendar.svg/" + Style.menuBorder
- sourceSize.width: moreMenu.rowIconWidth
- sourceSize.height: moreMenu.rowIconWidth
- }
+ spacing: moreMenu.indicatorSpacing
+ padding: moreMenu.itemPadding
+ indicator.width: moreMenu.indicatorItemWidth
+ indicator.height: moreMenu.indicatorItemWidth
- // QML dates are essentially JavaScript dates, which makes them very finicky and unreliable.
- // Instead, we exclusively deal with msecs from epoch time to make things less painful when editing.
- // We only use the QML Date when showing the nice string to the user.
- SpinBox {
- id: expireDateSpinBox
-
- // Work arounds the limitations of QML's 32 bit integer when handling msecs from epoch
- // Instead, we handle everything as days since epoch
- readonly property int dayInMSecs: 24 * 60 * 60 * 1000
- readonly property int expireDateReduced: Math.floor(root.expireDate / dayInMSecs)
- // Reset the model data after binding broken on user interact
- onExpireDateReducedChanged: value = expireDateReduced
-
- // We can't use JS's convenient Infinity or Number.MAX_VALUE as
- // JS Number type is 64 bits, whereas QML's int type is only 32 bits
- readonly property IntValidator intValidator: IntValidator {}
- readonly property int maximumExpireDateReduced: root.expireDateEnforced ?
- Math.floor(root.maximumExpireDate / dayInMSecs) :
- intValidator.top
- readonly property int minimumExpireDateReduced: {
- const currentDate = new Date();
- const minDateUTC = new Date(Date.UTC(currentDate.getFullYear(),
- currentDate.getMonth(),
- currentDate.getDate() + 1));
- return Math.floor(minDateUTC / dayInMSecs) // Start of day at 00:00:0000 UTC
- }
+ checkable: true
+ checked: root.expireDateEnabled
+ text: qsTr("Set expiration date")
+ enabled: !root.waitingForExpireDateEnabledChange && !root.expireDateEnforced
- // Taken from Kalendar 22.08
- // https://invent.kde.org/pim/kalendar/-/blob/release/22.08/src/contents/ui/KalendarUtils/dateutils.js
- function parseDateString(dateString) {
- function defaultParse() {
- const defaultParsedDate = Date.fromLocaleDateString(Qt.locale(), dateString, Locale.NarrowFormat);
- // JS always generates date in system locale, eliminate timezone difference to UTC
- const msecsSinceEpoch = defaultParsedDate.getTime() - (defaultParsedDate.getTimezoneOffset() * 60 * 1000);
- return new Date(msecsSinceEpoch);
+ onClicked: {
+ root.toggleExpirationDate(checked);
+ root.waitingForExpireDateEnabledChange = true;
}
- const dateStringDelimiterMatches = dateString.match(/\D/);
- if(dateStringDelimiterMatches.length === 0) {
- // Let the date method figure out this weirdness
- return defaultParse();
+ NCBusyIndicator {
+ anchors.fill: parent
+ visible: root.waitingForExpireDateEnabledChange
+ running: visible
+ z: 1
}
+ }
- const dateStringDelimiter = dateStringDelimiterMatches[0];
-
- const localisedDateFormatSplit = Qt.locale().dateFormat(Locale.NarrowFormat).split(dateStringDelimiter);
- const localisedDateDayPosition = localisedDateFormatSplit.findIndex((x) => /d/gi.test(x));
- const localisedDateMonthPosition = localisedDateFormatSplit.findIndex((x) => /m/gi.test(x));
- const localisedDateYearPosition = localisedDateFormatSplit.findIndex((x) => /y/gi.test(x));
+ RowLayout {
+ Layout.fillWidth: true
+ height: visible ? implicitHeight : 0
+ spacing: moreMenu.indicatorSpacing
- let splitDateString = dateString.split(dateStringDelimiter);
- let userProvidedYear = splitDateString[localisedDateYearPosition]
+ visible: root.expireDateEnabled
- const dateNow = new Date();
- const stringifiedCurrentYear = dateNow.getFullYear().toString();
+ Image {
+ Layout.preferredWidth: moreMenu.indicatorItemWidth
+ Layout.fillHeight: true
- // If we have any input weirdness, or if we have a fully-written year
- // (e.g. 2022 instead of 22) then use default parse
- if(splitDateString.length === 0 ||
- splitDateString.length > 3 ||
- userProvidedYear.length >= stringifiedCurrentYear.length) {
+ verticalAlignment: Image.AlignVCenter
+ horizontalAlignment: Image.AlignHCenter
+ fillMode: Image.Pad
- return defaultParse();
+ source: "image://svgimage-custom-color/calendar.svg/" + Style.menuBorder
+ sourceSize.width: moreMenu.rowIconWidth
+ sourceSize.height: moreMenu.rowIconWidth
}
- let fullyWrittenYear = userProvidedYear.split("");
- const digitsToAdd = stringifiedCurrentYear.length - fullyWrittenYear.length;
- for(let i = 0; i < digitsToAdd; i++) {
- fullyWrittenYear.splice(i, 0, stringifiedCurrentYear[i])
+ // QML dates are essentially JavaScript dates, which makes them very finicky and unreliable.
+ // Instead, we exclusively deal with msecs from epoch time to make things less painful when editing.
+ // We only use the QML Date when showing the nice string to the user.
+ SpinBox {
+ id: expireDateSpinBox
+
+ // Work arounds the limitations of QML's 32 bit integer when handling msecs from epoch
+ // Instead, we handle everything as days since epoch
+ readonly property int dayInMSecs: 24 * 60 * 60 * 1000
+ readonly property int expireDateReduced: Math.floor(root.expireDate / dayInMSecs)
+ // Reset the model data after binding broken on user interact
+ onExpireDateReducedChanged: value = expireDateReduced
+
+ // We can't use JS's convenient Infinity or Number.MAX_VALUE as
+ // JS Number type is 64 bits, whereas QML's int type is only 32 bits
+ readonly property IntValidator intValidator: IntValidator {}
+ readonly property int maximumExpireDateReduced: root.expireDateEnforced ?
+ Math.floor(root.maximumExpireDate / dayInMSecs) :
+ intValidator.top
+ readonly property int minimumExpireDateReduced: {
+ const currentDate = new Date();
+ const minDateUTC = new Date(Date.UTC(currentDate.getFullYear(),
+ currentDate.getMonth(),
+ currentDate.getDate() + 1));
+ return Math.floor(minDateUTC / dayInMSecs) // Start of day at 00:00:0000 UTC
+ }
+
+ // Taken from Kalendar 22.08
+ // https://invent.kde.org/pim/kalendar/-/blob/release/22.08/src/contents/ui/KalendarUtils/dateutils.js
+ function parseDateString(dateString) {
+ function defaultParse() {
+ const defaultParsedDate = Date.fromLocaleDateString(Qt.locale(), dateString, Locale.NarrowFormat);
+ // JS always generates date in system locale, eliminate timezone difference to UTC
+ const msecsSinceEpoch = defaultParsedDate.getTime() - (defaultParsedDate.getTimezoneOffset() * 60 * 1000);
+ return new Date(msecsSinceEpoch);
+ }
+
+ const dateStringDelimiterMatches = dateString.match(/\D/);
+ if(dateStringDelimiterMatches.length === 0) {
+ // Let the date method figure out this weirdness
+ return defaultParse();
+ }
+
+ const dateStringDelimiter = dateStringDelimiterMatches[0];
+
+ const localisedDateFormatSplit = Qt.locale().dateFormat(Locale.NarrowFormat).split(dateStringDelimiter);
+ const localisedDateDayPosition = localisedDateFormatSplit.findIndex((x) => /d/gi.test(x));
+ const localisedDateMonthPosition = localisedDateFormatSplit.findIndex((x) => /m/gi.test(x));
+ const localisedDateYearPosition = localisedDateFormatSplit.findIndex((x) => /y/gi.test(x));
+
+ let splitDateString = dateString.split(dateStringDelimiter);
+ let userProvidedYear = splitDateString[localisedDateYearPosition]
+
+ const dateNow = new Date();
+ const stringifiedCurrentYear = dateNow.getFullYear().toString();
+
+ // If we have any input weirdness, or if we have a fully-written year
+ // (e.g. 2022 instead of 22) then use default parse
+ if(splitDateString.length === 0 ||
+ splitDateString.length > 3 ||
+ userProvidedYear.length >= stringifiedCurrentYear.length) {
+
+ return defaultParse();
+ }
+
+ let fullyWrittenYear = userProvidedYear.split("");
+ const digitsToAdd = stringifiedCurrentYear.length - fullyWrittenYear.length;
+ for(let i = 0; i < digitsToAdd; i++) {
+ fullyWrittenYear.splice(i, 0, stringifiedCurrentYear[i])
+ }
+ fullyWrittenYear = fullyWrittenYear.join("");
+
+ const fixedYearNum = Number(fullyWrittenYear);
+ const monthIndexNum = Number(splitDateString[localisedDateMonthPosition]) - 1;
+ const dayNum = Number(splitDateString[localisedDateDayPosition]);
+
+ console.log(dayNum, monthIndexNum, fixedYearNum);
+
+ // Modification: return date in UTC
+ return new Date(Date.UTC(fixedYearNum, monthIndexNum, dayNum));
+ }
+
+ Layout.fillWidth: true
+ height: visible ? implicitHeight : 0
+
+
+ // We want all the internal benefits of the spinbox but don't actually want the
+ // buttons, so set an empty item as a dummy
+ up.indicator: Item {}
+ down.indicator: Item {}
+
+ background: Rectangle {
+ radius: Style.slightlyRoundedButtonRadius
+ border.width: Style.normalBorderWidth
+ border.color: expireDateSpinBox.activeFocus ? Style.ncBlue : Style.menuBorder
+ color: Style.backgroundColor
+ }
+
+ value: expireDateReduced
+ from: minimumExpireDateReduced
+ to: maximumExpireDateReduced
+
+ textFromValue: (value, locale) => {
+ const dateFromValue = new Date(value * dayInMSecs);
+ return dateFromValue.toLocaleDateString(Qt.locale(), Locale.NarrowFormat);
+ }
+ valueFromText: (text, locale) => {
+ const dateFromText = parseDateString(text);
+ return Math.floor(dateFromText.getTime() / dayInMSecs);
+ }
+
+ editable: true
+ inputMethodHints: Qt.ImhDate | Qt.ImhFormattedNumbersOnly
+
+ enabled: root.expireDateEnabled &&
+ !root.waitingForExpireDateChange &&
+ !root.waitingForExpireDateEnabledChange
+
+ onValueModified: {
+ if (!enabled || !activeFocus) {
+ return;
+ }
+
+ root.setExpireDate(value * dayInMSecs);
+ root.waitingForExpireDateChange = true;
+ }
+
+ NCBusyIndicator {
+ anchors.fill: parent
+ visible: root.waitingForExpireDateEnabledChange ||
+ root.waitingForExpireDateChange
+ running: visible
+ z: 1
+ }
}
- fullyWrittenYear = fullyWrittenYear.join("");
-
- const fixedYearNum = Number(fullyWrittenYear);
- const monthIndexNum = Number(splitDateString[localisedDateMonthPosition]) - 1;
- const dayNum = Number(splitDateString[localisedDateDayPosition]);
-
- console.log(dayNum, monthIndexNum, fixedYearNum);
-
- // Modification: return date in UTC
- return new Date(Date.UTC(fixedYearNum, monthIndexNum, dayNum));
}
- Layout.fillWidth: true
- height: visible ? implicitHeight : 0
-
+ CheckBox {
+ id: noteEnabledMenuItem
- // We want all the internal benefits of the spinbox but don't actually want the
- // buttons, so set an empty item as a dummy
- up.indicator: Item {}
- down.indicator: Item {}
+ Layout.fillWidth: true
- background: Rectangle {
- radius: Style.slightlyRoundedButtonRadius
- border.width: Style.normalBorderWidth
- border.color: expireDateSpinBox.activeFocus ? Style.ncBlue : Style.menuBorder
- color: Style.backgroundColor
- }
+ spacing: moreMenu.indicatorSpacing
+ padding: moreMenu.itemPadding
+ indicator.width: moreMenu.indicatorItemWidth
+ indicator.height: moreMenu.indicatorItemWidth
- value: expireDateReduced
- from: minimumExpireDateReduced
- to: maximumExpireDateReduced
+ checkable: true
+ checked: root.noteEnabled
+ text: qsTr("Note to recipient")
+ enabled: !root.waitingForNoteEnabledChange
- textFromValue: (value, locale) => {
- const dateFromValue = new Date(value * dayInMSecs);
- return dateFromValue.toLocaleDateString(Qt.locale(), Locale.NarrowFormat);
- }
- valueFromText: (text, locale) => {
- const dateFromText = parseDateString(text);
- return Math.floor(dateFromText.getTime() / dayInMSecs);
- }
-
- editable: true
- inputMethodHints: Qt.ImhDate | Qt.ImhFormattedNumbersOnly
-
- enabled: root.expireDateEnabled &&
- !root.waitingForExpireDateChange &&
- !root.waitingForExpireDateEnabledChange
-
- onValueModified: {
- if (!enabled || !activeFocus) {
- return;
+ onClicked: {
+ root.toggleNoteToRecipient(checked);
+ root.waitingForNoteEnabledChange = true;
}
- root.setExpireDate(value * dayInMSecs);
- root.waitingForExpireDateChange = true;
+ NCBusyIndicator {
+ anchors.fill: parent
+ visible: root.waitingForNoteEnabledChange
+ running: visible
+ z: 1
+ }
}
- NCBusyIndicator {
- anchors.fill: parent
- visible: root.waitingForExpireDateEnabledChange ||
- root.waitingForExpireDateChange
- running: visible
- z: 1
- }
- }
- }
+ RowLayout {
+ Layout.fillWidth: true
+ height: visible ? implicitHeight : 0
+ spacing: moreMenu.indicatorSpacing
- CheckBox {
- id: noteEnabledMenuItem
+ visible: root.noteEnabled
- spacing: moreMenu.indicatorSpacing
- padding: moreMenu.itemPadding
- indicator.width: moreMenu.indicatorItemWidth
- indicator.height: moreMenu.indicatorItemWidth
+ Image {
+ Layout.preferredWidth: moreMenu.indicatorItemWidth
+ Layout.fillHeight: true
- checkable: true
- checked: root.noteEnabled
- text: qsTr("Note to recipient")
- enabled: !root.waitingForNoteEnabledChange
+ verticalAlignment: Image.AlignVCenter
+ horizontalAlignment: Image.AlignHCenter
+ fillMode: Image.Pad
- onClicked: {
- root.toggleNoteToRecipient(checked);
- root.waitingForNoteEnabledChange = true;
- }
+ source: "image://svgimage-custom-color/edit.svg/" + Style.menuBorder
+ sourceSize.width: moreMenu.rowIconWidth
+ sourceSize.height: moreMenu.rowIconWidth
+ }
- NCBusyIndicator {
- anchors.fill: parent
- visible: root.waitingForNoteEnabledChange
- running: visible
- z: 1
+ NCInputTextEdit {
+ id: noteTextEdit
+
+ Layout.fillWidth: true
+ height: visible ? Math.max(Style.talkReplyTextFieldPreferredHeight, contentHeight) : 0
+ submitButton.height: Math.min(Style.talkReplyTextFieldPreferredHeight, height - 2)
+
+ text: root.note
+ enabled: root.noteEnabled &&
+ !root.waitingForNoteChange &&
+ !root.waitingForNoteEnabledChange
+
+ onEditingFinished: if(text !== root.note) {
+ root.setNote(text);
+ root.waitingForNoteChange = true;
+ }
+
+ NCBusyIndicator {
+ anchors.fill: parent
+ visible: root.waitingForNoteChange ||
+ root.waitingForNoteEnabledChange
+ running: visible
+ z: 1
+ }
+ }
+ }
}
}
RowLayout {
- anchors.left: parent.left
- anchors.leftMargin: moreMenu.itemPadding
- anchors.right: parent.right
- anchors.rightMargin: moreMenu.itemPadding
- height: visible ? implicitHeight : 0
- spacing: moreMenu.indicatorSpacing
-
- visible: root.noteEnabled
-
- Image {
- Layout.preferredWidth: moreMenu.indicatorItemWidth
- Layout.fillHeight: true
-
- verticalAlignment: Image.AlignVCenter
- horizontalAlignment: Image.AlignHCenter
- fillMode: Image.Pad
+ Layout.fillWidth: true
- source: "image://svgimage-custom-color/edit.svg/" + Style.menuBorder
- sourceSize.width: moreMenu.rowIconWidth
- sourceSize.height: moreMenu.rowIconWidth
+ CustomButton {
+ Layout.fillWidth: true
+ implicitWidth: parent.width / 2
+ height: Style.standardPrimaryButtonHeight
+
+ imageSource: "image://svgimage-custom-color/close.svg/" + Style.ncHeaderTextColor
+ text: qsTr("Unshare")
+ textColor: Style.ncHeaderTextColor
+ contentsFont.bold: true
+ bgColor: Style.errorBoxBackgroundColor
+ bgNormalOpacity: 1.0
+ bgHoverOpacity: Style.hoverOpacity
+
+ onClicked: root.deleteShare()
}
- NCInputTextEdit {
- id: noteTextEdit
-
+ CustomButton {
Layout.fillWidth: true
- height: visible ? Math.max(Style.talkReplyTextFieldPreferredHeight, contentHeight) : 0
- submitButton.height: Math.min(Style.talkReplyTextFieldPreferredHeight, height - 2)
+ implicitWidth: parent.width / 2
+ height: Style.standardPrimaryButtonHeight
- text: root.note
- enabled: root.noteEnabled &&
- !root.waitingForNoteChange &&
- !root.waitingForNoteEnabledChange
+ imageSource: "image://svgimage-custom-color/add.svg/" + Style.ncHeaderTextColor
+ text: qsTr("Add another link")
+ textColor: Style.ncHeaderTextColor
+ contentsFont.bold: true
+ bgColor: Style.ncBlue
+ bgNormalOpacity: 1.0
+ bgHoverOpacity: Style.hoverOpacity
- onEditingFinished: if(text !== root.note) {
- root.setNote(text);
- root.waitingForNoteChange = true;
- }
+ visible: root.isLinkShare && root.canCreateLinkShares
+ enabled: visible
- NCBusyIndicator {
- anchors.fill: parent
- visible: root.waitingForNoteChange ||
- root.waitingForNoteEnabledChange
- running: visible
- z: 1
- }
+ onClicked: root.createNewLinkShare()
}
}
-
- MenuItem {
- spacing: moreMenu.indicatorSpacing
- padding: moreMenu.itemPadding
-
- icon.width: moreMenu.indicatorItemWidth
- icon.height: moreMenu.indicatorItemWidth
- icon.color: Style.ncTextColor
- icon.source: "qrc:///client/theme/close.svg"
- text: qsTr("Unshare")
-
- onTriggered: root.deleteShare()
- }
-
- MenuItem {
- height: visible ? implicitHeight : 0
- spacing: moreMenu.indicatorSpacing
- padding: moreMenu.itemPadding
-
- icon.width: moreMenu.indicatorItemWidth
- icon.height: moreMenu.indicatorItemWidth
- icon.color: Style.ncTextColor
- icon.source: "qrc:///client/theme/add.svg"
- text: qsTr("Add another link")
-
- visible: root.isLinkShare && root.canCreateLinkShares
- enabled: visible
-
- onTriggered: root.createNewLinkShare()
- }
}
-
}