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:
nyagami
2024-03-10 23:04:50 +07:00
committed by GitHub
parent 40b7542a78
commit dde33a0576
7 changed files with 98 additions and 4 deletions
+23
View File
@@ -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%;
}
+60 -1
View File
@@ -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
View File
@@ -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">
+2 -2
View File
@@ -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>
+1 -1
View File
@@ -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)',