Improve mobile/iOS support and simplify theme handling
- Add iOS/mobile meta tags for better web app experience - Enhance Editor.razor.css for mobile responsiveness and touch - Simplify theme logic: only light/dark, no "auto" mode - Remove localStorage and system theme detection from theme.js - Apply themes via CSS variables for better compatibility - Update ThemeToggle to match new theme logic and improve UX
This commit is contained in:
@@ -3,7 +3,11 @@
|
|||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no" />
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
||||||
|
<meta name="apple-mobile-web-app-title" content="Notemark" />
|
||||||
|
<meta name="mobile-web-app-capable" content="yes" />
|
||||||
<base href="/" />
|
<base href="/" />
|
||||||
<ResourcePreloader />
|
<ResourcePreloader />
|
||||||
<link rel="stylesheet" href="@Assets["lib/bootstrap/dist/css/bootstrap.min.css"]" />
|
<link rel="stylesheet" href="@Assets["lib/bootstrap/dist/css/bootstrap.min.css"]" />
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
/* Notemark Editor Styles */
|
/* Notemark Editor Styles */
|
||||||
|
|
||||||
.editor-container {
|
.editor-container {
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -458,37 +457,76 @@
|
|||||||
background-color: white;
|
background-color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Mobile Responsive */
|
/* Mobile Responsive - Place at end to override desktop styles */
|
||||||
@media (max-width: 768px) {
|
@media screen and (max-width: 768px) {
|
||||||
.editor-layout.split-view {
|
.editor-layout.split-view {
|
||||||
flex-direction: column;
|
flex-direction: column !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.split-view .editor-pane {
|
.split-view .editor-pane {
|
||||||
border-right: none;
|
border-right: none;
|
||||||
border-bottom: 1px solid var(--border);
|
border-bottom: 1px solid var(--border);
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-pane {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.splitter {
|
||||||
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.top-bar {
|
.top-bar {
|
||||||
padding: 0.5rem;
|
padding: 0.5rem;
|
||||||
|
height: auto;
|
||||||
|
min-height: 50px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-bar-left,
|
||||||
|
.top-bar-center,
|
||||||
|
.top-bar-right {
|
||||||
|
gap: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-toggle,
|
.btn-toggle,
|
||||||
.btn-share,
|
.btn-share,
|
||||||
.btn-save,
|
.btn-save,
|
||||||
.btn-new {
|
.btn-new {
|
||||||
font-size: 0.75rem;
|
font-size: 14px;
|
||||||
padding: 0.375rem 0.75rem;
|
padding: 8px 12px;
|
||||||
|
min-height: 44px;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-save {
|
.btn-save {
|
||||||
padding: 0.375rem;
|
min-width: 44px;
|
||||||
min-width: 2rem;
|
padding: 8px;
|
||||||
font-size: 0.875rem;
|
}
|
||||||
|
|
||||||
|
.markdown-editor {
|
||||||
|
font-size: 16px; /* Prevent iOS zoom */
|
||||||
|
padding: 1rem;
|
||||||
|
-webkit-overflow-scrolling: touch;
|
||||||
}
|
}
|
||||||
|
|
||||||
.markdown-editor,
|
|
||||||
.preview-content {
|
.preview-content {
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
|
-webkit-overflow-scrolling: touch;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Share dropdown mobile adjustments */
|
||||||
|
.share-dropdown {
|
||||||
|
position: fixed;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
width: 90vw;
|
||||||
|
max-width: 320px;
|
||||||
|
z-index: 1000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -5,39 +5,35 @@
|
|||||||
</button>
|
</button>
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
private string currentTheme = "auto";
|
private string currentTheme = "light";
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
await JSRuntime.InvokeVoidAsync("notemarkTheme.init");
|
||||||
currentTheme = await JSRuntime.InvokeAsync<string>("notemarkTheme.getCurrentTheme");
|
currentTheme = await JSRuntime.InvokeAsync<string>("notemarkTheme.getCurrentTheme");
|
||||||
}
|
}
|
||||||
catch
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
// Fallback if JS not ready
|
System.Diagnostics.Debug.WriteLine($"Theme init error: {ex.Message}");
|
||||||
currentTheme = "auto";
|
currentTheme = "light";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task ToggleTheme()
|
private async Task ToggleTheme()
|
||||||
{
|
{
|
||||||
// Cycle through: auto -> light -> dark -> auto
|
// Simple toggle: light <-> dark
|
||||||
currentTheme = currentTheme switch
|
currentTheme = currentTheme == "light" ? "dark" : "light";
|
||||||
{
|
|
||||||
"auto" => "light",
|
|
||||||
"light" => "dark",
|
|
||||||
"dark" => "auto",
|
|
||||||
_ => "auto"
|
|
||||||
};
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await JSRuntime.InvokeVoidAsync("notemarkTheme.setTheme", currentTheme);
|
await JSRuntime.InvokeVoidAsync("notemarkTheme.setTheme", currentTheme);
|
||||||
|
System.Diagnostics.Debug.WriteLine($"Theme switched to: {currentTheme}");
|
||||||
}
|
}
|
||||||
catch
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
// JS not ready, silently fail
|
System.Diagnostics.Debug.WriteLine($"Theme toggle error: {ex.Message}");
|
||||||
}
|
}
|
||||||
|
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
@@ -45,23 +41,11 @@
|
|||||||
|
|
||||||
private string GetThemeIcon()
|
private string GetThemeIcon()
|
||||||
{
|
{
|
||||||
return currentTheme switch
|
return currentTheme == "dark" ? "🌙" : "☀️";
|
||||||
{
|
|
||||||
"light" => "☀️",
|
|
||||||
"dark" => "🌙",
|
|
||||||
"auto" => "🔄",
|
|
||||||
_ => "🔄"
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetThemeTooltip()
|
private string GetThemeTooltip()
|
||||||
{
|
{
|
||||||
return currentTheme switch
|
return currentTheme == "dark" ? "Switch to light mode" : "Switch to dark mode";
|
||||||
{
|
|
||||||
"light" => "Switch to dark mode",
|
|
||||||
"dark" => "Switch to auto mode",
|
|
||||||
"auto" => "Switch to light mode",
|
|
||||||
_ => "Toggle theme"
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,35 +1,43 @@
|
|||||||
|
// Ultra-simple theme for iOS testing
|
||||||
window.notemarkTheme = {
|
window.notemarkTheme = {
|
||||||
|
currentTheme: 'light',
|
||||||
|
|
||||||
init: function() {
|
init: function() {
|
||||||
// Get saved theme or default to 'auto'
|
console.log('Simple theme init');
|
||||||
const savedTheme = localStorage.getItem('notemark-theme') || 'auto';
|
this.applyTheme(this.currentTheme);
|
||||||
this.applyTheme(savedTheme);
|
return this.currentTheme;
|
||||||
return savedTheme;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
setTheme: function(theme) {
|
setTheme: function(theme) {
|
||||||
localStorage.setItem('notemark-theme', theme);
|
console.log('Setting theme:', theme);
|
||||||
|
this.currentTheme = theme;
|
||||||
this.applyTheme(theme);
|
this.applyTheme(theme);
|
||||||
},
|
},
|
||||||
|
|
||||||
applyTheme: function(theme) {
|
applyTheme: function(theme) {
|
||||||
|
console.log('Applying theme:', theme);
|
||||||
const root = document.documentElement;
|
const root = document.documentElement;
|
||||||
|
|
||||||
if (theme === 'light') {
|
if (theme === 'dark') {
|
||||||
root.setAttribute('data-theme', 'light');
|
root.style.setProperty('--bg', '#1a1a1a');
|
||||||
} else if (theme === 'dark') {
|
root.style.setProperty('--surface', '#2d2d2d');
|
||||||
root.setAttribute('data-theme', 'dark');
|
root.style.setProperty('--primary-text', '#ffffff');
|
||||||
|
root.style.setProperty('--secondary-text', '#cccccc');
|
||||||
|
root.style.setProperty('--border', '#404040');
|
||||||
|
root.style.setProperty('--accent', '#007acc');
|
||||||
} else {
|
} else {
|
||||||
// For 'auto', remove data-theme to let CSS @media handle it
|
root.style.setProperty('--bg', '#ffffff');
|
||||||
root.removeAttribute('data-theme');
|
root.style.setProperty('--surface', '#f8f9fa');
|
||||||
|
root.style.setProperty('--primary-text', '#333333');
|
||||||
|
root.style.setProperty('--secondary-text', '#666666');
|
||||||
|
root.style.setProperty('--border', '#e9ecef');
|
||||||
|
root.style.setProperty('--accent', '#007acc');
|
||||||
}
|
}
|
||||||
},
|
console.log('Theme applied successfully');
|
||||||
|
|
||||||
getSystemTheme: function() {
|
|
||||||
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
|
|
||||||
},
|
},
|
||||||
|
|
||||||
getCurrentTheme: function() {
|
getCurrentTheme: function() {
|
||||||
return localStorage.getItem('notemark-theme') || 'auto';
|
return this.currentTheme;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user