mirror of
https://github.com/chylex/TweetDuck.git
synced 2025-05-09 05:34:05 +02:00
Refactor notification bootstrapping
This commit is contained in:
parent
ceae748503
commit
6a421292b3
Browser
Adapters
Notification
Resources
TweetDuck.csprojlib/TweetLib.Core/Features/Notifications
@ -46,9 +46,18 @@ public static bool RunFile(IFrame frame, string file) {
|
||||
}
|
||||
|
||||
public static void RunBootstrap(IFrame frame, string moduleNamespace) {
|
||||
string script = GetBootstrapScript(moduleNamespace, includeStylesheets: true);
|
||||
|
||||
if (script != null) {
|
||||
RunScript(frame, script, "bootstrap");
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetBootstrapScript(string moduleNamespace, bool includeStylesheets) {
|
||||
string script = Program.Resources.Load("bootstrap.js");
|
||||
|
||||
if (script == null) {
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
|
||||
string path = Path.Combine(Program.ResourcesPath, moduleNamespace);
|
||||
@ -62,7 +71,7 @@ public static void RunBootstrap(IFrame frame, string moduleNamespace) {
|
||||
|
||||
var targetList = ext switch {
|
||||
".js" => moduleNames,
|
||||
".css" => stylesheetNames,
|
||||
".css" => includeStylesheets ? stylesheetNames : null,
|
||||
_ => null
|
||||
};
|
||||
|
||||
@ -73,7 +82,7 @@ public static void RunBootstrap(IFrame frame, string moduleNamespace) {
|
||||
script = script.Replace("{{modules}}", string.Join("|", moduleNames));
|
||||
script = script.Replace("{{stylesheets}}", string.Join("|", stylesheetNames));
|
||||
|
||||
RunScript(frame, script, "bootstrap");
|
||||
return script;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ protected override FormBorderStyle NotificationBorderStyle {
|
||||
public FormNotificationExample(FormBrowser owner, PluginManager pluginManager) : base(owner, pluginManager, false) {
|
||||
browser.LoadingStateChanged += browser_LoadingStateChanged;
|
||||
|
||||
string exampleTweetHTML = Program.Resources.LoadSilent("pages/example.html")?.Replace("{avatar}", AppLogo.Url) ?? string.Empty;
|
||||
string exampleTweetHTML = Program.Resources.LoadSilent("notification/example/example.html")?.Replace("{avatar}", AppLogo.Url) ?? string.Empty;
|
||||
|
||||
#if DEBUG
|
||||
exampleTweetHTML = exampleTweetHTML.Replace("</p>", @"</p><div style='margin-top:256px'>Scrollbar test padding...</div>");
|
||||
|
@ -2,6 +2,7 @@
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
using CefSharp;
|
||||
using TweetDuck.Browser.Adapters;
|
||||
using TweetDuck.Browser.Bridge;
|
||||
using TweetDuck.Browser.Handling;
|
||||
using TweetDuck.Controls;
|
||||
@ -238,7 +239,7 @@ public override void ResumeNotification() {
|
||||
protected override string GetTweetHTML(DesktopNotification tweet) {
|
||||
return tweet.GenerateHtml(BodyClasses, HeadLayout, Config.CustomNotificationCSS, plugins.NotificationInjections, new string[] {
|
||||
PropertyBridge.GenerateScript(PropertyBridge.Environment.Notification),
|
||||
Program.Resources.Load("notification.js")
|
||||
CefScriptExecutor.GetBootstrapScript("notification", includeStylesheets: false)
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,7 @@ public FormNotificationScreenshotable(Action callback, FormBrowser owner, Plugin
|
||||
return;
|
||||
}
|
||||
|
||||
string script = Program.Resources.LoadSilent("screenshot.js");
|
||||
string script = Program.Resources.LoadSilent("notification/screenshot/screenshot.js");
|
||||
|
||||
if (script == null) {
|
||||
this.InvokeAsyncSafe(callback);
|
||||
@ -37,7 +37,7 @@ public FormNotificationScreenshotable(Action callback, FormBrowser owner, Plugin
|
||||
}
|
||||
|
||||
using IFrame frame = args.Browser.MainFrame;
|
||||
CefScriptExecutor.RunScript(frame, script.Replace("{width}", realWidth.ToString()).Replace("{frames}", TweetScreenshotManager.WaitFrames.ToString()), "gen:screenshot");
|
||||
CefScriptExecutor.RunScript(frame, script.Replace("{width}", realWidth.ToString()).Replace("1/*FRAMES*/", TweetScreenshotManager.WaitFrames.ToString()), "gen:screenshot");
|
||||
};
|
||||
|
||||
SetNotificationSize(realWidth, 1024);
|
||||
|
@ -7,6 +7,14 @@
|
||||
import introduction from "./introduction/introduction.js";
|
||||
import hide_cookie_bar from "./login/hide_cookie_bar.js";
|
||||
import setup_document_attributes from "./login/setup_document_attributes.js";
|
||||
import add_skip_button from "./notification/add_skip_button.js";
|
||||
import disable_clipboard_formatting_notification from "./notification/disable_clipboard_formatting.js";
|
||||
import expand_links_or_show_tooltip_notification from "./notification/expand_links_or_show_tooltip.js";
|
||||
import handle_links from "./notification/handle_links.js";
|
||||
import handle_show_this_thread_link from "./notification/handle_show_this_thread_link.js";
|
||||
import reset_scroll_position_on_load from "./notification/reset_scroll_position_on_load.js";
|
||||
import scroll_smoothly from "./notification/scroll_smoothly.js";
|
||||
import setup_body_hover_class from "./notification/setup_body_hover_class.js";
|
||||
import add_tweetduck_to_settings_menu from "./tweetdeck/add_tweetduck_to_settings_menu.js";
|
||||
import bypass_tco_links from "./tweetdeck/bypass_t.co_links.js";
|
||||
import clear_search_input from "./tweetdeck/clear_search_input.js";
|
||||
@ -72,6 +80,7 @@ const globalFunctions = [
|
||||
window.TDGF_reinjectCustomCSS,
|
||||
window.TDGF_reload,
|
||||
window.TDGF_reloadColumns,
|
||||
window.TDGF_scrollSmoothly,
|
||||
window.TDGF_setSoundNotificationData,
|
||||
window.TDGF_showTweetDetail,
|
||||
window.TDGF_triggerScreenshot,
|
||||
|
@ -14,6 +14,7 @@ if (!("$TDX" in window)) {
|
||||
* @property {function(message: string)} crashDebug
|
||||
* @property {function(tooltip: string|null)} displayTooltip
|
||||
* @property {function} fixClipboard
|
||||
* @property {function} loadNextNotification
|
||||
* @property {function(fontSize: string, headLayout: string)} loadNotificationLayout
|
||||
* @property {function(namespace: string)} onModulesLoaded
|
||||
* @property {function(columnId: string, chirpId: string, columnName: string, tweetHtml: string, tweetCharacters: int, tweetUrl: string, quoteUrl: string)} onTweetPopup
|
||||
@ -24,6 +25,7 @@ if (!("$TDX" in window)) {
|
||||
* @property {function(videoUrl: string, tweetUrl: string, username: string, callback: function)} playVideo
|
||||
* @property {function(tweetUrl: string, quoteUrl: string, chirpAuthors: string, chirpImages: string)} setRightClickedChirp
|
||||
* @property {function(type: string, url: string)} setRightClickedLink
|
||||
* @property {function} showTweetDetail
|
||||
* @property {function(html: string, width: number)} screenshotTweet
|
||||
* @property {function} stopVideo
|
||||
*/
|
||||
@ -39,6 +41,7 @@ if (!("$TDX" in window)) {
|
||||
* @property {boolean} [muteNotifications]
|
||||
* @property {boolean} [notificationMediaPreviews]
|
||||
* @property {boolean} [openSearchInFirstColumn]
|
||||
* @property {boolean} [skipOnLinkClick]
|
||||
* @property {string} [translationTarget]
|
||||
*/
|
||||
|
||||
|
17
Resources/Content/notification/add_skip_button.js
Normal file
17
Resources/Content/notification/add_skip_button.js
Normal file
@ -0,0 +1,17 @@
|
||||
import { $TD } from "../api/bridge.js";
|
||||
|
||||
const iconHTML = `
|
||||
<svg id="td-skip" width="10" height="17" viewBox="0 0 350 600">
|
||||
<path fill="#888" d="M0,151.656l102.208-102.22l247.777,247.775L102.208,544.986L0,442.758l145.546-145.547">
|
||||
</svg>`;
|
||||
|
||||
/**
|
||||
* Adds an icon button that skips to the next notification.
|
||||
*/
|
||||
export default function() {
|
||||
document.body.children[0].insertAdjacentHTML("beforeend", iconHTML);
|
||||
|
||||
document.getElementById("td-skip").addEventListener("click", function() {
|
||||
$TD.loadNextNotification();
|
||||
});
|
||||
};
|
@ -0,0 +1,5 @@
|
||||
import disable_clipboard_formatting from "../tweetdeck/disable_clipboard_formatting.js";
|
||||
|
||||
export default function() {
|
||||
disable_clipboard_formatting();
|
||||
};
|
@ -0,0 +1,5 @@
|
||||
import expand_links_or_show_tooltip from "../tweetdeck/expand_links_or_show_tooltip.js";
|
||||
|
||||
export default function() {
|
||||
expand_links_or_show_tooltip();
|
||||
};
|
39
Resources/Content/notification/handle_links.js
Normal file
39
Resources/Content/notification/handle_links.js
Normal file
@ -0,0 +1,39 @@
|
||||
import { $TD, $TDX } from "../api/bridge.js";
|
||||
|
||||
/**
|
||||
* Adds an event listener to all elements in a collection.
|
||||
*/
|
||||
function addEventListener(collection, type, listener) {
|
||||
for (const ele of collection) {
|
||||
ele.addEventListener(type, listener);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {MouseEvent} e
|
||||
*/
|
||||
function handleLinkClick(e) {
|
||||
if (e.button === 0 || e.button === 1) {
|
||||
const ele = e.currentTarget;
|
||||
|
||||
$TD.openBrowser(ele.href);
|
||||
e.preventDefault();
|
||||
|
||||
if ($TDX.skipOnLinkClick) {
|
||||
const parentClasses = ele.parentNode.classList;
|
||||
|
||||
if (parentClasses.contains("js-tweet-text") || parentClasses.contains("js-quoted-tweet-text") || parentClasses.contains("js-timestamp")) {
|
||||
$TD.loadNextNotification();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Bypasses default link open function, and skips notification when opening links if enabled in app configuration.
|
||||
*/
|
||||
export default function() {
|
||||
const links = document.getElementsByTagName("A");
|
||||
addEventListener(links, "click", handleLinkClick);
|
||||
addEventListener(links, "auxclick", handleLinkClick);
|
||||
};
|
@ -0,0 +1,10 @@
|
||||
import { $TD } from "../api/bridge.js";
|
||||
|
||||
/**
|
||||
* Handles clicking on the 'Show this thread' link.
|
||||
*/
|
||||
export default function() {
|
||||
document.getElementById("tduck-show-thread")?.addEventListener("click", function(){
|
||||
$TD.showTweetDetail();
|
||||
});
|
||||
};
|
@ -0,0 +1,6 @@
|
||||
/**
|
||||
* Forces the scroll position to reset every time a notification loads.
|
||||
*/
|
||||
export default function() {
|
||||
history.scrollRestoration = "manual";
|
||||
};
|
37
Resources/Content/notification/screenshot/screenshot.js
Normal file
37
Resources/Content/notification/screenshot/screenshot.js
Normal file
@ -0,0 +1,37 @@
|
||||
/**
|
||||
* @typedef TD_Screenshot_Bridge
|
||||
* @type {Object}
|
||||
*
|
||||
* @property {function} triggerScreenshot
|
||||
* @property {function(number)} setHeight
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param $TDS
|
||||
*/
|
||||
(function($TDS) {
|
||||
const ele = document.getElementsByTagName("article")[0];
|
||||
ele.style.width = "{width}px";
|
||||
|
||||
ele.style.position = "absolute";
|
||||
const contentHeight = ele.offsetHeight;
|
||||
ele.style.position = "static";
|
||||
|
||||
const avatar = ele.querySelector(".tweet-avatar");
|
||||
const avatarBottom = avatar ? avatar.getBoundingClientRect().bottom : 0;
|
||||
|
||||
$TDS.setHeight(Math.floor(Math.max(contentHeight, avatarBottom + 9))).then(() => {
|
||||
let framesLeft = 1/*FRAMES*/; // basic render is done in 1 frame, large media take longer
|
||||
|
||||
const onNextFrame = function() {
|
||||
if (--framesLeft < 0) {
|
||||
$TDS.triggerScreenshot();
|
||||
}
|
||||
else {
|
||||
requestAnimationFrame(onNextFrame);
|
||||
}
|
||||
};
|
||||
|
||||
onNextFrame();
|
||||
});
|
||||
})(/** @type TD_Screenshot_Bridge */ $TD_NotificationScreenshot);
|
35
Resources/Content/notification/scroll_smoothly.js
Normal file
35
Resources/Content/notification/scroll_smoothly.js
Normal file
@ -0,0 +1,35 @@
|
||||
/**
|
||||
* Works around broken smooth scrolling in Chromium/CEF.
|
||||
*/
|
||||
export default function() {
|
||||
let targetY = 0;
|
||||
let delay = -1;
|
||||
let scrolling = false;
|
||||
|
||||
window.TDGF_scrollSmoothly = function(delta) {
|
||||
targetY += delta;
|
||||
|
||||
if (targetY < 0) {
|
||||
targetY = 0;
|
||||
}
|
||||
else if (targetY > document.body.offsetHeight - window.innerHeight) {
|
||||
targetY = document.body.offsetHeight - window.innerHeight;
|
||||
}
|
||||
|
||||
const prevY = window.scrollY;
|
||||
window.scrollTo({ top: targetY, left: window.scrollX, behavior: "smooth" });
|
||||
scrolling = true;
|
||||
|
||||
const diff = Math.abs(targetY - prevY);
|
||||
const time = 420 * (Math.log(diff + 510) - 6);
|
||||
|
||||
clearTimeout(delay);
|
||||
delay = setTimeout(() => scrolling = false, time);
|
||||
};
|
||||
|
||||
window.addEventListener("scroll", function() {
|
||||
if (!scrolling) {
|
||||
targetY = window.scrollY;
|
||||
}
|
||||
});
|
||||
};
|
12
Resources/Content/notification/setup_body_hover_class.js
Normal file
12
Resources/Content/notification/setup_body_hover_class.js
Normal file
@ -0,0 +1,12 @@
|
||||
/**
|
||||
* Adds a class to the <body> element when hovering the notification.
|
||||
*/
|
||||
export default function() {
|
||||
document.body.addEventListener("mouseenter", function(){
|
||||
document.body.classList.add("td-hover");
|
||||
});
|
||||
|
||||
document.body.addEventListener("mouseleave", function(){
|
||||
document.body.classList.remove("td-hover");
|
||||
});
|
||||
};
|
@ -30,7 +30,7 @@ public virtual void OnReloadTriggered() {
|
||||
public string LoadSilent(string path) => LoadInternal(path, silent: true);
|
||||
|
||||
protected virtual string LocateFile(string path) {
|
||||
return Path.Combine(Program.ScriptPath, path);
|
||||
return Path.Combine(Program.ResourcesPath, path);
|
||||
}
|
||||
|
||||
private string LoadInternal(string path, bool silent) {
|
||||
@ -49,27 +49,7 @@ private string LoadInternal(string path, bool silent) {
|
||||
string resource;
|
||||
|
||||
try {
|
||||
string contents = File.ReadAllText(location, Encoding.UTF8);
|
||||
int separator;
|
||||
|
||||
// first line can be either:
|
||||
// #<version>\r\n
|
||||
// #<version>\n
|
||||
|
||||
if (contents[0] != '#') {
|
||||
ShowLoadError(silent ? null : sync, $"File {path} appears to be corrupted, please try reinstalling the app.");
|
||||
separator = 0;
|
||||
}
|
||||
else {
|
||||
separator = contents.IndexOf('\n');
|
||||
string fileVersion = contents.Substring(1, separator - 1).TrimEnd();
|
||||
|
||||
if (fileVersion != Program.VersionTag) {
|
||||
ShowLoadError(silent ? null : sync, $"File {path} is made for a different version of TweetDuck ({fileVersion}) and may not function correctly in this version, please try reinstalling the app.");
|
||||
}
|
||||
}
|
||||
|
||||
resource = contents.Substring(separator).TrimStart();
|
||||
resource = File.ReadAllText(location, Encoding.UTF8);
|
||||
} catch (Exception ex) {
|
||||
ShowLoadError(silent ? null : sync, $"Could not load {path}. The program will continue running with limited functionality.\n\n{ex.Message}");
|
||||
resource = null;
|
||||
|
@ -1,184 +0,0 @@
|
||||
(function(){
|
||||
//
|
||||
// Variable: Collection of all <a> tags.
|
||||
//
|
||||
const links = document.getElementsByTagName("A");
|
||||
|
||||
//
|
||||
// Function: Adds an event listener to all elements in the array or collection.
|
||||
//
|
||||
const addEventListener = function(collection, type, listener){
|
||||
for(let ele of collection){
|
||||
ele.addEventListener(type, listener);
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// Block: Hook into links to bypass default open function, and handle skipping notification when opening links.
|
||||
//
|
||||
(function(){
|
||||
const onLinkClick = function(e){
|
||||
if (e.button === 0 || e.button === 1){
|
||||
const ele = e.currentTarget;
|
||||
|
||||
$TD.openBrowser(ele.href);
|
||||
e.preventDefault();
|
||||
|
||||
if ($TDX.skipOnLinkClick){
|
||||
const parentClasses = ele.parentNode.classList;
|
||||
|
||||
if (parentClasses.contains("js-tweet-text") || parentClasses.contains("js-quoted-tweet-text") || parentClasses.contains("js-timestamp")){
|
||||
$TD.loadNextNotification();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
addEventListener(links, "click", onLinkClick);
|
||||
addEventListener(links, "auxclick", onLinkClick);
|
||||
})();
|
||||
|
||||
//
|
||||
// Block: Expand shortened links on hover or display tooltip.
|
||||
//
|
||||
(function(){
|
||||
let prevMouseX = -1, prevMouseY = -1;
|
||||
let tooltipTimer, tooltipDisplayed;
|
||||
|
||||
addEventListener(links, "mouseenter", function(e){
|
||||
const me = e.currentTarget;
|
||||
|
||||
const url = me.getAttribute("data-full-url");
|
||||
return if !url;
|
||||
|
||||
const text = me.textContent;
|
||||
return if text.charCodeAt(text.length-1) !== 8230 && text.charCodeAt(0) !== 8230; // horizontal ellipsis
|
||||
|
||||
if ($TDX.expandLinksOnHover){
|
||||
tooltipTimer = window.setTimeout(function(){
|
||||
me.setAttribute("td-prev-text", text);
|
||||
me.innerHTML = url.replace(/^https?:\/\/(www\.)?/, "");
|
||||
}, 200);
|
||||
}
|
||||
else{
|
||||
tooltipTimer = window.setTimeout(function(){
|
||||
$TD.displayTooltip(url);
|
||||
tooltipDisplayed = true;
|
||||
}, 400);
|
||||
}
|
||||
});
|
||||
|
||||
addEventListener(links, "mouseleave", function(e){
|
||||
return if !e.currentTarget.hasAttribute("data-full-url");
|
||||
|
||||
if ($TDX.expandLinksOnHover){
|
||||
const prevText = e.currentTarget.getAttribute("td-prev-text");
|
||||
|
||||
if (prevText){
|
||||
e.currentTarget.innerHTML = prevText;
|
||||
}
|
||||
}
|
||||
|
||||
window.clearTimeout(tooltipTimer);
|
||||
|
||||
if (tooltipDisplayed){
|
||||
tooltipDisplayed = false;
|
||||
$TD.displayTooltip(null);
|
||||
}
|
||||
});
|
||||
|
||||
addEventListener(links, "mousemove", function(e){
|
||||
if (tooltipDisplayed && (prevMouseX !== e.clientX || prevMouseY !== e.clientY)){
|
||||
const url = e.currentTarget.getAttribute("data-full-url");
|
||||
return if !url;
|
||||
|
||||
$TD.displayTooltip(url);
|
||||
prevMouseX = e.clientX;
|
||||
prevMouseY = e.clientY;
|
||||
}
|
||||
});
|
||||
})();
|
||||
|
||||
//
|
||||
// Block: Work around broken smooth scrolling.
|
||||
//
|
||||
(function(){;
|
||||
let targetY = 0;
|
||||
let delay = -1;
|
||||
let scrolling = false;
|
||||
|
||||
window.TDGF_scrollSmoothly = function(delta){
|
||||
targetY += delta;
|
||||
|
||||
if (targetY < 0){
|
||||
targetY = 0;
|
||||
}
|
||||
else if (targetY > document.body.offsetHeight - window.innerHeight){
|
||||
targetY = document.body.offsetHeight - window.innerHeight;
|
||||
}
|
||||
|
||||
const prevY = window.scrollY;
|
||||
window.scrollTo({ top: targetY, left: window.scrollX, behavior: "smooth" });
|
||||
scrolling = true;
|
||||
|
||||
const diff = Math.abs(targetY - prevY);
|
||||
const time = 420 * (Math.log(diff + 510) - 6);
|
||||
|
||||
clearTimeout(delay);
|
||||
delay = setTimeout(function(){ scrolling = false; }, time);
|
||||
};
|
||||
|
||||
window.addEventListener("scroll", function(){
|
||||
if (!scrolling){
|
||||
targetY = window.scrollY;
|
||||
}
|
||||
});
|
||||
})();
|
||||
|
||||
//
|
||||
// Block: Work around clipboard HTML formatting.
|
||||
//
|
||||
document.addEventListener("copy", function(){
|
||||
window.setTimeout($TD.fixClipboard, 0);
|
||||
});
|
||||
|
||||
//
|
||||
// Block: Setup a handler for 'Show this thread'.
|
||||
//
|
||||
(function(){
|
||||
const btn = document.getElementById("tduck-show-thread");
|
||||
return if !btn;
|
||||
|
||||
btn.addEventListener("click", function(){
|
||||
$TD.showTweetDetail();
|
||||
});
|
||||
})();
|
||||
|
||||
//
|
||||
// Block: Setup a skip button.
|
||||
//
|
||||
document.body.children[0].insertAdjacentHTML("beforeend", `
|
||||
<svg id="td-skip" width="10" height="17" viewBox="0 0 350 600">
|
||||
<path fill="#888" d="M0,151.656l102.208-102.22l247.777,247.775L102.208,544.986L0,442.758l145.546-145.547">
|
||||
</svg>`);
|
||||
|
||||
document.getElementById("td-skip").addEventListener("click", function(){
|
||||
$TD.loadNextNotification();
|
||||
});
|
||||
|
||||
//
|
||||
// Block: Setup a hover class on body.
|
||||
//
|
||||
document.body.addEventListener("mouseenter", function(){
|
||||
document.body.classList.add("td-hover");
|
||||
});
|
||||
|
||||
document.body.addEventListener("mouseleave", function(){
|
||||
document.body.classList.remove("td-hover");
|
||||
});
|
||||
|
||||
//
|
||||
// Block: Force a reset of scroll position on every load.
|
||||
//
|
||||
history.scrollRestoration = "manual";
|
||||
})();
|
@ -1,26 +0,0 @@
|
||||
(function($TD){
|
||||
const ele = document.getElementsByTagName("article")[0];
|
||||
ele.style.width = "{width}px";
|
||||
|
||||
ele.style.position = "absolute";
|
||||
const contentHeight = ele.offsetHeight;
|
||||
ele.style.position = "static";
|
||||
|
||||
const avatar = ele.querySelector(".tweet-avatar");
|
||||
const avatarBottom = avatar ? avatar.getBoundingClientRect().bottom : 0;
|
||||
|
||||
$TD.setHeight(Math.floor(Math.max(contentHeight, avatarBottom + 9))).then(() => {
|
||||
let framesLeft = {frames}; // basic render is done in 1 frame, large media take longer
|
||||
|
||||
let onNextFrame = function(){
|
||||
if (--framesLeft < 0){
|
||||
$TD.triggerScreenshot();
|
||||
}
|
||||
else{
|
||||
requestAnimationFrame(onNextFrame);
|
||||
}
|
||||
};
|
||||
|
||||
onNextFrame();
|
||||
});
|
||||
})($TD_NotificationScreenshot);
|
@ -323,6 +323,9 @@
|
||||
<None Include="app.config" />
|
||||
<None Include="packages.config" />
|
||||
<None Include="Resources\Content\error\error.html" />
|
||||
<None Include="Resources\Content\notification\example\example.html" />
|
||||
<None Include="Resources\Content\notification\notification.css" />
|
||||
<None Include="Resources\Content\notification\screenshot\screenshot.js" />
|
||||
<None Include="Resources\Content\plugins\notification\plugins.js" />
|
||||
<None Include="Resources\Content\plugins\tweetdeck\plugins.js" />
|
||||
<None Include="Resources\Images\avatar.png" />
|
||||
@ -356,10 +359,6 @@
|
||||
<None Include="Resources\Plugins\timeline-polls\browser.js" />
|
||||
<None Include="Resources\PostBuild.fsx" />
|
||||
<None Include="Resources\PostCefUpdate.ps1" />
|
||||
<None Include="Resources\Scripts\notification.js" />
|
||||
<None Include="Resources\Scripts\pages\example.html" />
|
||||
<None Include="Resources\Scripts\screenshot.js" />
|
||||
<None Include="Resources\Scripts\styles\notification.css" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Redist Include="$(ProjectDir)bld\Redist\*.*" />
|
||||
@ -389,12 +388,21 @@
|
||||
<Content Include="Resources\Content\api\ready.js" />
|
||||
<Content Include="Resources\Content\api\td.js" />
|
||||
<Content Include="Resources\Content\api\utils.js" />
|
||||
<Content Include="Resources\Content\bootstrap.js" />
|
||||
<Content Include="Resources\Content\introduction\introduction.css" />
|
||||
<Content Include="Resources\Content\introduction\introduction.js" />
|
||||
<Content Include="Resources\Content\load.js" />
|
||||
<Content Include="Resources\Content\login\hide_cookie_bar.js" />
|
||||
<Content Include="Resources\Content\login\login.css" />
|
||||
<Content Include="Resources\Content\login\setup_document_attributes.js" />
|
||||
<Content Include="Resources\Content\notification\add_skip_button.js" />
|
||||
<Content Include="Resources\Content\notification\disable_clipboard_formatting.js" />
|
||||
<Content Include="Resources\Content\notification\expand_links_or_show_tooltip.js" />
|
||||
<Content Include="Resources\Content\notification\handle_links.js" />
|
||||
<Content Include="Resources\Content\notification\handle_show_this_thread_link.js" />
|
||||
<Content Include="Resources\Content\notification\reset_scroll_position_on_load.js" />
|
||||
<Content Include="Resources\Content\notification\scroll_smoothly.js" />
|
||||
<Content Include="Resources\Content\notification\setup_body_hover_class.js" />
|
||||
<Content Include="Resources\Content\plugins\base.js" />
|
||||
<Content Include="Resources\Content\plugins\setup.js" />
|
||||
<Content Include="Resources\Content\tweetdeck\add_tweetduck_to_settings_menu.js" />
|
||||
@ -459,7 +467,9 @@
|
||||
<Content Include="Resources\Content\tweetdeck\tweetdeck.css" />
|
||||
<Content Include="Resources\Content\update\update.js" />
|
||||
<Content Include="Resources\Content\update\update.css" />
|
||||
<Content Include="Resources\Scripts\bootstrap.js" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Resources\Scripts" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<PropertyGroup>
|
||||
|
@ -50,15 +50,13 @@ public string GenerateHtml(string bodyClasses, string? headLayout, string? custo
|
||||
headLayout ??= DefaultHeadLayout;
|
||||
customStyles ??= string.Empty;
|
||||
|
||||
string mainCSS = App.ResourceHandler.Load("styles/notification.css") ?? string.Empty;
|
||||
|
||||
StringBuilder build = new StringBuilder(1000);
|
||||
build.Append("<!DOCTYPE html>");
|
||||
build.Append(headLayout);
|
||||
build.Append("<style type='text/css'>").Append(mainCSS).Append("</style>");
|
||||
build.Append("<link rel='stylesheet' href='td://resources/notification/notification.css'>");
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(customStyles)) {
|
||||
build.Append("<style type='text/css'>").Append(customStyles).Append("</style>");
|
||||
build.Append("<style>").Append(customStyles).Append("</style>");
|
||||
}
|
||||
|
||||
build.Append("</head><body class='scroll-styled-v");
|
||||
|
Loading…
Reference in New Issue
Block a user