diff --git a/harbour-tooter.pro b/harbour-tooter.pro index 275feee..85000db 100644 --- a/harbour-tooter.pro +++ b/harbour-tooter.pro @@ -12,6 +12,8 @@ # The name of your application TARGET = harbour-tooter +QT += network dbus sql + CONFIG += sailfishapp SOURCES += src/harbour-tooter.cpp \ diff --git a/qml/lib/API.js b/qml/lib/API.js index df46b3f..3b8d784 100644 --- a/qml/lib/API.js +++ b/qml/lib/API.js @@ -116,7 +116,7 @@ var notificationGenerator = function(item){ var notification; switch (item.urgency){ case "normal": - notification = Qt.createQmlObject('import org.nemomobile.notifications 1.0; Notification { category: "x-nemo.example"; urgency: Notification.Normal; }', Qt.application, 'InternalQmlObject'); + notification = Qt.createQmlObject('import org.nemomobile.notifications 1.0; Notification { category: "x-nemo.example"; urgency: Notification.Normal; }', Qt.application, 'InternalQmlObject'); break; case "critical": notification = Qt.createQmlObject('import org.nemomobile.notifications 1.0; Notification { category: "x-nemo.example"; urgency: Notification.Critical; }', Qt.application, 'InternalQmlObject'); @@ -124,6 +124,7 @@ var notificationGenerator = function(item){ default: notification = Qt.createQmlObject('import org.nemomobile.notifications 1.0; Notification { category: "x-nemo.example"; urgency: Notification.Low; }', Qt.application, 'InternalQmlObject'); } + notification.timestamp = item.timestamp notification.summary = item.summary notification.body = item.body @@ -176,7 +177,7 @@ var notifier = function(item){ } break; default: - console.log(JSON.stringify(messageObject.data)) + //console.log(JSON.stringify(messageObject.data)) return; } notificationGenerator(msg) diff --git a/qml/lib/Worker.js b/qml/lib/Worker.js index c538394..40d09ff 100644 --- a/qml/lib/Worker.js +++ b/qml/lib/Worker.js @@ -207,6 +207,7 @@ function getDate(dateStr){ function parseToot (data){ //console.log(JSON.stringify(data)) var item = {}; + item['type'] = "toot" item['highlight'] = false item['status_id'] = data["id"] diff --git a/qml/pages/Conversation.qml b/qml/pages/Conversation.qml index 073a34b..818226d 100644 --- a/qml/pages/Conversation.qml +++ b/qml/pages/Conversation.qml @@ -147,6 +147,7 @@ Page { RemorseItem { id: remorse } Image { anchors.fill: parent + fillMode: Image.PreserveAspectCrop source: model.preview_url } diff --git a/qml/pages/components/ImageFullScreen.qml b/qml/pages/components/ImageFullScreen.qml index eef3805..97400c4 100644 --- a/qml/pages/components/ImageFullScreen.qml +++ b/qml/pages/components/ImageFullScreen.qml @@ -3,117 +3,205 @@ import Sailfish.Silica 1.0 import QtMultimedia 5.0 Page { - id: page + id: imagePage property string type: "" property string previewURL: "" property string mediaURL: "" allowedOrientations: Orientation.All - Component.onCompleted: { + Component.onCompleted: function(){ console.log(type) console.log(previewURL) console.log(mediaURL) - } - onStateChanged: { - if (status === PageStatus.Deactivating){ - video.stop() - } - if (status === PageStatus.Activating){ - if (type !== "image" ) - video.play() + if (type != 'gifv' && type != 'video') { + imagePreview.source = mediaURL + imageFlickable.visible = true; + } else { + video.source = mediaURL + video.fillMode = VideoOutput.PreserveAspectFit + video.play() + videoFlickable.visible = true; } } - BusyIndicator { - running: image.status !== Image.Ready - size: BusyIndicatorSize.Large - anchors.verticalCenter: parent.verticalCenter - anchors.horizontalCenter: parent.horizontalCenter - } - Item { + Flickable { + id: videoFlickable + visible: false anchors.fill: parent + contentWidth: imageContainer.width; contentHeight: imageContainer.height clip: true Image { - id: image - anchors.centerIn: parent - fillMode: Image.PreserveAspectCrop - asynchronous: true - opacity: status === Image.Ready ? 1.0 : 0.0 - Behavior on opacity { FadeAnimator {} } - source: type === "image" ? mediaURL : previewURL - onStatusChanged: { - if (status === Image.Ready) { - console.log('Loaded') - width = sourceSize.width - height = sourceSize.height - if (width > height) - pinch.scale = page.width / width - else - pinch.scale = page.height / height - } - } - Video { - id: video - anchors.fill: parent - autoLoad: true - onStateChanged: { - switch(status){ - case MediaPlayer.Loaded: - play(); - break; - case MediaPlayer.Loading: - loader.running = true; - break; - case MediaPlayer.EndOfMedia: - if(seekable) - seek(0) - break; - default: - loader.running = false; - } - } - - source: type !== "image" ? mediaURL : "" - onErrorStringChanged: { - console.log(errorString) - } - BusyIndicator { - id: loader - size: BusyIndicatorSize.Small - anchors.verticalCenter: parent.verticalCenter - anchors.horizontalCenter: parent.horizontalCenter - } - - MouseArea { - anchors.fill: parent - onClicked: { - video.playbackState == MediaPlayer.PlayingState ? video.pause() : video.play() - } - } - - focus: true - } - + id: videoPreview + fillMode: Image.PreserveAspectFit + anchors.fill: parent + source: previewURL } + Video { + id: video + anchors.fill: parent + onPositionChanged: function(){ + console.log(duration) + console.log(bufferProgress) + console.log(position) + progressRec.width = parent.width * position/duration + } + onStopped: function(){ + play() + } + } + Rectangle { + id: progressRec + anchors.bottom: parent.bottom + width: 0 + height: Theme.paddingSmall + color: Theme.highlightBackgroundColor + } + } + Flickable { + id: imageFlickable + visible: false + anchors.fill: parent + contentWidth: imageContainer.width; contentHeight: imageContainer.height + clip: true + onHeightChanged: if (imagePreview.status === Image.Ready) imagePreview.fitToScreen(); + Item { + id: imageContainer + width: Math.max(imagePreview.width * imagePreview.scale, imageFlickable.width) + height: Math.max(imagePreview.height * imagePreview.scale, imageFlickable.height) + + Image { + id: imagePreview + + property real prevScale + + function fitToScreen() { + scale = Math.min(imageFlickable.width / width, imageFlickable.height / height, 1) + pinchArea.minScale = scale + prevScale = scale + } + + anchors.centerIn: parent + fillMode: Image.PreserveAspectFit + cache: true + asynchronous: true + sourceSize.height: 1000; + smooth: false + + onStatusChanged: { + if (status == Image.Ready) { + fitToScreen() + loadedAnimation.start() + } + } + + NumberAnimation { + id: loadedAnimation + target: imagePreview + property: "opacity" + duration: 250 + from: 0; to: 1 + easing.type: Easing.InOutQuad + } + + onScaleChanged: { + if ((width * scale) > imageFlickable.width) { + var xoff = (imageFlickable.width / 2 + imageFlickable.contentX) * scale / prevScale; + imageFlickable.contentX = xoff - imageFlickable.width / 2 + } + if ((height * scale) > imageFlickable.height) { + var yoff = (imageFlickable.height / 2 + imageFlickable.contentY) * scale / prevScale; + imageFlickable.contentY = yoff - imageFlickable.height / 2 + } + prevScale = scale + } + } + } PinchArea { - id: pinch - visible: type === "image" + id: pinchArea + opacity: 0.3 + property real minScale: 1.0 + property real maxScale: 3.0 + anchors.fill: parent - pinch.target: image - pinch.minimumScale: 0.1 - pinch.maximumScale: 10 - pinch.dragAxis: Pinch.XAndYAxis - } - Label { - visible: type !== "image" - anchors { - bottom: parent.bottom - left: parent.left - right: parent.right + enabled: imagePreview.status === Image.Ready + pinch.target: imagePreview + pinch.minimumScale: minScale * 0.5 // This is to create "bounce back effect" + pinch.maximumScale: maxScale * 1.5 // when over zoomed + + onPinchFinished: { + imageFlickable.returnToBounds() + if (imagePreview.scale < pinchArea.minScale) { + bounceBackAnimation.to = pinchArea.minScale + bounceBackAnimation.start() + } + else if (imagePreview.scale > pinchArea.maxScale) { + bounceBackAnimation.to = pinchArea.maxScale + bounceBackAnimation.start() + } + } + NumberAnimation { + id: bounceBackAnimation + target: imagePreview + duration: 250 + property: "scale" + from: imagePreview.scale + } + } + } + + Loader { + anchors.centerIn: parent + sourceComponent: { + switch (imagePreview.status) { + case Image.Loading: + return loadingIndicator + case Image.Error: + return failedLoading + default: + return undefined } - text: "Video playing is faulty... may break app... Just to know :)" } + Component { + id: loadingIndicator + + Item { + height: childrenRect.height + width: imagePage.width + + ProgressCircle { + id: imageLoadingIndicator + anchors.horizontalCenter: parent.horizontalCenter + progressValue: imagePreview.progress + } + } + } + + Component { + id: failedLoading + Text { + font.pixelSize: Theme.fontSizeSmall; + text: qsTr("Error loading image") + color: Theme.highlightColor + } + } + } + + VerticalScrollDecorator { flickable: imageFlickable } + IconButton { + visible: false + anchors{ + right: imagePage.right; + rightMargin: Theme.paddingLarge; + bottom: imagePage.bottom; + bottomMargin: Theme.paddingLarge; + } + width: Theme.iconSizeMedium+Theme.paddingMedium*2 + + icon.source: "image://theme/icon-m-cloud-download" + onClicked: { + //py.saveImg(MD5.hex_md5(strThumbnailUrl),strHpTitle+"."+Script.parseDate(currentDay)); + } } } diff --git a/qml/pages/components/MyImage.qml b/qml/pages/components/MyImage.qml index 4f94ce9..13cd278 100644 --- a/qml/pages/components/MyImage.qml +++ b/qml/pages/components/MyImage.qml @@ -10,7 +10,6 @@ Item { opacity: 0.2 anchors.fill: parent color: Theme.highlightDimmerColor - } Image { anchors.centerIn: parent diff --git a/qml/pages/components/MyList.qml b/qml/pages/components/MyList.qml index d2f5967..b6b9497 100644 --- a/qml/pages/components/MyList.qml +++ b/qml/pages/components/MyList.qml @@ -57,6 +57,19 @@ SilicaListView { } PullDownMenu { + MenuItem { + text: "NOTIFIKACIJA" + onClicked: { + Logic.notifier({ + type: "favourite", + urgency: "critical", + created_at: new Date(), + reblog_account_display_name: "@akakakak", + content: "blaaaaaa blaaaaaablaaaaaablaaaaaa" + + }) + } + } MenuItem { text: qsTr("Settings") onClicked: { diff --git a/qml/pages/components/Toot.qml b/qml/pages/components/Toot.qml index 0afa99f..fb9b9ab 100644 --- a/qml/pages/components/Toot.qml +++ b/qml/pages/components/Toot.qml @@ -186,4 +186,5 @@ BackgroundItem { type: "reply" }) } + } diff --git a/qml/pages/components/VisualContainer.qml b/qml/pages/components/VisualContainer.qml index 182c541..d3f6aaf 100644 --- a/qml/pages/components/VisualContainer.qml +++ b/qml/pages/components/VisualContainer.qml @@ -9,6 +9,16 @@ BackgroundItem { signal navigateTo(string link) width: parent.width height: mnu.height + miniHeader.height + (typeof attachments !== "undefined" && attachments.count ? media.height + Theme.paddingLarge + Theme.paddingMedium: Theme.paddingLarge) + lblContent.height + Theme.paddingLarge + (ministatus.visible ? ministatus.height : 0) + Rectangle { + x: 0; + y: 0; + visible: status_visibility == 'direct' + width: parent.width + height: parent.height + opacity: 0.3 + color: Theme.highlightBackgroundColor; + } + MiniStatus { id: ministatus anchors { @@ -284,4 +294,5 @@ BackgroundItem { onDoubleClicked: { console.log("double click") } + } diff --git a/translations/harbour-tooter-de.ts b/translations/harbour-tooter-de.ts index a0f8268..fe77649 100644 --- a/translations/harbour-tooter-de.ts +++ b/translations/harbour-tooter-de.ts @@ -78,6 +78,13 @@ + + ImageFullScreen + + Error loading image + + + ImageUploader diff --git a/translations/harbour-tooter-el.ts b/translations/harbour-tooter-el.ts index c41c9bb..544825a 100644 --- a/translations/harbour-tooter-el.ts +++ b/translations/harbour-tooter-el.ts @@ -78,6 +78,13 @@ Κτυπήστε για εισαγωγή + + ImageFullScreen + + Error loading image + + + ImageUploader diff --git a/translations/harbour-tooter-en.ts b/translations/harbour-tooter-en.ts index e0a6f62..937c8e7 100644 --- a/translations/harbour-tooter-en.ts +++ b/translations/harbour-tooter-en.ts @@ -78,6 +78,13 @@ Tap to insert + + ImageFullScreen + + Error loading image + + + ImageUploader diff --git a/translations/harbour-tooter-es.ts b/translations/harbour-tooter-es.ts index a8e95cf..c2aa5e2 100644 --- a/translations/harbour-tooter-es.ts +++ b/translations/harbour-tooter-es.ts @@ -78,6 +78,13 @@ Toca para insertar + + ImageFullScreen + + Error loading image + + + ImageUploader diff --git a/translations/harbour-tooter-fr.ts b/translations/harbour-tooter-fr.ts index 7eeceda..47f359d 100644 --- a/translations/harbour-tooter-fr.ts +++ b/translations/harbour-tooter-fr.ts @@ -78,6 +78,13 @@ Appuyez pour insérer + + ImageFullScreen + + Error loading image + + + ImageUploader diff --git a/translations/harbour-tooter-nl.ts b/translations/harbour-tooter-nl.ts index 6b549f6..64c067f 100644 --- a/translations/harbour-tooter-nl.ts +++ b/translations/harbour-tooter-nl.ts @@ -78,6 +78,13 @@ + + ImageFullScreen + + Error loading image + + + ImageUploader diff --git a/translations/harbour-tooter-oc.ts b/translations/harbour-tooter-oc.ts index e223ef4..ca0a76c 100644 --- a/translations/harbour-tooter-oc.ts +++ b/translations/harbour-tooter-oc.ts @@ -78,6 +78,13 @@ Tustejar per inserir + + ImageFullScreen + + Error loading image + + + ImageUploader diff --git a/translations/harbour-tooter-sr.ts b/translations/harbour-tooter-sr.ts index 801a73c..4485d18 100644 --- a/translations/harbour-tooter-sr.ts +++ b/translations/harbour-tooter-sr.ts @@ -78,6 +78,13 @@ Тапни за убацивање + + ImageFullScreen + + Error loading image + + + ImageUploader diff --git a/translations/harbour-tooter.ts b/translations/harbour-tooter.ts index 8c4bdad..7569f9e 100644 --- a/translations/harbour-tooter.ts +++ b/translations/harbour-tooter.ts @@ -78,6 +78,13 @@ Tap to insert + + ImageFullScreen + + Error loading image + + + ImageUploader