diff --git a/.editorconfig b/.editorconfig index 939f463..abb18f4 100644 --- a/.editorconfig +++ b/.editorconfig @@ -30,4 +30,4 @@ indent_size = 2 indent_size = 2 [*.{xaml}] -indent_size = 4 +indent_size = 2 diff --git a/.gitignore b/.gitignore index de9d934..cf42f4d 100644 --- a/.gitignore +++ b/.gitignore @@ -8,7 +8,11 @@ **/BundleArtifacts/ **/GeneratedArtifacts/ **/.vs/ -**/.vscode/ +# Ignore editor-local VSCode/VSCodium files, but commit the shared workspace +# config (issue #22: 2-space XAML for VSCodium). +**/.vscode/* +!.vscode/settings.json +!.vscode/extensions.json *.user *.suo *.userosscache diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..7fb3b6e --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,7 @@ +{ + // EditorConfig makes VSCodium honor .editorconfig (including 2-space XAML) for + // every file type, not just the [xml]/[xaml] overrides in settings.json. + "recommendations": [ + "editorconfig.editorconfig" + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..4af7e19 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,13 @@ +{ + // XAML is treated as XML by VSCodium. Force 2-space indentation and stop the + // editor from guessing indent width from file contents (issue #22). + "editor.detectIndentation": false, + "[xml]": { + "editor.tabSize": 2, + "editor.insertSpaces": true + }, + "[xaml]": { + "editor.tabSize": 2, + "editor.insertSpaces": true + } +} diff --git a/App.xaml b/App.xaml index 807e8bc..498a7ad 100644 --- a/App.xaml +++ b/App.xaml @@ -2,12 +2,12 @@ - - - - - - - - + + + + + + + + diff --git a/AppShell.xaml b/AppShell.xaml index 52fff8d..5da7606 100644 --- a/AppShell.xaml +++ b/AppShell.xaml @@ -4,5 +4,5 @@ xmlns:views="clr-namespace:PostXING.App.Views" x:Class="PostXING.App.AppShell" Shell.FlyoutBehavior="Disabled"> - + diff --git a/Platforms/Android/MainActivity.cs b/Platforms/Android/MainActivity.cs index 64f7fa8..3564f92 100644 --- a/Platforms/Android/MainActivity.cs +++ b/Platforms/Android/MainActivity.cs @@ -10,10 +10,9 @@ namespace PostXING.App; Theme = "@style/Maui.SplashTheme", MainLauncher = true, LaunchMode = LaunchMode.SingleTop, - // AdjustResize is kept as a hint, but target SDK 35+ edge-to-edge enforcement defeats it: the - // window no longer shrinks for the soft keyboard. So EditorPage reads the IME inset natively and - // pushes it into the editor JS, which sizes the editor above the keyboard (GH #39). Harmless - // where AdjustResize still works. + // AdjustResize so the soft keyboard shrinks the WebView viewport instead of panning the + // window up; CodeMirror inside the editor then auto-scrolls the cursor into view. Without + // this the keyboard can sit on top of the last few lines of text. WindowSoftInputMode = SoftInput.AdjustResize, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density)] public class MainActivity : MauiAppCompatActivity diff --git a/Platforms/Windows/App.xaml b/Platforms/Windows/App.xaml index a6d30e6..57e09c1 100644 --- a/Platforms/Windows/App.xaml +++ b/Platforms/Windows/App.xaml @@ -1,7 +1,7 @@ + x:Class="PostXING.App.WinUI.App" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:maui="using:Microsoft.Maui"> diff --git a/Resources/Raw/editor/index.html b/Resources/Raw/editor/index.html index b85fc95..307fa6a 100644 --- a/Resources/Raw/editor/index.html +++ b/Resources/Raw/editor/index.html @@ -749,30 +749,20 @@ setCaretOffset(editor, offset); } - // Keep the editor sized to the actual visible area above the Android soft keyboard. The visual - // viewport does NOT shrink for the soft keyboard on the Android WebView (measured: innerHeight, - // visualViewport.height and this var all stay full-height whether the keyboard is up or down), so - // the JS can't detect the keyboard on its own. Instead the Android host reads the IME inset - // natively and pushes it here (in device px) via setKeyboardInsetPx; we subtract it from - // innerHeight. On Windows hostInsetPx stays 0 and we use the visual viewport height unchanged - // (there's no soft keyboard to exclude there). - let hostInsetPx = 0; // soft-keyboard height in *device* px, pushed by the Android host (0 = hidden) + // Keep the editor sized to the visual viewport (the actual visible area, excluding the + // Android soft keyboard). Without this, AdjustResize doesn't always shrink the WebView's + // layout viewport, and content scrolls "off the bottom" behind the keyboard. function syncEditorHeight() { - let h; - if (hostInsetPx > 0) { - const dpr = window.devicePixelRatio || 1; - h = Math.max(120, window.innerHeight - hostInsetPx / dpr); - } else { - h = window.visualViewport ? window.visualViewport.height : window.innerHeight; - } - document.documentElement.style.setProperty('--vv-h', h + 'px'); + const vv = window.visualViewport; + if (!vv) return; + document.documentElement.style.setProperty('--vv-h', vv.height + 'px'); } syncEditorHeight(); if (window.visualViewport) { window.visualViewport.addEventListener('resize', () => { syncEditorHeight(); - // Once the new height is applied, bring the caret back into view; a frame's delay so the - // height has taken effect and the rects are fresh. + // Once the keyboard finishes appearing, bring the caret back into view; a frame's + // delay so the new height has been applied and rects are fresh. requestAnimationFrame(scrollCaretIntoView); }); } @@ -853,19 +843,6 @@ scheduleOutgoing(); }); - // Keep the caret visible as it moves — typing, newlines, arrows, taps — regardless of IME - // composition state. The input handler above defers to compositionend while composing, which - // would otherwise let the caret slide behind the keyboard mid-word; selectionchange fires on - // every caret move, so it covers that gap. Throttled to one frame. - let caretScrollScheduled = false; - document.addEventListener('selectionchange', () => { - if (caretScrollScheduled) return; - const sel = window.getSelection(); - if (!sel || !sel.rangeCount || !editor.contains(sel.anchorNode)) return; - caretScrollScheduled = true; - requestAnimationFrame(() => { caretScrollScheduled = false; scrollCaretIntoView(); }); - }); - // Paste as plain text (strip styles from the OS clipboard). editor.addEventListener('paste', (e) => { e.preventDefault(); @@ -932,14 +909,6 @@ focus() { editor.focus(); }, - // Android host -> JS: the soft-keyboard height in device px (0 when hidden). The visual viewport - // doesn't shrink for the keyboard on the Android WebView, so this is the only reliable signal; - // we resize the editor to the visible area above the keyboard and pull the caret back into view. - setKeyboardInsetPx(px) { - hostInsetPx = (typeof px === 'number' && px > 0) ? px : 0; - syncEditorHeight(); - requestAnimationFrame(scrollCaretIntoView); - }, getText() { return editor.innerText; }, diff --git a/Resources/Styles/Colors.xaml b/Resources/Styles/Colors.xaml index 461dee0..a7882a0 100644 --- a/Resources/Styles/Colors.xaml +++ b/Resources/Styles/Colors.xaml @@ -2,43 +2,43 @@ - - - - #1E5BFF - #4D7DFF - #0A2BC2 - #06B6D4 - #0E7490 - #E08A2E - #D97706 - #B25C00 - - - #7F170E - - - #08081A - #0F0F1F - #1A1A2E - #2D2D4A - - - #FFFFFF - #E5E7EB - #9095A4 - #6B7080 - - - #10B981 - #F59E0B - #EF4444 - - - #8C000000 - - - #2D2D4A - #E5E7EB + + + + #1E5BFF + #4D7DFF + #0A2BC2 + #06B6D4 + #0E7490 + #E08A2E + #D97706 + #B25C00 + + + #7F170E + + + #08081A + #0F0F1F + #1A1A2E + #2D2D4A + + + #FFFFFF + #E5E7EB + #9095A4 + #6B7080 + + + #10B981 + #F59E0B + #EF4444 + + + #8C000000 + + + #2D2D4A + #E5E7EB diff --git a/Resources/Styles/Styles.xaml b/Resources/Styles/Styles.xaml index 37c6b15..b9aa5f1 100644 --- a/Resources/Styles/Styles.xaml +++ b/Resources/Styles/Styles.xaml @@ -2,180 +2,180 @@ - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/Views/AboutPage.xaml b/Views/AboutPage.xaml index decda4e..95816a8 100644 --- a/Views/AboutPage.xaml +++ b/Views/AboutPage.xaml @@ -5,107 +5,107 @@ BackgroundColor="{AppThemeBinding Light={StaticResource Paper100}, Dark={StaticResource Ink950}}" Shell.NavBarIsVisible="False" Title="About"> - - - + + + -