[Sailfish] Night View mode

This commit is contained in:
Muki 2016-11-19 14:01:15 +01:00
parent e005aaadfa
commit 7f99968e7d
7 changed files with 182 additions and 37 deletions

View file

@ -45,11 +45,13 @@ Page {
property int markAsReadTime: 4000
property int toolbarHideTime: 4000
property bool readerMode: false
property bool nightMode: false
property bool readerModePossible: false
property bool nightModePossible: true
property bool autoReaderMode: settings.readerMode
function openUrlEntryInBrowser(url) {
notification.show(qsTr("Launching an external browser..."))
notification.show(qsTr("Launching an external browser."))
Qt.openUrlExternally(url)
}
@ -66,11 +68,21 @@ Page {
function navigate(url) {
if (settings.offlineMode) {
// WORKAROUND for https://github.com/mkiol/kaktus/issues/14
//utils.resetQtWebKit()
var xhr = new XMLHttpRequest()
xhr.onreadystatechange = function () {
console.log("xhr.onreadystatechange")
console.log(" xhr.readyState: " + xhr.readyState)
console.log(" xhr.status: " + xhr.status)
console.log(" xhr.responseType: " + xhr.responseType)
console.log(" xhr.responseURL : " + xhr.responseURL )
console.log(" xhr.statusText: " + xhr.statusText)
if(xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
view.loadHtml(xhr.responseText)
}
}
xhr.open("GET", offlineUrl);
xhr.send()
@ -83,6 +95,7 @@ Page {
if (view.canGoBack) {
view.goBack()
root.readerModePossible = false
root.nightModePossible = false
//view.scrollToTop()
} else {
pageStack.pop()
@ -115,16 +128,25 @@ Page {
}
function switchReaderMode() {
postMessage(root.readerMode ? "readermodehandler_disable" : "readermodehandler_enable");
postMessage(root.readerMode ? "readability_disable" : "readability_enable")
}
function switchNightMode() {
postMessage(root.nightMode ? "nightmode_disable" : "nightmode_enable")
}
function messageReceivedHandler(message) {
if (message.type === "theme_init") {
initTheme()
} else if (message.type === "readability_result") {
root.nightModePossible = true
if ((settings.nightMode || root.nightMode) && !settings.offlineMode) {
postMessage("nightmode_enable")
} else {
postMessage("nightmode_disable")
}
} else if (message.type === "readability_result") {
root.readerModePossible = message.data.possible
root.readerMode = message.data.enabled
@ -133,6 +155,8 @@ Page {
(root.autoReaderMode || settings.offlineMode)) {
switchReaderMode()
root.autoReaderMode = false
} else if (settings.offlineMode) {
postMessage("theme_apply")
}
} else if (message.type === "readability_status") {
@ -149,6 +173,14 @@ Page {
root.readerMode = false
view.scrollToTop()
} else if (message.type === "nightmode_enabled") {
root.nightMode = true
} else if (message.type === "nightmode_disabled") {
root.nightMode = false
}
}
@ -203,12 +235,14 @@ Page {
experimental.overview: false
experimental.enableResizeContent: true
experimental.userAgent: _settings.getDmUserAgent()
//experimental.transparentBackground: true
experimental.userScripts: [
Qt.resolvedUrl("js/ObjectOverrider.js"),
Qt.resolvedUrl("js/Readability.js"),
Qt.resolvedUrl("js/Theme.js"),
Qt.resolvedUrl("js/ReaderModeHandler.js"),
Qt.resolvedUrl("js/NightModeHandler.js"),
Qt.resolvedUrl("js/MessageListener.js")]
experimental.onMessageReceived: {
@ -230,16 +264,17 @@ Page {
timer.start();
// Readability.js
postMessage("readermodehandler_check", { "title": view.canGoBack ? "" : root.title });
postMessage("readability_apply_fixups")
postMessage("readability_check", { "title": view.canGoBack ? "" : root.title });
break;
case WebView.LoadFailedStatus:
proggressPanel.open = false;
if (_settings.offlineMode) {
notification.show(qsTr("Failed to load page from local cache :-("));
notification.show(qsTr("Failed to load page from local cache."));
} else {
notification.show(qsTr("Failed to load page content :-("));
notification.show(qsTr("Failed to load page content."));
}
break;
default:
@ -343,17 +378,27 @@ Page {
text: qsTr("Toggle Reader View")
icon: root.readerMode ? "image://icons/icon-m-reader-selected" : "image://icons/icon-m-reader"
enabled: root.readerModePossible && !settings.offlineMode
visible: true
visible: !settings.offlineMode
onClicked: {
root.switchReaderMode()
}
}
IconBarItem {
text: qsTr("Toggle Night View")
icon: root.nightMode ? "image://icons/icon-m-night-selected" : "image://icons/icon-m-night"
enabled: !root.readerMode && !settings.offlineMode
visible: !settings.offlineMode
onClicked: {
root.switchNightMode()
}
}
IconBarItem {
text: qsTr("Browser")
icon: "image://icons/icon-m-browser"
onClicked: {
notification.show(qsTr("Launching an external browser..."));
notification.show(qsTr("Launching an external browser."));
Qt.openUrlExternally(onlineUrl);
}
}
@ -382,6 +427,15 @@ Page {
}
}
IconBarItem {
text: qsTr("Copy URL")
icon: "image://theme/icon-m-clipboard"
onClicked: {
notification.show(qsTr("URL was copied to the clipboard."));
Clipboard.text = root.onlineUrl;
}
}
IconBarItem {
text: qsTr("Increase font")
icon: "image://icons/icon-m-fontup"
@ -398,15 +452,6 @@ Page {
}
}
IconBarItem {
text: qsTr("Copy URL")
icon: "image://theme/icon-m-clipboard"
onClicked: {
notification.show(qsTr("URL copied to clipboard"));
Clipboard.text = root.onlineUrl;
}
}
IconBarItem {
text: qsTr("Hide toolbar")
icon: "image://theme/icon-m-dismiss"

View file

@ -9,20 +9,26 @@ window.Kaktus_MessageListenerObject.prototype.onMessage = function(message) {
var obj = JSON.parse(message.data);
var data = obj.data;
if(obj.type === "readermodehandler_enable")
if(obj.type === "readability_enable")
Kaktus_ReaderModeHandler.switchMode(true);
else if(obj.type === "readermodehandler_disable")
else if(obj.type === "readability_disable")
Kaktus_ReaderModeHandler.switchMode(false);
else if(obj.type === "readermodehandler_check")
else if(obj.type === "readability_check")
Kaktus_ReaderModeHandler.check(data);
else if(obj.type === "readermodehandler_status")
else if(obj.type === "readability_status")
Kaktus_ReaderModeHandler.status();
else if(obj.type === "readability_apply_fixups")
Kaktus_ReaderModeHandler.applyFixups(document);
else if(obj.type === "theme_set")
Kaktus_Theme.set(data.theme);
else if(obj.type === "theme_update_scale")
Kaktus_Theme.updateScale();
else if(obj.type === "theme_apply")
Kaktus_Theme.apply();
else if(obj.type === "nightmode_disable")
Kaktus_NightModeHandler.switchMode(false);
else if(obj.type === "nightmode_enable")
Kaktus_NightModeHandler.switchMode(true);
};
window.Kaktus_MessageListener = new window.Kaktus_MessageListenerObject();

View file

@ -0,0 +1,50 @@
// Code heavily inspired and partially borrowed from
// harbour-webpirate project (https://github.com/Dax89/harbour-webpirate)
window.Kaktus_NightModeHandlerObject = function() {
this.enabled = false;
this.style_id = "_kaktus_nightmode_style";
this.class_name = "_kaktus_nightmode_class";
}
window.Kaktus_NightModeHandlerObject.prototype.createStyle = function() {
var css = "html." + this.class_name + " { -webkit-filter: contrast(68%) brightness(108%) invert(); }\n" +
"html." + this.class_name + " iframe { -webkit-filter: invert(); }\n" + // Keep iframes normal
"html." + this.class_name + " object { -webkit-filter: invert(); }\n" + // Keep Flash items normal
"html." + this.class_name + " embed { -webkit-filter: invert(); }\n" + // Keep Flash items normal (HTML5)
"html." + this.class_name + " video { -webkit-filter: invert(); }\n" + // Keep HTML5 Videos normal
"html." + this.class_name + " img { -webkit-filter: invert(); }" ; // Keep images normal
var style_ele = document.getElementById(this.style_id);
if (style_ele) {
style_ele.innerHTML = css;
} else {
style_ele = document.createElement("style");
style_ele.id = this.style_id;
style_ele.type = "text/css";
style_ele.appendChild(document.createTextNode(css));
document.head.appendChild(style_ele);
}
};
window.Kaktus_NightModeHandlerObject.prototype.switchMode = function(enabled) {
if (this.enabled === enabled)
return;
var html = document.getElementsByTagName("html")[0];
if (this.enabled) {
this.enabled = false;
html.className = html.className.replace(this.class_name, "");
} else {
this.enabled = true;
this.createStyle();
html.className += " " + this.class_name;
}
var result = { type: "nightmode_" + (this.enabled ? "enabled" : "disabled") };
navigator.qt.postMessage(JSON.stringify(result));
}
window.Kaktus_NightModeHandler = new window.Kaktus_NightModeHandlerObject();

View file

@ -9,6 +9,18 @@ window.Kaktus_ReaderModeHandlerObject = function() {
this.readabilityPossible = false;
};
window.Kaktus_ReaderModeHandlerObject.prototype.applyFixups = function(doc) {
var elements, i;
//doc = doc ? doc : document
// target attributes
elements = doc.querySelectorAll("[target]");
for (i = 0; i < elements.length; i++) {
elements[i].removeAttribute("target");
}
};
window.Kaktus_ReaderModeHandlerObject.prototype.applyFiltering = function(doc, insert) {
var elements, i;
@ -25,7 +37,7 @@ window.Kaktus_ReaderModeHandlerObject.prototype.applyFiltering = function(doc, i
doc.body.innerHTML = newBody;
}
// width, height, target attributes
// width, height, target, class attributes
elements = doc.querySelectorAll("[width],[height],[target],[class]");
for (i = 0; i < elements.length; i++) {
elements[i].removeAttribute("width");
@ -38,8 +50,6 @@ window.Kaktus_ReaderModeHandlerObject.prototype.applyFiltering = function(doc, i
//elements = doc.getElementsByTagName("img");
//for (i = 0; i < elements.length; i++)
// elements[i].style.maxWidth = "100%";
};
window.Kaktus_ReaderModeHandlerObject.prototype.check = function(data) {

View file

@ -29,8 +29,6 @@ window.Kaktus_ThemeObject.prototype.updateScale = function() {
var viewport_ele = document.querySelector("meta[name='viewport']");
var content = "width=device-width/" + scale + ", initial-scale=" + scale;
// console.log("viewport content: " + content);
if (viewport_ele) {
viewport_ele.content = content;
} else {

View file

@ -93,17 +93,17 @@ bool Settings::getPowerSaveMode()
return settings.value("powersavemode", true).toBool();
}
void Settings::setShowOnlyUnread(bool value)
void Settings::setFilter(int value)
{
if (getShowOnlyUnread() != value) {
settings.setValue("showonlyunread", value);
emit showOnlyUnreadChanged();
if (getFilter() != value) {
settings.setValue("filter", value);
emit filterChanged();
}
}
bool Settings::getShowOnlyUnread()
int Settings::getFilter()
{
return settings.value("showonlyunread", true).toBool();
return settings.value("filter", 0).toInt();
}
void Settings::setShowOldestFirst(bool value)
@ -166,6 +166,19 @@ bool Settings::getOfflineMode()
#endif
}
void Settings::setAutoOffline(bool value)
{
if (getAutoOffline() != value) {
settings.setValue("autooffline", value);
emit autoOfflineChanged();
}
}
bool Settings::getAutoOffline()
{
return settings.value("autooffline", true).toBool();
}
void Settings::setReaderMode(bool value)
{
if (getReaderMode() != value) {
@ -179,6 +192,19 @@ bool Settings::getReaderMode()
return settings.value("readermode", false).toBool();
}
void Settings::setNightMode(bool value)
{
if (getNightMode() != value) {
settings.setValue("nightmode", value);
emit nightModeChanged();
}
}
bool Settings::getNightMode()
{
return settings.value("nightmode", false).toBool();
}
void Settings::setSyncRead(bool value)
{
if (getSyncRead() != value) {

View file

@ -47,11 +47,12 @@ class Settings: public QObject
Q_OBJECT
Q_PROPERTY (bool offlineMode READ getOfflineMode WRITE setOfflineMode NOTIFY offlineModeChanged)
Q_PROPERTY (bool autoOffline READ getAutoOffline WRITE setAutoOffline NOTIFY autoOfflineChanged)
Q_PROPERTY (bool readerMode READ getReaderMode WRITE setReaderMode NOTIFY readerModeChanged)
Q_PROPERTY (bool showTabIcons READ getShowTabIcons WRITE setShowTabIcons NOTIFY showTabIconsChanged)
Q_PROPERTY (bool signedIn READ getSignedIn WRITE setSignedIn NOTIFY signedInChanged)
Q_PROPERTY (bool showStarredTab READ getShowStarredTab WRITE setShowStarredTab NOTIFY showStarredTabChanged)
Q_PROPERTY (bool showOnlyUnread READ getShowOnlyUnread WRITE setShowOnlyUnread NOTIFY showOnlyUnreadChanged)
Q_PROPERTY (int filter READ getFilter WRITE setFilter NOTIFY filterChanged)
Q_PROPERTY (QString dashboardInUse READ getDashboardInUse WRITE setDashboardInUse NOTIFY dashboardInUseChanged)
Q_PROPERTY (int lastUpdateDate READ getLastUpdateDate WRITE setLastUpdateDate NOTIFY lastUpdateDateChanged)
Q_PROPERTY (int allowedOrientations READ getAllowedOrientations WRITE setAllowedOrientations NOTIFY allowedOrientationsChanged)
@ -76,6 +77,7 @@ class Settings: public QObject
Q_PROPERTY (int clickBehavior READ getClickBehavior WRITE setClickBehavior NOTIFY clickBehaviorChanged)
Q_PROPERTY (bool expandedMode READ getExpandedMode WRITE setExpandedMode NOTIFY expandedModeChanged)
Q_PROPERTY (int webviewNavigation READ getWebviewNavigation WRITE setWebviewNavigation NOTIFY webviewNavigationChanged)
Q_PROPERTY (bool nightMode READ getNightMode WRITE setNightMode NOTIFY nightModeChanged)
public:
static Settings* instance();
@ -99,9 +101,15 @@ public:
void setOfflineMode(bool value);
bool getOfflineMode();
void setAutoOffline(bool value);
bool getAutoOffline();
void setReaderMode(bool value);
bool getReaderMode();
void setNightMode(bool value);
bool getNightMode();
void setPowerSaveMode(bool value);
bool getPowerSaveMode();
@ -220,8 +228,8 @@ public:
Q_INVOKABLE void setRetentionDays(int value);
Q_INVOKABLE int getRetentionDays();
bool getShowOnlyUnread();
void setShowOnlyUnread(bool value);
int getFilter();
void setFilter(int value);
bool getShowOldestFirst();
void setShowOldestFirst(bool value);
@ -248,11 +256,13 @@ public:
signals:
void offlineModeChanged();
void autoOfflineChanged();
void readerModeChanged();
void nightModeChanged();
void showTabIconsChanged();
void signedInChanged();
void showStarredTabChanged();
void showOnlyUnreadChanged();
void filterChanged();
void dashboardInUseChanged();
void lastUpdateDateChanged();
void allowedOrientationsChanged();