1
0
mirror of https://github.com/chylex/TweetDuck.git synced 2025-04-30 14:34:09 +02:00

Refactor update checker as a bootstrapped module

This commit is contained in:
chylex 2021-12-22 07:52:54 +01:00
parent db251bfdfd
commit 86136d7692
Signed by: chylex
GPG Key ID: 4DE42C8F19A80548
6 changed files with 178 additions and 159 deletions

View File

@ -165,7 +165,7 @@ private void browser_FrameLoadEnd(object sender, FrameLoadEndEventArgs e) {
CefScriptExecutor.RunBootstrap(frame, "login", "login.css");
}
CefScriptExecutor.RunFile(frame, "update.js");
CefScriptExecutor.RunBootstrap(frame, "update", "update.css");
}
if (url == ErrorUrl) {

View File

@ -53,6 +53,7 @@ import setup_video_player from "./features/setup_video_player.js";
import skip_pre_login_page from "./features/skip_pre_login_page.js";
import show_introduction from "./introduction/show_introduction.js";
import hide_cookie_bar from "./login/hide_cookie_bar.js";
import check_updates from "./update/check_updates.js";
const globalFunctions = [
window.TDGF_applyROT13,
@ -71,5 +72,6 @@ const globalFunctions = [
window.TDGF_setSoundNotificationData,
window.TDGF_showTweetDetail,
window.TDGF_triggerScreenshot,
window.TDUF_displayNotification,
window.jQuery,
];

View File

@ -0,0 +1,173 @@
import { crashDebug } from "../api/utils.js";
/**
* @typedef $TDU
* @type {Object}
*
* @property {function} onUpdateAccepted
* @property {function} onUpdateDismissed
* @property {function} triggerUpdateCheck
*/
/**
* Creates the update notification element. Removes the old one if already exists.
* @param version
* @param changelog
* @return {HTMLDivElement}
*/
function displayNotification(version, changelog) {
// changelog
let log = document.getElementById("tweetduck-changelog");
if (!log) {
log = document.createElement("div");
log.id = "tweetduck-changelog";
log.style.display = "none";
log.innerHTML = `
<div id='tweetduck-changelog-box'>
<h2>TweetDuck Update ${version}</h2>
${markdown(atob(changelog))}
</div>`;
document.body.appendChild(log);
}
// notification
let ele = document.getElementById("tweetduck-update");
const existed = !!ele;
if (existed) {
ele.remove();
}
ele = document.createElement("div");
ele.id = "tweetduck-update";
ele.innerHTML = `
<p class='tdu-title'>T&#8202;weetDuck Update ${version}</p>
<p class='tdu-info tdu-showlog'>View update information</p>
<div class='tdu-buttons'>
<button class='tdu-btn-download'>Update now</button>
<button class='tdu-btn-later'>Remind me later</button>
<button class='tdu-btn-ignore'>Ignore this update</button>
</div>`;
if (!existed) {
ele.classList.add("hidden-below");
}
document.body.appendChild(ele);
// ui functions
const exitNow = function() {
ele.remove();
log.remove();
css.remove();
};
const exitSlide = function() {
log.style.display = "none";
ele.classList.add("hidden-below");
setTimeout(exitNow, 400);
};
const onClick = function(element, callback) {
element.addEventListener("click", callback);
};
// ui listeners
onClick(ele.querySelector(".tdu-showlog"), function() {
log.style.display = window.getComputedStyle(log).display === "none" ? "block" : "none";
});
onClick(log, function() {
log.style.display = "none";
});
onClick(log.children[0], function(e) {
e.stopPropagation();
});
onClick(ele.querySelector(".tdu-btn-download"), function() {
exitNow();
$TDU.onUpdateAccepted();
});
onClick(ele.querySelector(".tdu-btn-later"), function() {
exitSlide();
});
onClick(ele.querySelector(".tdu-btn-ignore"), function() {
$TDU.onUpdateDismissed();
exitSlide();
});
// finalize notification
if (!existed) {
ele.getBoundingClientRect(); // reflow
ele.classList.remove("hidden-below");
}
return ele;
}
/**
* Ghetto-converts markdown to HTML.
* @param {string} md
* @return {string}
*/
function markdown(md) {
return md.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/^##? (.*?)$/gm, "<h2>$1</h2>")
.replace(/^### (.*?)$/gm, "<h3>$1</h3>")
.replace(/^- (.*?)$/gm, "<p class='li'>$1</p>")
.replace(/^ - (.*?)$/gm, "<p class='li l2'>$1</p>")
.replace(/\*\*(.*?)\*\*/g, "<strong>$1</strong>")
.replace(/\*(.*?)\*/g, "<em>$1</em>")
.replace(/`(.*?)`/g, "<code>$1</code>")
.replace(/\[(.*?)\]\((.*?)\)/g, "<a href='$2' target='_blank'>$1</a>")
.replace(/^([a-z0-9].*?)$/gmi, "<p>$1</p>")
.replace(/\n\r?\n\r?/g, "<br>");
}
/**
* Returns true if the website has a jQuery "TD.ready" event.
*/
function hasReadyEvent() {
if (!("$" in window)) {
return false;
}
try {
// noinspection JSUnresolvedFunction
return window.$._data(document, "events")["TD"].some(obj => obj.namespace === "ready");
} catch(err) {
console.warn(err);
return false;
}
}
/**
* Registers functions and performs an update check.
*/
export default function() {
if (!("$TDU" in window)) {
crashDebug("Missing $TDU");
return;
}
const triggerCheck = function() {
$TDU.triggerUpdateCheck();
};
if (hasReadyEvent()) {
$(document).one("TD.ready", triggerCheck);
}
else {
setTimeout(triggerCheck, 500);
}
window.TDUF_displayNotification = displayNotification;
};

View File

@ -1,156 +0,0 @@
(function(){
if (!("$TDU" in window)){
console.error("Missing $TDU");
return;
}
//
// Function: Creates the update notification element. Removes the old one if already exists.
//
const displayNotification = function(version, changelog){
// styles
let css = document.getElementById("tweetduck-update-css");
if (!css){
css = document.createElement("style");
css.id = "tweetduck-update-css";
css.innerText = `#import "styles/update.css"`;
document.head.appendChild(css);
}
// changelog
let log = document.getElementById("tweetduck-changelog");
if (!log){
log = document.createElement("div");
log.id = "tweetduck-changelog";
log.style.display = "none";
log.innerHTML = `
<div id='tweetduck-changelog-box'>
<h2>TweetDuck Update ${version}</h2>
${markdown(atob(changelog))}
</div>`;
document.body.appendChild(log);
}
// notification
let ele = document.getElementById("tweetduck-update");
const existed = !!ele;
if (existed){
ele.remove();
}
ele = document.createElement("div");
ele.id = "tweetduck-update";
ele.innerHTML = `
<p class='tdu-title'>T&#8202;weetDuck Update ${version}</p>
<p class='tdu-info tdu-showlog'>View update information</p>
<div class='tdu-buttons'>
<button class='tdu-btn-download'>Update now</button>
<button class='tdu-btn-later'>Remind me later</button>
<button class='tdu-btn-ignore'>Ignore this update</button>
</div>`;
if (!existed){
ele.classList.add("hidden-below");
}
document.body.appendChild(ele);
// ui functions
const exitNow = function(){
ele.remove();
log.remove();
css.remove();
};
const exitSlide = function(){
log.style.display = "none";
ele.classList.add("hidden-below");
setTimeout(exitNow, 400);
};
const onClick = function(element, callback){
element.addEventListener("click", callback);
};
// ui listeners
onClick(ele.querySelector(".tdu-showlog"), function(){
log.style.display = window.getComputedStyle(log).display === "none" ? "block" : "none";
});
onClick(log, function(){
log.style.display = "none";
});
onClick(log.children[0], function(e){
e.stopPropagation();
});
onClick(ele.querySelector(".tdu-btn-download"), function(){
exitNow();
$TDU.onUpdateAccepted();
});
onClick(ele.querySelector(".tdu-btn-later"), function(){
exitSlide();
});
onClick(ele.querySelector(".tdu-btn-ignore"), function(){
$TDU.onUpdateDismissed();
exitSlide();
});
// finalize notification
if (!existed){
ele.getBoundingClientRect(); // reflow
ele.classList.remove("hidden-below");
}
return ele;
};
//
// Function: Ghetto-converts markdown to HTML.
//
const markdown = function(md){
return md.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/^##? (.*?)$/gm, "<h2>$1</h2>")
.replace(/^### (.*?)$/gm, "<h3>$1</h3>")
.replace(/^- (.*?)$/gm, "<p class='li'>$1</p>")
.replace(/^ - (.*?)$/gm, "<p class='li l2'>$1</p>")
.replace(/\*\*(.*?)\*\*/g, "<strong>$1</strong>")
.replace(/\*(.*?)\*/g, "<em>$1</em>")
.replace(/`(.*?)`/g, "<code>$1</code>")
.replace(/\[(.*?)\]\((.*?)\)/g, "<a href='$2' target='_blank'>$1</a>")
.replace(/^([a-z0-9].*?)$/gmi, "<p>$1</p>")
.replace(/\n\r?\n\r?/g, "<br>");
};
//
// Block: Check updates on startup.
//
const triggerCheck = function(){
$TDU.triggerUpdateCheck();
};
try{
throw "Missing jQuery or TD.ready event" if !($._data(document, "events").TD.some(obj => obj.namespace === "ready"));
$(document).one("TD.ready", triggerCheck);
}catch(err){
console.warn(err);
setTimeout(triggerCheck, 500);
}
//
// Block: Setup global functions.
//
window.TDUF_displayNotification = displayNotification;
})();

View File

@ -325,6 +325,7 @@
<None Include="Resources\Content\styles\introduction.css" />
<None Include="Resources\Content\styles\tweetdeck.css" />
<None Include="Resources\Content\styles\login.css" />
<None Include="Resources\Content\styles\update.css" />
<None Include="Resources\Images\avatar.png" />
<None Include="Resources\Images\icon-muted.ico" />
<None Include="Resources\Images\icon-small.ico" />
@ -357,7 +358,6 @@
<None Include="Resources\PostBuild.fsx" />
<None Include="Resources\PostCefUpdate.ps1" />
<None Include="Resources\Scripts\imports\scripts\plugins.base.js" />
<None Include="Resources\Scripts\imports\styles\update.css" />
<None Include="Resources\Scripts\notification.js" />
<None Include="Resources\Scripts\pages\error.html" />
<None Include="Resources\Scripts\pages\example.html" />
@ -365,7 +365,6 @@
<None Include="Resources\Scripts\plugins.notification.js" />
<None Include="Resources\Scripts\screenshot.js" />
<None Include="Resources\Scripts\styles\notification.css" />
<None Include="Resources\Scripts\update.js" />
</ItemGroup>
<ItemGroup>
<Redist Include="$(ProjectDir)bld\Redist\*.*" />
@ -457,6 +456,7 @@
<Content Include="Resources\Content\globals\show_tweet_detail.js" />
<Content Include="Resources\Content\login\hide_cookie_bar.js" />
<Content Include="Resources\Content\login\setup_document_attributes.js" />
<Content Include="Resources\Content\update\check_updates.js" />
<Content Include="Resources\Scripts\bootstrap.js" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />