Display mutators for popular image posting sites
This commit is contained in:
parent
0107dd60a1
commit
cb81610515
|
@ -1,9 +1,10 @@
|
|||
<template>
|
||||
<div class="image-preview-wrapper" v-if="isVisible()">
|
||||
<webview class="image-preview-external" :src="isExternalUrl() ? url : null" :style="{display: isExternalUrl() ? 'flex' : 'none'}"></webview>
|
||||
<!-- hiding elements instead of using 'v-if' is used here as an optimization -->
|
||||
<div class="image-preview-wrapper" :style="{display: visible ? 'block' : 'none'}">
|
||||
<webview webpreferences="allowRunningInsecureContent" id="image-preview-ext" ref="imagePreviewExt" class="image-preview-external" :src="externalUrl" :style="{display: externalUrlVisible ? 'flex' : 'none'}"></webview>
|
||||
<div
|
||||
class="image-preview-local"
|
||||
:style="{backgroundImage: `url(${url})`, display: isInternalUrl() ? 'block' : 'none'}"
|
||||
:style="{backgroundImage: `url(${internalUrl})`, display: internalUrlVisible ? 'block' : 'none'}"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -13,23 +14,33 @@
|
|||
import {Component, Hook} from '@f-list/vue-ts';
|
||||
import Vue from 'vue';
|
||||
import {EventBus} from './event-bus';
|
||||
import {domain } from '../bbcode/core';
|
||||
import {domain} from '../bbcode/core';
|
||||
import {ImagePreviewMutator} from './image-preview-mutator';
|
||||
|
||||
@Component
|
||||
export default class ImagePreview extends Vue {
|
||||
public visible: boolean = false;
|
||||
|
||||
public externalUrlVisible: boolean = false;
|
||||
public internalUrlVisible: boolean = false;
|
||||
|
||||
public externalUrl: string|null = null;
|
||||
public internalUrl: string|null = null;
|
||||
|
||||
public url: string|null = null;
|
||||
public domain: string|undefined;
|
||||
|
||||
private jsMutator = new ImagePreviewMutator();
|
||||
private interval: any = null;
|
||||
|
||||
private exitInterval: any = null;
|
||||
private exitUrl: string|null = null;
|
||||
|
||||
@Hook('mounted')
|
||||
onMounted() {
|
||||
EventBus.$on(
|
||||
'imagepreview-dismiss',
|
||||
(eventData: any) => {
|
||||
console.log('DIMSMISS');
|
||||
this.dismiss(eventData.url);
|
||||
}
|
||||
);
|
||||
|
@ -37,10 +48,39 @@
|
|||
EventBus.$on(
|
||||
'imagepreview-show',
|
||||
(eventData: any) => {
|
||||
console.log('SHOW');
|
||||
this.show(eventData.url);
|
||||
}
|
||||
);
|
||||
|
||||
const webview = this.$refs.imagePreviewExt as any;
|
||||
|
||||
webview.addEventListener(
|
||||
'dom-ready',
|
||||
() => {
|
||||
const url = webview.getURL();
|
||||
|
||||
const js = this.jsMutator.getMutatorJsForSite(url);
|
||||
|
||||
if (js) {
|
||||
webview.executeJavaScript(js);
|
||||
}
|
||||
|
||||
// webview.openDevTools();
|
||||
|
||||
/* webview.executeJavaScript(
|
||||
"(() => {"
|
||||
+ "$('#topbar').hide();"
|
||||
+ "$('.post-header').hide();"
|
||||
+ "$('#inside').css({padding: 0, margin: 0, width: '100%'});"
|
||||
+ "$('#right-content').hide();"
|
||||
+ "$('.post-container').css({width: '100%'});"
|
||||
+ "$('.post-image img').css({width: '100%', 'min-height': 'unset'});"
|
||||
+ "$('#recommendations').hide();"
|
||||
+ "$('.left').css({float: 'none'});"
|
||||
+ "})()"
|
||||
);*/
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
@ -50,24 +90,63 @@
|
|||
return;
|
||||
}
|
||||
|
||||
this.url = null;
|
||||
this.visible = false;
|
||||
let due = this.visible ? 1000 : 0;
|
||||
|
||||
this.cancelTimer();
|
||||
|
||||
if (this.exitInterval) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.exitUrl = this.url;
|
||||
|
||||
this.exitInterval = setTimeout(
|
||||
() => {
|
||||
this.url = null;
|
||||
this.visible = false;
|
||||
|
||||
this.internalUrlVisible = false;
|
||||
this.externalUrlVisible = false;
|
||||
|
||||
this.externalUrl = 'about:blank';
|
||||
this.internalUrl = 'about:blank';
|
||||
|
||||
this.exitUrl = null;
|
||||
this.exitInterval = null;
|
||||
},
|
||||
due
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
show(url: string) {
|
||||
// url = 'https://imgur.com/a/2uzWx';
|
||||
// url = 'http://lodash.com';
|
||||
// url = 'https://rule34.xxx/index.php?page=post&s=view&id=3254983';
|
||||
|
||||
let due = ((url === this.exitUrl) && (this.exitInterval)) ? 0 : 100;
|
||||
|
||||
this.url = url;
|
||||
this.domain = domain(url);
|
||||
|
||||
this.cancelExitTimer();
|
||||
this.cancelTimer();
|
||||
|
||||
this.interval = setTimeout(
|
||||
() => {
|
||||
const isInternal = this.isInternalUrl();
|
||||
|
||||
this.internalUrlVisible = isInternal;
|
||||
this.externalUrlVisible = !isInternal;
|
||||
|
||||
if (isInternal)
|
||||
this.internalUrl = this.url;
|
||||
else
|
||||
this.externalUrl = this.url;
|
||||
|
||||
this.visible = true;
|
||||
},
|
||||
100
|
||||
due
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -81,6 +160,15 @@
|
|||
}
|
||||
|
||||
|
||||
cancelExitTimer() {
|
||||
if (this.exitInterval) {
|
||||
clearTimeout(this.exitInterval);
|
||||
}
|
||||
|
||||
this.exitInterval = null;
|
||||
}
|
||||
|
||||
|
||||
isVisible() {
|
||||
return this.visible;
|
||||
}
|
||||
|
@ -115,7 +203,7 @@
|
|||
top: 0;
|
||||
left: 0;
|
||||
pointer-events: none;
|
||||
|
||||
background-color: black;
|
||||
}
|
||||
|
||||
.image-preview-local {
|
||||
|
@ -128,5 +216,6 @@
|
|||
background-size: contain;
|
||||
background-position: top left;
|
||||
background-repeat: no-repeat;
|
||||
// background-color: black;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
/* tslint:disable:quotemark */
|
||||
|
||||
import { domain } from '../bbcode/core';
|
||||
|
||||
export interface ImagePreviewMutatorCollection {
|
||||
[key: string]: string;
|
||||
}
|
||||
|
||||
export class ImagePreviewMutator {
|
||||
private mutators: ImagePreviewMutatorCollection = {};
|
||||
|
||||
constructor() {
|
||||
this.init();
|
||||
}
|
||||
|
||||
getMutatorJsForSite(url: string): string | undefined {
|
||||
const urlDomain = domain(url);
|
||||
|
||||
if (!urlDomain)
|
||||
return;
|
||||
|
||||
console.log('Domain is', urlDomain);
|
||||
|
||||
const mutatorJs = this.mutators[urlDomain];
|
||||
|
||||
if (!mutatorJs)
|
||||
return;
|
||||
|
||||
return `(() => { try { ${mutatorJs} } catch (err) { console.error(err); } })()`;
|
||||
}
|
||||
|
||||
protected add(domain: string, mutatorJs: string) {
|
||||
this.mutators[domain] = mutatorJs;
|
||||
}
|
||||
|
||||
protected init() {
|
||||
this.add('e621.net', this.getBaseJsMutatorScript('#image'));
|
||||
this.add('e-hentai.org', this.getBaseJsMutatorScript('#img'));
|
||||
this.add('gelbooru.com', this.getBaseJsMutatorScript('#image'));
|
||||
this.add('chan.sankakucomplex.com', this.getBaseJsMutatorScript('#image'));
|
||||
|
||||
this.add(
|
||||
'gfycat.com',
|
||||
`${this.getBaseJsMutatorScript('video')}
|
||||
document.querySelector('video').play();
|
||||
`
|
||||
);
|
||||
|
||||
this.add(
|
||||
'imgur.com',
|
||||
`
|
||||
const imageCount = $('.post-image-container').length;
|
||||
|
||||
${this.getBaseJsMutatorScript('.image.post-image img, .image.post-image video')}
|
||||
|
||||
if(imageCount > 1)
|
||||
$('#flistWrapper').append('<div id="imageCount" style="position: absolute; bottom: 0; right: 0; background: green; border: 2px solid lightgreen; width: 5rem; height: 5rem; font-size: 2rem; font-weight: bold; color: white; border-radius: 5rem; margin: 0.75rem;"><div style="position: absolute; top: 50%; left: 50%; transform: translateY(-50%) translateX(-50%);">+' + (imageCount - 1) + '</div></div>');
|
||||
`
|
||||
|
||||
// "$('#topbar').hide();"
|
||||
// + "$('.post-header').hide();"
|
||||
// + "$('#inside').css({padding: 0, margin: 0, width: '100%'});"
|
||||
// + "$('#right-content').hide();"
|
||||
// + "$('.post-container').css({width: '100%'});"
|
||||
// + "$('.post-image img').css({width: 'auto', 'min-height': 'unset', 'max-height': '100vh'});"
|
||||
// + "$('#recommendations').hide();"
|
||||
// + "$('.left').css({float: 'none'});"
|
||||
// + "$('body').css({overflow: 'hidden'});"
|
||||
// + "const imageCount = $('.post-image-container').length;"
|
||||
// + "if(imageCount > 1) {"
|
||||
// + "$('body').append('<div id=\"imageCount\" style=\"position: absolute; bottom: 0; right: 0; background: green; border: 2px solid lightgreen; width: 5rem; height: 5rem; font-size: 2rem; font-weight: bold; color: white; border-radius: 5rem; margin: 0.75rem;\"><div style=\"position: absolute; top: 50%; left: 50%; transform: translateY(-50%) translateX(-50%);\">+' + (imageCount - 1) + '</div></div>');"
|
||||
// + "}"
|
||||
);
|
||||
|
||||
this.add(
|
||||
'rule34.xxx',
|
||||
`${this.getBaseJsMutatorScript('#image')}
|
||||
const content = document.querySelector('#content');
|
||||
content.remove();
|
||||
`
|
||||
);
|
||||
}
|
||||
|
||||
getBaseJsMutatorScript(imageSelector: string): string {
|
||||
return `const body = document.querySelector('body');
|
||||
const img = document.querySelector('${imageSelector}');
|
||||
const el = document.createElement('div');
|
||||
el.id = 'flistWrapper';
|
||||
|
||||
el.style = 'width: 100%; height: 100%; position: absolute; top: 0; left: 0; z-index: 100000; '
|
||||
+ 'background-color: black; background-size: contain; background-repeat: no-repeat; background-position: top left;';
|
||||
|
||||
img.remove();
|
||||
el.append(img);
|
||||
body.append(el);
|
||||
body.style = 'padding: 0; margin: 0; overflow: hidden; width: 100%; height: 100%';
|
||||
img.style = 'object-position: top left; object-fit: contain; width: 100%; height: 100%;'
|
||||
`;
|
||||
}
|
||||
|
||||
}
|
|
@ -118,7 +118,8 @@ function createWindow(): Electron.BrowserWindow | undefined {
|
|||
if(tabCount >= 3) return;
|
||||
const lastState = windowState.getSavedWindowState();
|
||||
const windowProperties: Electron.BrowserWindowConstructorOptions & {maximized: boolean} = {
|
||||
...lastState, center: lastState.x === undefined, show: false
|
||||
...lastState, center: lastState.x === undefined, show: false,
|
||||
webPreferences: { webviewTag: true }
|
||||
};
|
||||
if(process.platform === 'darwin') windowProperties.titleBarStyle = 'hiddenInset';
|
||||
else windowProperties.frame = false;
|
||||
|
|
Loading…
Reference in New Issue