Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Preview support via Sailfish.WebView #8

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
2 changes: 1 addition & 1 deletion CONTRIBUTORS.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ SPDX-License-Identifier: GFDL-1.3-or-later
## Programming

- author: Mirian Margiani
- many improvements: roundedrectangle
- link title copying, link sharing, webview preview: roundedrectangle
24 changes: 20 additions & 4 deletions Opal/LinkHandler/LinkHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,32 @@
*/

/*!
\qmlmethod bool LinkHandler::openOrCopyUrl(externalUrl, title)
\qmlmethod bool LinkHandler::openOrCopyUrl(externalUrl, title, previewType)

This function shows a page that lets the user preview
an external link (\a externalUrl) before either copying it to the clipboard,
copying its title (if available), sharing it
or opening it externally. The \a title argument is optional.
This module includes an algorithm for checking if the WebView module is installed,
Internet connection is established, Sailjail permissions include Internet usage
and the scheme provided is an Internet scheme.
You can override this algorithm with \a previewType property which can be one of the following:

\list
\li \c LinkPreviewType.auto - default
\li \c LinkPreviewType.internetOnly - skips WebView and scheme check, recommended for internet links where scheme should not be checked
\li \c LinkPreviewType.schemeOnly - skips WebView and internet check
\li \c LinkPreviewType.internetAndScheme - skips WebView check, recommended for links where you can't fully know if scheme is http or https
\li \c LinkPreviewType.disable - skips all checks and disables preview, recommended for apps without Internet and WebVoew permissions
\li \c LinkPreviewType.enable - skips all checks and enables preview

\endlist

It is recommended to set a value different from auto to skip unnecessary checks for performance.

\sa Qt::openUrlExternally
*/
function openOrCopyUrl(externalUrl, title) {
function openOrCopyUrl(externalUrl, title, previewType) {
pageStack.push(Qt.resolvedUrl("private/ExternalUrlPage.qml"),
{'externalUrl': externalUrl, 'title': !!title ? title : ''})
}
{'externalUrl': externalUrl, 'title': !!title ? title : '', 'previewType': typeof previewType !== 'undefined' ? previewType : 0})
}
11 changes: 11 additions & 0 deletions Opal/LinkHandler/PreviewType.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
pragma Singleton
import QtQuick 2.0

QtObject {
property int auto: 0
property int internetOnly: 1
property int schemeOnly: 2
property int internetAndScheme: 3
property int enable: 4
property int disable: 5
}
102 changes: 102 additions & 0 deletions Opal/LinkHandler/private/ExternalUrlPage.qml
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,103 @@ import QtQuick 2.2
import Sailfish.Silica 1.0
import Nemo.Notifications 1.0
import Sailfish.Share 1.0
import Nemo.DBus 2.0
import '..'

Page {
id: root
property url externalUrl
property string title: '' // optional
property int previewType: LinkPreviewType.auto

allowedOrientations: Orientation.All

Component {
id: webViewComponent
Page {
id: webViewPage
allowedOrientations: Orientation.All
property bool __linkhandler_webview: true
property var __webview

onStatusChanged: if (status == PageStatus.Active)
__webview = Qt.createQmlObject("import Sailfish.WebView 1.0
WebView {
anchors.fill: parent
url: externalUrl
}", webViewPage); else if (__webview) __webview.destroy()
Component.onCompleted: statusChanged()
}
}

Timer {
id: pushWebviewTimer
interval: 0
onTriggered: if (previewType === LinkPreviewType.enable) pageStack.pushAttached(webViewComponent)
else if (previewType === LinkPreviewType.schemeOnly) connman.checkState('online')
}

DBusInterface {
// Sailjail info: if we don't specify Internet permission, we won't have access to this service, and as a result no webview will pop up
// And WebView permission doesn't seem to change anything
id: connman
bus: DBus.SystemBus
service: 'net.connman'
iface: 'net.connman.Manager'
path: '/'

signalsEnabled: previewType === LinkPreviewType.auto || previewType === LinkPreviewType.internetOnly || previewType === LinkPreviewType.internetAndScheme

function checkState(state) {
if (state === "online") {
if (previewType === LinkPreviewType.auto) {
try {
const tester = Qt.createQmlObject("import QtQuick 2.0
import Sailfish.Silica 1.0
import Sailfish.WebView 1.0
Item{}", root, 'WebviewTester [inline]')
} catch(err) { console.log(err); return }
if (typeof tester === 'undefined') return
tester.destroy()
}

if (previewType !== LinkPreviewType.internetOnly) {
switch (externalUrl.toString().slice(0, externalUrl.toString().indexOf(':'))) {
case 'http':
case 'https':
//case 'file':
break
default: return
}
}

if (!pageStack.nextPage())
pageStack.pushAttached(webViewComponent)
} else if (pageStack.nextPage() && pageStack.nextPage().__linkhandler_webview)
pageStack.popAttached()
}

function propertyChanged(name, value) {
if (name === 'State') checkState(value)
}

Component.onCompleted:{
switch (previewType) {
case LinkPreviewType.disable:
break
case LinkPreviewType.enable:
case LinkPreviewType.schemeOnly:
// pageStack.completeAnimation doesn't work
pushWebviewTimer.start()
break
default:
call('GetProperties', [], function(properties) {
checkState(properties.State)
})
}
}
}

ShareAction {
id: shareHandler
mimeType: 'text/x-url'
Expand Down Expand Up @@ -70,6 +159,8 @@ Page {
}
width: parent.width
spacing: Theme.paddingLarge
height: implicitHeight
Behavior on height { NumberAnimation { duration: 200 } }

ButtonLayout {
id: firstRow
Expand Down Expand Up @@ -123,5 +214,16 @@ Page {
}
}
}

Label {
text: qsTr("Swipe left to preview")
visible: pageStack.nextPage() && pageStack.nextPage().__linkhandler_webview
width: parent.width - 2*Theme.horizontalPageMargin
anchors.horizontalCenter: parent.horizontalCenter
horizontalAlignment: Text.AlignHCenter
color: Theme.secondaryHighlightColor
font.pixelSize: Theme.fontSizeSmall
wrapMode: Text.Wrap
}
}
}
1 change: 1 addition & 0 deletions Opal/LinkHandler/qmldir
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ module Opal.LinkHandler
# SPDX-FileCopyrightText: 2023 Mirian Margiani
# SPDX-License-Identifier: GPL-3.0-or-later
LinkHandler 1.0 LinkHandler.js
singleton LinkPreviewType 1.0 PreviewType.qml
21 changes: 17 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ SPDX-License-Identifier: GFDL-1.3-or-later

# Link handler for Sailfish apps

This module provides a link handler to open, copy or share external links.
This module provides a link handler to open, copy, share or preview external links.

Text items and Silica's `Label` support external links using the
`<a href="url">title</a>` notation. They can then be opened externally when
clicked by a user.

To avoid surprises, it is often desirable to give users the option to copy an
external link instead of immediately opening it in the default web browser.
This module provides a way to do that.
To avoid surprises, it is often desirable to give users the option to copy,
share or preview an external link instead of immediately opening it
in the default web browser. This module provides a way to do that.


## Usage
Expand All @@ -34,6 +34,19 @@ Label {
}
```

## Permissions

Some permissions are required for WebView-based preview support in this module to work in Sailjail. Make sure that if you aren't using Internet URLs you don't need Internet permission, and if you are not using preview at all you don't need any of these permissions.

Add this to your `harbour-my-app.desktop` file:

```{ini}
[X-Sailjail]
Permissions=Internet;WebView
```

See [here](https://github.com/sailfishos/sailjail-permissions#permissions) for a list of all Sailjail permissions.

## Screenshots

| 1. | 2. |
Expand Down