Fix themes & Added Reader Image Modal (#997)
* fix: annoying scroll on context menu * fix app theme * fix: android textselecthandle color * fix plugin render callback dependencies * add image modal for reader
This commit is contained in:
@@ -303,4 +303,27 @@ tts.highlight {
|
||||
opacity: 1;
|
||||
transform: translateX(0);
|
||||
}
|
||||
}
|
||||
|
||||
#Image-Modal {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
#Image-Modal.show {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
max-width: max-content;
|
||||
max-height: max-content;
|
||||
background-color: var(--theme-surface-0-9);
|
||||
align-items: center;
|
||||
overflow: scroll;
|
||||
}
|
||||
|
||||
#Image img {
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
@@ -25,6 +25,7 @@ const selectVolumeIcon =
|
||||
class Reader {
|
||||
constructor() {
|
||||
this.selection = window.getSelection();
|
||||
this.viewport = document.querySelector('meta[name=viewport]');
|
||||
this.footerWrapper = document.getElementById('reader-footer-wrapper');
|
||||
this.percentage = document.getElementById('reader-percentage');
|
||||
this.battery = document.getElementById('reader-battery');
|
||||
@@ -510,6 +511,14 @@ class ContextMenu {
|
||||
});
|
||||
document.addEventListener('contextmenu', e => {
|
||||
e.preventDefault();
|
||||
if (e.target instanceof HTMLImageElement) {
|
||||
if (imageModal.showing) {
|
||||
imageModal.hide();
|
||||
} else {
|
||||
imageModal.show(e.target);
|
||||
}
|
||||
return;
|
||||
}
|
||||
this.isOpened = true;
|
||||
if (this.reader.selection.type === 'Range') {
|
||||
this.renderMenu([this.items.START_HERE, this.items.START_READING]);
|
||||
@@ -517,7 +526,7 @@ class ContextMenu {
|
||||
this.renderMenu([this.items.START_READING]);
|
||||
}
|
||||
const { clientX, clientY } = e;
|
||||
document.body.appendChild(this.contextMenu);
|
||||
e.target.appendChild(this.contextMenu);
|
||||
const positionY =
|
||||
clientY + this.contextMenu.scrollHeight >= window.innerHeight
|
||||
? window.innerHeight - this.contextMenu.scrollHeight - 20
|
||||
@@ -537,6 +546,55 @@ class ContextMenu {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {import("./type").ImageModal}
|
||||
*/
|
||||
class ImageModal {
|
||||
/**
|
||||
* @param {import('./type').Reader} reader
|
||||
*/
|
||||
constructor(reader) {
|
||||
this.reader = reader;
|
||||
this.$ = document.getElementById('Image-Modal');
|
||||
this.img = this.$.querySelector('img');
|
||||
this.showing = false;
|
||||
this.$.onclick = e => {
|
||||
if (e.target.id !== 'Image-Modal-img') {
|
||||
e.stopPropagation();
|
||||
this.hide();
|
||||
}
|
||||
};
|
||||
this.$.ontouchmove = e => {
|
||||
e.stopImmediatePropagation();
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {HTMLImageElement} image
|
||||
*/
|
||||
show(image) {
|
||||
this.img.src = image.src;
|
||||
this.img.alt = `Can not render image from ${image.src}`;
|
||||
this.reader.viewport.setAttribute(
|
||||
'content',
|
||||
'width=device-width, initial-scale=1.0, maximum-scale=10',
|
||||
);
|
||||
this.$.classList.add('show');
|
||||
this.showing = true;
|
||||
}
|
||||
hide() {
|
||||
this.$.classList.remove('show');
|
||||
this.showing = false;
|
||||
this.img.src = '';
|
||||
this.img.alt = '';
|
||||
this.reader.viewport.setAttribute(
|
||||
'content',
|
||||
'width=device-width, initial-scale=1.0, maximum-scale=1.0',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
var swipeHandler = new SwipeHandler();
|
||||
var toolWrapper = new ToolWrapper();
|
||||
@@ -544,6 +602,7 @@ try {
|
||||
var scrollHandler = new ScrollHandler(reader, toolWrapper);
|
||||
var tts = new TextToSpeech(reader);
|
||||
toolWrapper.tools = [scrollHandler, tts];
|
||||
imageModal = new ImageModal(reader);
|
||||
const contextMenu = new ContextMenu(reader);
|
||||
contextMenu.init();
|
||||
} catch (e) {
|
||||
|
||||
+8
@@ -7,6 +7,7 @@ import 'typescript/lib/lib.dom';
|
||||
|
||||
interface Reader {
|
||||
selection: Selection;
|
||||
viewport: HTMLMetaElement;
|
||||
footerWrapper: HTMLDivElement;
|
||||
percentage: HTMLDivElement;
|
||||
battery: HTMLDivElement;
|
||||
@@ -60,3 +61,10 @@ interface ContextMenu {
|
||||
closeMenu: (menu: HTMLUListElement) => void;
|
||||
init: () => void;
|
||||
}
|
||||
|
||||
interface ImageModal {
|
||||
reader: Reader;
|
||||
showing: boolean;
|
||||
show: (image: HTMLImageElement) => void;
|
||||
hide: () => void;
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||
<item name="android:navigationBarColor">@color/colorPrimaryDark</item>
|
||||
<item name="android:statusBarColor">@color/colorPrimaryDark</item>
|
||||
<item name="colorControlActivated">#2596be</item>
|
||||
</style>
|
||||
|
||||
<style name="SplashScreenTheme" parent="SplashScreen_SplashTheme">
|
||||
|
||||
@@ -181,7 +181,7 @@ export const InstalledTab = memo(
|
||||
</Swipeable>
|
||||
);
|
||||
},
|
||||
[theme.primary],
|
||||
[theme.id, searchedPlugins],
|
||||
);
|
||||
|
||||
return (
|
||||
@@ -368,7 +368,7 @@ export const AvailableTab = memo(({ searchText, theme }: AvailableTabProps) => {
|
||||
/>
|
||||
);
|
||||
},
|
||||
[theme.primary],
|
||||
[theme.id, sections],
|
||||
);
|
||||
|
||||
return (
|
||||
|
||||
@@ -241,6 +241,9 @@ const WebViewReader: FC<WebViewReaderProps> = props => {
|
||||
<div id="TTS-Controller"></div>
|
||||
<div id="ScrollBar"></div>
|
||||
</div>
|
||||
<div id="Image-Modal">
|
||||
<img id="Image-Modal-img">
|
||||
</div>
|
||||
<div id="reader-footer-wrapper">
|
||||
<div id="reader-footer">
|
||||
<div id="reader-battery" class="reader-footer-item"></div>
|
||||
|
||||
@@ -23,7 +23,7 @@ export const midnightDusk = {
|
||||
onErrorContainer: 'rgb(65, 0, 2)',
|
||||
background: 'rgb(255, 251, 255)',
|
||||
onBackground: 'rgb(28, 27, 31)',
|
||||
surface: 'rgba(255, 243, 252)',
|
||||
surface: 'rgb(254, 251, 255)',
|
||||
onSurface: 'rgb(28, 27, 31)',
|
||||
surfaceVariant: 'rgb(243, 221, 224)',
|
||||
onSurfaceVariant: 'rgb(82, 67, 70)',
|
||||
|
||||
Reference in New Issue
Block a user