Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
8f33143
copied old code
CD-Z Feb 27, 2026
54737de
clean up WebVieweReader
CD-Z Feb 28, 2026
34db2c6
update pnpm-lock.yaml
CD-Z May 8, 2026
ab47426
Update index.tsx
CD-Z May 8, 2026
cf5ada0
Improve TextInput focus and keyboard behavior
CD-Z May 8, 2026
7d263e7
optimized app bar animation
CD-Z May 8, 2026
6c49696
Remove gap between keyboard and content
CD-Z May 8, 2026
785cdc0
Update ToggleButton
CD-Z May 8, 2026
f33313f
Remove AdvancedTab from Reader settings
CD-Z May 8, 2026
2460bac
added code migration
CD-Z May 10, 2026
0d0aa6b
Update settings webview
CD-Z May 10, 2026
bb2f94e
updated text remover modal
CD-Z May 10, 2026
9b1d492
small fixes
CD-Z May 10, 2026
bc1cb67
add stopPropagation
CD-Z May 10, 2026
c6d8e49
dismiss Keyboard on closing KeyboardAvoidingModal
CD-Z May 10, 2026
93c2bdd
add simple regex validation
CD-Z May 10, 2026
4cf29ee
Update KeyboardAvoidingModal.tsx
CD-Z May 10, 2026
2ca43ae
added localization
CD-Z May 10, 2026
b86e43d
Update useTextModifications.ts
CD-Z May 10, 2026
9672a04
Update useTextModifications.ts
CD-Z May 10, 2026
92cbbd1
updated KeyboardAvoidingModal
CD-Z May 10, 2026
607a79c
Update SettingsReaderWebView.tsx
CD-Z May 10, 2026
806a0b8
Update useTextModifications.ts
CD-Z May 10, 2026
822ffde
Update SettingsReaderWebView.tsx
CD-Z May 10, 2026
8cf71ea
Update ReaderScreen.tsx
CD-Z May 10, 2026
2f6ed73
Update setting migration
CD-Z May 10, 2026
93c298d
clone snippets on save
CD-Z May 10, 2026
297feb8
fade out disabled ToggleButton
CD-Z May 10, 2026
f77c8eb
small fixes
CD-Z Jul 1, 2026
18ef214
Custom code screen rework
CD-Z Jul 1, 2026
fd0cad8
Switch to KeyboardAwareScrollView
CD-Z Jul 1, 2026
400f8ad
Fix scrolling.
CD-Z Jul 1, 2026
6c78580
redesign
CD-Z Jul 1, 2026
7cb5974
Extracted Snippet
CD-Z Jul 1, 2026
cc52d26
update KeyboardAvoidingModal
CD-Z Jul 2, 2026
4d51074
Update CustomCodeScreen with SimpleCodeEditor
CD-Z Jul 2, 2026
7d519c6
added file import
CD-Z Jul 3, 2026
ee214d1
rewrite again
CD-Z Jul 3, 2026
bb8b8ce
updated codeeditor
CD-Z Jul 4, 2026
a98d835
fix item list height calculation
CD-Z Jul 4, 2026
e610de7
change to prism for highlighting
CD-Z Jul 4, 2026
7f13993
change highlightColors in Dark mode
CD-Z Jul 4, 2026
7291146
continue on empty text
CD-Z Jul 4, 2026
8f03941
fix smaller issues
CD-Z Jul 4, 2026
0473d91
improved types
CD-Z Jul 4, 2026
55f64fa
Localized new strings
CD-Z Jul 4, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 18 additions & 13 deletions App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import LottieSplashScreen from 'react-native-lottie-splash-screen';
import { SafeAreaProvider } from 'react-native-safe-area-context';
import { Provider as PaperProvider } from 'react-native-paper';
import * as Notifications from 'expo-notifications';
import { KeyboardProvider } from 'react-native-keyboard-controller';

import AppErrorBoundary, {
ErrorFallback,
Expand All @@ -31,7 +32,6 @@ Notifications.setNotificationHandler({
},
});


const App = () => {
const state = useInitDatabase();

Expand All @@ -48,18 +48,23 @@ const App = () => {
return (
<Suspense fallback={null}>
<GestureHandlerRootView style={styles.flex}>
<AppErrorBoundary>
<SafeAreaProvider>
<ThemeProvider>
<PaperProvider>
<BottomSheetModalProvider>
<StatusBar translucent={true} backgroundColor="transparent" />
<Main />
</BottomSheetModalProvider>
</PaperProvider>
</ThemeProvider>
</SafeAreaProvider>
</AppErrorBoundary>
<ThemeProvider>
<AppErrorBoundary>
<SafeAreaProvider>
<KeyboardProvider>
<PaperProvider>
<BottomSheetModalProvider>
<StatusBar
translucent={true}
backgroundColor="transparent"
/>
<Main />
</BottomSheetModalProvider>
</PaperProvider>
</KeyboardProvider>
</SafeAreaProvider>
</AppErrorBoundary>
</ThemeProvider>
</GestureHandlerRootView>
</Suspense>
);
Expand Down
6 changes: 3 additions & 3 deletions android/app/src/main/assets/css/toolWrapper.css
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@
right: unset;
left: 50%;
transform: translateX(-50%);
bottom: 120px;
bottom: calc(68px + var(--bottom-inset));
display: flex;
flex-direction: row-reverse;
align-items: center;
}

@media only screen and (min-width: 500px) {
#ToolWrapper.horizontal {
bottom: 80px;
bottom: calc(28px + var(--bottom-inset));
}
}

Expand All @@ -32,7 +32,7 @@

#ToolWrapper.hidden.horizontal {
opacity: 0;
bottom: 80px;
bottom: calc(28px + var(--bottom-inset));
right: unset;
}

Expand Down
195 changes: 195 additions & 0 deletions android/app/src/main/assets/js/textRemover.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
// Text selection functionality
window.textRemover = new (function () {
let selectionUI = null;
let isUIActive = false;

function createSelectionUI() {
if (selectionUI) return selectionUI;

const { div, button } = van.tags;
selectionUI = div(
{
id: 'text-selection-ui',
style:
'position: fixed; background: color-mix(in srgb, var(--theme-surface), transparent 10%); border-radius: 8px; padding: 8px; z-index: 100000; opacity: 0; box-shadow: 0 4px 12px rgba(0,0,0,0.25); transition: opacity 150ms',
},
button(
{
style:
'background: var(--theme-secondary); color: var(--theme-onSecondary); padding: 6px 12px; margin: 2px; border-radius: 4px; font-size: 12px;',
onclick: e => {
if (reader.hidden.val) {
e.stopPropagation();
}
removeSelectedText();
},
},
'Remove',
),
button(
{
style:
'background: var(--theme-primary); color: var(--theme-onPrimary); padding: 6px 12px; margin: 2px; border-radius: 4px; font-size: 12px;',
onclick: e => {
if (reader.hidden.val) {
e.stopPropagation();
}
replaceSelectedText();
},
},
'Replace',
),
);

document.body.appendChild(selectionUI);
return selectionUI;
}

function showSelectionUI() {
const ui = createSelectionUI();

// Get selection bounds
const selection = window.getSelection();
if (selection.rangeCount > 0) {
const range = selection.getRangeAt(0);
const rect = range.getBoundingClientRect();

// Get UI element heights from CSS variables (with fallbacks)
const statusBarHeight =
parseInt(
getComputedStyle(document.documentElement).getPropertyValue(
'--StatusBar-currentHeight',
),
10,
) || 24;
const navigationBarHeight =
parseInt(
getComputedStyle(document.documentElement).getPropertyValue(
'--bottom-inset',
),
10,
) || 24;
const readerPadding =
parseInt(
getComputedStyle(document.documentElement).getPropertyValue(
'--readerSettings-padding',
),
10,
) || 16;
const uiHeight = 50; // Approximate height of our UI

// Calculate available space
const viewportHeight = window.innerHeight;
const selectionCenterY = rect.top + rect.height / 2;
const topSafeArea = statusBarHeight + readerPadding + 10;
const bottomSafeArea = readerPadding + uiHeight + navigationBarHeight;

// Position UI based on selection location
let topPosition;
if (selectionCenterY < viewportHeight / 2) {
// Selection is in top half, position UI at bottom
//TODO: make this dynamic
const avoidScrollbar = reader.generalSettings.val.verticalSeekbar
? 0
: 42;
const avoidUI = !reader.hidden.val ? 46 + avoidScrollbar : 0;
topPosition = viewportHeight - bottomSafeArea - avoidUI - 4;
ui.style.top = topPosition + 'px';
ui.style.bottom = 'auto';
} else {
// Selection is in bottom half, position UI at top (accounting for status bar)
topPosition = Math.max(topSafeArea, statusBarHeight + 20);
const avoidUI = !reader.hidden.val ? 34 : 0;
ui.style.top = topPosition + avoidUI + 'px';
ui.style.bottom = 'auto';
}

// Center horizontally
ui.style.left = '50%';
ui.style.transform = 'translateX(-50%)';
} else {
// Fallback: position at top if no selection rect available
ui.style.top = '20px';
ui.style.left = '50%';
ui.style.transform = 'translateX(-50%)';
ui.style.bottom = 'auto';
}

ui.style.opacity = '1';
isUIActive = true;
}

function hideSelectionUI() {
if (selectionUI) {
selectionUI.style.opacity = '0';
}
isUIActive = false;
}

function getSelectedText() {
const selection = window.getSelection();
if (selection.rangeCount > 0) {
return selection.toString().trim();
}
return '';
}
Comment thread
CD-Z marked this conversation as resolved.

function removeSelectedText() {
const selectedText = getSelectedText();
if (selectedText) {
reader.post({
type: 'text-action',
data: { remove: selectedText },
});
}
hideSelectionUI();
window.getSelection().removeAllRanges();
}

function replaceSelectedText() {
const selectedText = getSelectedText();
if (selectedText) {
// For replace, we need user input, so send a different message
reader.post({
type: 'text-action',
data: { replace: selectedText },
});
}
hideSelectionUI();
window.getSelection().removeAllRanges();
}

// Handle text selection
document.addEventListener('selectionchange', function () {
const selectedText = getSelectedText();
if (selectedText) {
showSelectionUI();
} else if (!isUIActive) {
hideSelectionUI();
}
});

// Hide UI when clicking/tapping elsewhere
document.addEventListener('touchstart', function (e) {
if (isUIActive && selectionUI && !selectionUI.contains(e.target)) {
const selectedText = getSelectedText();
if (!selectedText) {
hideSelectionUI();
}
}
});

document.addEventListener('click', function (e) {
if (isUIActive && selectionUI && !selectionUI.contains(e.target)) {
const selectedText = getSelectedText();
if (!selectedText) {
hideSelectionUI();
}
}
});

// Hide UI on scroll
window.addEventListener('scroll', function () {
hideSelectionUI();
});
})();
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@
"react-native-error-boundary": "^3.1.0",
"react-native-file-access": "^4.0.2",
"react-native-gesture-handler": "^2.30.1",
"react-native-keyboard-controller": "^1.20.7",
"react-native-lottie-splash-screen": "^1.1.2",
"react-native-mmkv": "^4.3.0",
"react-native-nitro-modules": "^0.35.2",
Expand Down Expand Up @@ -142,6 +143,7 @@
"@types/jest": "^29.5.14",
"@types/lodash-es": "^4.17.12",
"@types/react": "~19.2.14",
"@types/react-syntax-highlighter": "^15.5.13",
"@types/sanitize-html": "^2.16.1",
"@typescript-eslint/eslint-plugin": "^8.58.0",
"@typescript-eslint/parser": "^8.58.0",
Expand All @@ -163,6 +165,7 @@
"jest-expo": "^55.0.11",
"lint-staged": "^12.5.0",
"prettier": "2.8.8",
"react-syntax-highlighter": "^16.1.1",
"react-test-renderer": "19.2.4",
"rock": "^0.12.12",
"typescript": "~5.9.3"
Expand Down
Loading
Loading