Skip to content

Commit

Permalink
Linked Image Rendering & Image Viewer
Browse files Browse the repository at this point in the history
- Renders linked images in post content.
- Implements an image viewer dialog with download and copy URL functionality.
- Improves spacing within post content and between content & scrollbars.
- Adds download functionality for images, showing notifications on completion.

Rich Text & Reference Handling

- Parses post content as rich text, providing a more polished display.
- Handles profile and note references, enabling navigation to relevant views.
- Fixes referenced post display for both reposts and quote reposts.

Video Support

- Detects video URLs within post content and embeds a new PostVideo component.
- Implements video playback controls (play/pause, progress bar, time display).
- Adds a dedicated video viewer dialog with asynchronous download and copy URL options.
- Fixes notification positioning for video downloads.
- Introduces Qt Multimedia dependencies and relevant icons.

Fullscreen Video Flow

- Adds FullscreenVideoWindow for seamless fullscreen playback.
- Creates a reusable NotificationToast component for consistent notifications.
- Replaces ad-hoc fullscreen logic with the new VideoPlayer component to eliminate flicker.

Scrolling & UI Improvements

- Simplifies logic in ScrollingListView for smoother scrolling and user interaction.
- Improves scrollbar interactivity with arrow buttons for easier navigation.
  • Loading branch information
prolic committed Feb 26, 2025
1 parent 6dcc5fa commit 7ec97d9
Show file tree
Hide file tree
Showing 28 changed files with 1,295 additions and 134 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/continuous.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ jobs:
- name: Install Qt5 Dependencies
run: |
sudo apt-get install -y qtdeclarative5-dev libqt5quick5 qt5-image-formats-plugins qttools5-dev-tools qtbase5-dev
sudo apt-get install -y qtdeclarative5-dev libqt5quick5 qt5-image-formats-plugins qtmultimedia5-dev qml-module-qtmultimedia qttools5-dev-tools qtbase5-dev
- name: Install secp256k1 Library
run: |
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ jobs:
- name: Install Qt5 Dependencies
run: |
sudo apt-get install -y qtdeclarative5-dev libqt5quick5 qt5-image-formats-plugins qttools5-dev-tools qtbase5-dev
sudo apt-get install -y qtdeclarative5-dev libqt5quick5 qt5-image-formats-plugins qtmultimedia5-dev qml-module-qtmultimedia qttools5-dev-tools qtbase5-dev
- name: Install secp256k1 Library
run: |
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ jobs:
- name: Install Qt5 Dependencies
run: |
sudo apt-get install -y qtdeclarative5-dev libqt5quick5 qt5-image-formats-plugins qttools5-dev-tools qtbase5-dev
sudo apt-get install -y qtdeclarative5-dev libqt5quick5 qt5-image-formats-plugins qtmultimedia5-dev qml-module-qtmultimedia qttools5-dev-tools qtbase5-dev
- name: Install secp256k1 Library
run: |
Expand Down
2 changes: 2 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ RUN apt-get update && apt-get install -y \
qt5-image-formats-plugins \
qttools5-dev-tools \
qtbase5-dev \
qtmultimedia5-dev \
qml-module-qtmultimedia \
wget \
sudo \
build-essential \
Expand Down
2 changes: 2 additions & 0 deletions docs/Setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ sudo apt-get install qtdeclarative5-dev \
libqt5quick5 \
qttools5-dev-tools \
qtbase5-dev \
qtmultimedia5-dev \
qml-module-qtmultimedia \
qt5-image-formats-plugins \
liblmdb-dev
```
Expand Down
1 change: 1 addition & 0 deletions resources/icons/download.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions resources/icons/fullscreen.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions resources/icons/fullscreen_exit.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions resources/icons/pause.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions resources/icons/play_arrow.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 0 additions & 1 deletion resources/qml/content/AccountList.ui.qml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import Dialogs 1.0
import Futr 1.0
import HsQML.Model 1.0


ScrollView {
Layout.fillWidth: true
Layout.fillHeight: true
Expand Down
2 changes: 1 addition & 1 deletion resources/qml/content/App.qml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import HsQML.Clipboard 1.0
import Futr 1.0

ApplicationWindow {
id: root
id: appWindow
width: Constants.width
height: Constants.height
minimumWidth: 920
Expand Down
61 changes: 61 additions & 0 deletions resources/qml/content/Components/FullscreenVideoWindow.ui.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Controls.Material 2.15
import QtQuick.Window 2.15
import QtMultimedia 5.15

import Components 1.0

Window {
id: fullscreenVideoWindow
visible: true
width: Screen.width
height: Screen.height
visibility: Window.FullScreen
color: "black"
flags: Qt.Window | Qt.FramelessWindowHint

property string videoUrl: ""

NotificationToast {
id: notification
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
anchors.bottomMargin: 100
}

VideoPlayer {
id: fullscreenVideoPlayer
anchors.fill: parent
videoSource: fullscreenVideoWindow.videoUrl
isFullscreen: true

onShowNotification: function(message) {
notification.show(message)
}

Component.onCompleted: {
fullscreenVideoPlayer.play()
}

onFullScreenRequested: {
fullscreenVideoPlayer.stop()
fullscreenVideoWindow.close()
}
}

Item {
anchors.fill: parent
focus: true
Keys.onEscapePressed: {
fullscreenVideoPlayer.stop()
fullscreenVideoWindow.close()
}
}

Component.onDestruction: {
if (fullscreenVideoPlayer) {
fullscreenVideoPlayer.stop()
}
}
}
12 changes: 6 additions & 6 deletions resources/qml/content/Components/MessageInput.ui.qml
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,18 @@ import Futr 1.0

Pane {
id: root

property string placeholderText: qsTr("Type a message...")
property string buttonText: qsTr("Send")

signal messageSent(string text)

Layout.fillWidth: true
Layout.leftMargin: Constants.spacing_m
Layout.rightMargin: Constants.spacing_m
Layout.bottomMargin: Constants.spacing_m
padding: Constants.spacing_m

background: Rectangle {
color: Material.dialogColor
radius: 5
Expand All @@ -45,7 +45,7 @@ Pane {
wrapMode: TextArea.Wrap
font: Constants.fontMedium
focus: true

Keys.onReturnPressed: function(event) {
if (event.modifiers & Qt.ShiftModifier) {
event.accepted = false
Expand All @@ -63,7 +63,7 @@ Pane {
implicitWidth: 80
implicitHeight: 36
Layout.alignment: Qt.AlignVCenter

onClicked: sendMessage()
}
}
Expand Down
39 changes: 39 additions & 0 deletions resources/qml/content/Components/NotificationToast.ui.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Controls.Material 2.15

Rectangle {
id: root
width: notificationText.width + 40
height: 40
radius: 20
color: Material.accent
opacity: 0
z: 999999

property alias text: notificationText.text

Text {
id: notificationText
anchors.centerIn: parent
text: ""
color: "white"
font.bold: true
}

Behavior on opacity {
NumberAnimation { duration: 300 }
}

Timer {
id: closeTimer
interval: 3000
running: root.opacity > 0
onTriggered: root.opacity = 0
}

function show(message) {
text = message
opacity = 1.0
}
}
Loading

0 comments on commit 7ec97d9

Please sign in to comment.