mirror of
https://github.com/jamescliffordspratt/macros.git
synced 2026-07-22 05:46:53 +00:00
fix: prevent mobile redirect when opening meal template modals from settings
This commit is contained in:
parent
88d0c75d31
commit
4a69e84e98
5 changed files with 205 additions and 34 deletions
|
|
@ -17,6 +17,9 @@
|
|||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "MIT",
|
||||
"standard-version": {
|
||||
"tagPrefix": ""
|
||||
},
|
||||
"devDependencies": {
|
||||
"@testing-library/dom": "^10.4.0",
|
||||
"@types/jest": "^29.5.14",
|
||||
|
|
|
|||
206
release.ps1
206
release.ps1
|
|
@ -1,63 +1,211 @@
|
|||
<#
|
||||
.SYNOPSIS
|
||||
Bumps the plugin version and triggers an automated GitHub release.
|
||||
|
||||
.DESCRIPTION
|
||||
Runs type checking, bumps the version using standard-version (which also
|
||||
updates CHANGELOG.md and creates a git tag), syncs the version to
|
||||
manifest.json, then pushes. The tag push triggers GitHub Actions to build
|
||||
the plugin and publish the release automatically.
|
||||
|
||||
.PARAMETER Bump
|
||||
Version bump type: patch, minor, or major (default: patch)
|
||||
patch x.x.X Bug fixes, small improvements
|
||||
minor x.X.0 New features (backward compatible)
|
||||
major X.0.0 Breaking changes
|
||||
Interactive release script for the Macros Obsidian plugin.
|
||||
Stages changes, commits, bumps version, and pushes — triggering
|
||||
an automated GitHub Actions release.
|
||||
|
||||
.EXAMPLE
|
||||
.\release.ps1
|
||||
.\release.ps1 minor
|
||||
.\release.ps1 -Bump major
|
||||
#>
|
||||
param(
|
||||
[ValidateSet("patch", "minor", "major")]
|
||||
[string]$Bump = "patch"
|
||||
)
|
||||
|
||||
Set-StrictMode -Version Latest
|
||||
$ErrorActionPreference = "Stop"
|
||||
Set-Location $PSScriptRoot
|
||||
|
||||
# ── Helpers ─────────────────────────────────────────────────────────────────
|
||||
|
||||
function Header([string]$msg) {
|
||||
Write-Host ""
|
||||
Write-Host " $msg" -ForegroundColor White
|
||||
Write-Host (" " + ("─" * $msg.Length)) -ForegroundColor DarkGray
|
||||
}
|
||||
|
||||
function Step([string]$msg) {
|
||||
Write-Host "`n→ $msg" -ForegroundColor Cyan
|
||||
}
|
||||
|
||||
function Ok([string]$msg) {
|
||||
Write-Host " ✓ $msg" -ForegroundColor Green
|
||||
}
|
||||
|
||||
function Warn([string]$msg) {
|
||||
Write-Host " ! $msg" -ForegroundColor Yellow
|
||||
}
|
||||
|
||||
function Fail([string]$msg) {
|
||||
Write-Host "`n✗ $msg" -ForegroundColor Red
|
||||
Write-Host "`n ✗ $msg" -ForegroundColor Red
|
||||
Write-Host ""
|
||||
Read-Host " Press Enter to exit"
|
||||
exit 1
|
||||
}
|
||||
|
||||
function Prompt([string]$msg) {
|
||||
Write-Host " $msg" -ForegroundColor Gray -NoNewline
|
||||
return (Read-Host " ")
|
||||
}
|
||||
|
||||
function Menu([string]$title, [string[]]$options, [string[]]$descriptions, [int]$default = 0) {
|
||||
Write-Host ""
|
||||
Write-Host " $title" -ForegroundColor White
|
||||
for ($i = 0; $i -lt $options.Length; $i++) {
|
||||
$marker = if ($i -eq $default) { "▶" } else { " " }
|
||||
$num = $i + 1
|
||||
Write-Host " $marker [$num] $($options[$i])" -ForegroundColor $(if ($i -eq $default) { "Cyan" } else { "Gray" })
|
||||
Write-Host " $($descriptions[$i])" -ForegroundColor DarkGray
|
||||
}
|
||||
Write-Host ""
|
||||
$choice = Prompt "Choose (1-$($options.Length)) [default: $($default+1)]"
|
||||
if ([string]::IsNullOrWhiteSpace($choice)) { return $default }
|
||||
$idx = [int]$choice - 1
|
||||
if ($idx -lt 0 -or $idx -ge $options.Length) { return $default }
|
||||
return $idx
|
||||
}
|
||||
|
||||
# ── Banner ───────────────────────────────────────────────────────────────────
|
||||
|
||||
Clear-Host
|
||||
Write-Host ""
|
||||
Write-Host " ╔══════════════════════════════════════╗" -ForegroundColor DarkCyan
|
||||
Write-Host " ║ Macros Plugin Release Script ║" -ForegroundColor Cyan
|
||||
Write-Host " ╚══════════════════════════════════════╝" -ForegroundColor DarkCyan
|
||||
|
||||
# ── Check git status ─────────────────────────────────────────────────────────
|
||||
|
||||
Header "Changed files"
|
||||
|
||||
$status = git status --short
|
||||
if ([string]::IsNullOrWhiteSpace($status)) {
|
||||
Warn "No changes detected. Nothing to commit."
|
||||
Write-Host ""
|
||||
Read-Host " Press Enter to exit"
|
||||
exit 0
|
||||
}
|
||||
|
||||
$status -split "`n" | ForEach-Object {
|
||||
if ($_.Trim()) { Write-Host " $_" -ForegroundColor DarkGray }
|
||||
}
|
||||
|
||||
# ── Commit type ──────────────────────────────────────────────────────────────
|
||||
|
||||
$typeIdx = Menu "Commit type" `
|
||||
@("feat", "fix", "chore", "docs", "refactor", "perf", "test") `
|
||||
@(
|
||||
"New feature or capability → bumps MINOR version",
|
||||
"Bug fix or correction → bumps PATCH version",
|
||||
"Maintenance, deps, tooling → bumps PATCH version",
|
||||
"Documentation only → bumps PATCH version",
|
||||
"Code restructure, no behaviour change → bumps PATCH version",
|
||||
"Performance improvement → bumps PATCH version",
|
||||
"Adding or fixing tests → bumps PATCH version"
|
||||
)
|
||||
|
||||
$types = @("feat", "fix", "chore", "docs", "refactor", "perf", "test")
|
||||
$commitType = $types[$typeIdx]
|
||||
|
||||
# ── Commit description ───────────────────────────────────────────────────────
|
||||
|
||||
Header "Commit message"
|
||||
$subject = ""
|
||||
while ([string]::IsNullOrWhiteSpace($subject)) {
|
||||
$subject = Prompt "Short description (e.g. 'add weekly summary view')"
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
Write-Host " Optional: add a longer body (press Enter to skip)" -ForegroundColor Gray
|
||||
Write-Host " You can paste multiple lines. Enter a blank line when done." -ForegroundColor DarkGray
|
||||
Write-Host ""
|
||||
$bodyLines = @()
|
||||
while ($true) {
|
||||
$line = Prompt " >"
|
||||
if ([string]::IsNullOrWhiteSpace($line)) { break }
|
||||
$bodyLines += $line
|
||||
}
|
||||
|
||||
$commitMsg = "${commitType}: ${subject}"
|
||||
if ($bodyLines.Count -gt 0) {
|
||||
$commitMsg += "`n`n" + ($bodyLines -join "`n")
|
||||
}
|
||||
|
||||
# ── Breaking change? ─────────────────────────────────────────────────────────
|
||||
|
||||
$breaking = Prompt "Breaking change? (y/N)"
|
||||
if ($breaking -match "^[Yy]") {
|
||||
$breakingDesc = Prompt "Describe the breaking change"
|
||||
$commitMsg += "`n`nBREAKING CHANGE: $breakingDesc"
|
||||
}
|
||||
|
||||
# ── Version bump ─────────────────────────────────────────────────────────────
|
||||
|
||||
$defaultBump = if ($commitType -eq "feat" -or $breaking -match "^[Yy]") { 1 } else { 0 }
|
||||
if ($breaking -match "^[Yy]") { $defaultBump = 2 }
|
||||
|
||||
$bumpIdx = Menu "Version bump" `
|
||||
@("patch", "minor", "major") `
|
||||
@(
|
||||
"x.x.X Bug fixes, maintenance, small improvements",
|
||||
"x.X.0 New features (backward compatible)",
|
||||
"X.0.0 Breaking changes"
|
||||
) `
|
||||
$defaultBump
|
||||
|
||||
$bumps = @("patch", "minor", "major")
|
||||
$bump = $bumps[$bumpIdx]
|
||||
|
||||
# ── Confirm ───────────────────────────────────────────────────────────────────
|
||||
|
||||
$currentVersion = node -p "require('./package.json').version"
|
||||
Header "Ready to release"
|
||||
Write-Host " Commit : $commitMsg" -ForegroundColor White
|
||||
Write-Host " Bump : $bump ($currentVersion → next $bump)" -ForegroundColor White
|
||||
Write-Host ""
|
||||
$confirm = Prompt "Proceed? (Y/n)"
|
||||
if ($confirm -match "^[Nn]") {
|
||||
Write-Host "`n Aborted." -ForegroundColor Yellow
|
||||
exit 0
|
||||
}
|
||||
|
||||
# ── Execute ───────────────────────────────────────────────────────────────────
|
||||
|
||||
Step "Staging all changes..."
|
||||
git add .
|
||||
Ok "Staged"
|
||||
|
||||
Step "Committing..."
|
||||
git commit -m $commitMsg
|
||||
if ($LASTEXITCODE -ne 0) { Fail "Commit failed." }
|
||||
Ok "Committed"
|
||||
|
||||
Step "Type checking..."
|
||||
npm run typecheck
|
||||
if ($LASTEXITCODE -ne 0) { Fail "Type check failed. Fix errors before releasing." }
|
||||
Ok "Types OK"
|
||||
|
||||
Step "Bumping version ($Bump) and updating CHANGELOG.md..."
|
||||
npx standard-version --release-as $Bump
|
||||
Step "Bumping version ($bump) and updating CHANGELOG..."
|
||||
npx standard-version --release-as $bump
|
||||
if ($LASTEXITCODE -ne 0) { Fail "Version bump failed." }
|
||||
|
||||
Step "Syncing version to manifest.json..."
|
||||
node sync-version.js
|
||||
if ($LASTEXITCODE -ne 0) { Fail "Version sync failed." }
|
||||
|
||||
git add manifest.json
|
||||
git commit -m "chore: sync version to manifest" --no-verify
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Host " (nothing to commit — manifest already in sync)" -ForegroundColor DarkGray
|
||||
$syncResult = git commit -m "chore: sync version to manifest" --no-verify 2>&1
|
||||
if ($LASTEXITCODE -ne 0 -and $syncResult -notmatch "nothing to commit") {
|
||||
Warn "manifest sync commit skipped (already in sync)"
|
||||
} else {
|
||||
Ok "manifest.json synced"
|
||||
}
|
||||
|
||||
Step "Pushing to GitHub..."
|
||||
git push --follow-tags origin main
|
||||
if ($LASTEXITCODE -ne 0) { Fail "Push failed." }
|
||||
|
||||
$version = node -p "require('./package.json').version"
|
||||
Write-Host "`n✓ v$version pushed. GitHub Actions will build and publish the release." -ForegroundColor Green
|
||||
Write-Host " Track progress at: https://github.com/JamesCliffordSpratt/macros/actions" -ForegroundColor DarkGray
|
||||
$newVersion = node -p "require('./package.json').version"
|
||||
Write-Host ""
|
||||
Write-Host " ╔══════════════════════════════════════╗" -ForegroundColor DarkGreen
|
||||
Write-Host " ║ Release v$newVersion complete!$(if($newVersion.Length -lt 6){' '}elseif($newVersion.Length -lt 7){' '}else{' '})║" -ForegroundColor Green
|
||||
Write-Host " ╚══════════════════════════════════════╝" -ForegroundColor DarkGreen
|
||||
Write-Host ""
|
||||
Write-Host " GitHub Actions is now building and publishing the release." -ForegroundColor Gray
|
||||
Write-Host " Track: https://github.com/JamesCliffordSpratt/macros/actions" -ForegroundColor DarkGray
|
||||
Write-Host ""
|
||||
Read-Host " Press Enter to close"
|
||||
|
|
|
|||
|
|
@ -1276,7 +1276,8 @@ export class NutritionalSettingTab extends PluginSettingTab {
|
|||
.setName(t('settings.meals.create'))
|
||||
.setDesc(t('settings.meals.createDesc'))
|
||||
.addButton((btn) => {
|
||||
btn.setButtonText(t('settings.meals.addButton')).onClick(() => {
|
||||
btn.setButtonText(t('settings.meals.addButton')).onClick((evt) => {
|
||||
evt.preventDefault();
|
||||
new AddMealTemplateModal(this.plugin).open();
|
||||
});
|
||||
});
|
||||
|
|
@ -1296,7 +1297,8 @@ export class NutritionalSettingTab extends PluginSettingTab {
|
|||
editBtn
|
||||
.setButtonText(t('general.edit'))
|
||||
.setCta()
|
||||
.onClick(() => {
|
||||
.onClick((evt) => {
|
||||
evt.preventDefault();
|
||||
new EditMealTemplateModal(this.plugin, meal).open();
|
||||
});
|
||||
})
|
||||
|
|
|
|||
|
|
@ -262,6 +262,7 @@ export class AddMealTemplateModal extends Modal {
|
|||
const removeButton = buttonContainer.createEl('button', {
|
||||
text: t('meals.create.remove'),
|
||||
cls: 'remove-button',
|
||||
attr: { type: 'button' },
|
||||
});
|
||||
|
||||
// Edit serving button (if nutrition data available)
|
||||
|
|
@ -269,6 +270,7 @@ export class AddMealTemplateModal extends Modal {
|
|||
const editButton = buttonContainer.createEl('button', {
|
||||
text: t('meals.create.editServing'),
|
||||
cls: 'edit-button',
|
||||
attr: { type: 'button' },
|
||||
});
|
||||
|
||||
this.component.registerDomEvent(editButton, 'click', () => {
|
||||
|
|
@ -286,6 +288,7 @@ export class AddMealTemplateModal extends Modal {
|
|||
const addButton = buttonContainer.createEl('button', {
|
||||
text: t('meals.create.addToMeal'),
|
||||
cls: 'add-button',
|
||||
attr: { type: 'button' },
|
||||
});
|
||||
|
||||
this.component.registerDomEvent(addButton, 'click', () => {
|
||||
|
|
@ -382,6 +385,7 @@ export class AddMealTemplateModal extends Modal {
|
|||
const removeButton = itemTag.createEl('button', {
|
||||
text: '×',
|
||||
cls: 'remove-item-button',
|
||||
attr: { type: 'button' },
|
||||
});
|
||||
|
||||
this.component.registerDomEvent(removeButton, 'click', () => {
|
||||
|
|
@ -415,11 +419,13 @@ export class AddMealTemplateModal extends Modal {
|
|||
const cancelButton = buttonContainer.createEl('button', {
|
||||
text: t('general.cancel'),
|
||||
cls: 'cancel-button',
|
||||
attr: { type: 'button' },
|
||||
});
|
||||
|
||||
this.createButton = buttonContainer.createEl('button', {
|
||||
text: t('meals.create.create'),
|
||||
cls: 'create-button disabled',
|
||||
attr: { type: 'button' },
|
||||
});
|
||||
|
||||
(this.createButton as HTMLButtonElement).disabled = true;
|
||||
|
|
@ -712,6 +718,7 @@ export class EditMealTemplateModal extends Modal {
|
|||
const removeButton = buttonContainer.createEl('button', {
|
||||
text: t('meals.create.remove'),
|
||||
cls: 'remove-button',
|
||||
attr: { type: 'button' },
|
||||
});
|
||||
|
||||
// Edit serving button (if nutrition data available)
|
||||
|
|
@ -719,6 +726,7 @@ export class EditMealTemplateModal extends Modal {
|
|||
const editButton = buttonContainer.createEl('button', {
|
||||
text: t('meals.create.editServing'),
|
||||
cls: 'edit-button',
|
||||
attr: { type: 'button' },
|
||||
});
|
||||
|
||||
this.component.registerDomEvent(editButton, 'click', () => {
|
||||
|
|
@ -736,6 +744,7 @@ export class EditMealTemplateModal extends Modal {
|
|||
const addButton = buttonContainer.createEl('button', {
|
||||
text: t('meals.create.addToMeal'),
|
||||
cls: 'add-button',
|
||||
attr: { type: 'button' },
|
||||
});
|
||||
|
||||
this.component.registerDomEvent(addButton, 'click', () => {
|
||||
|
|
@ -857,6 +866,7 @@ export class EditMealTemplateModal extends Modal {
|
|||
const removeButton = itemTag.createEl('button', {
|
||||
text: '×',
|
||||
cls: 'remove-item-button',
|
||||
attr: { type: 'button' },
|
||||
});
|
||||
|
||||
this.component.registerDomEvent(removeButton, 'click', () => {
|
||||
|
|
@ -886,11 +896,13 @@ export class EditMealTemplateModal extends Modal {
|
|||
const cancelButton = buttonContainer.createEl('button', {
|
||||
text: t('general.cancel'),
|
||||
cls: 'cancel-button',
|
||||
attr: { type: 'button' },
|
||||
});
|
||||
|
||||
this.saveButton = buttonContainer.createEl('button', {
|
||||
text: t('meals.edit.saveChanges'),
|
||||
cls: 'save-button',
|
||||
attr: { type: 'button' },
|
||||
});
|
||||
|
||||
this.component.registerDomEvent(cancelButton, 'click', () => {
|
||||
|
|
|
|||
|
|
@ -240,6 +240,7 @@ export class EditMealTemplateModal extends Modal {
|
|||
const removeButton = buttonContainer.createEl('button', {
|
||||
text: t('meals.create.remove'),
|
||||
cls: 'remove-button',
|
||||
attr: { type: 'button' },
|
||||
});
|
||||
|
||||
// Edit serving button (if nutrition data available)
|
||||
|
|
@ -247,7 +248,8 @@ export class EditMealTemplateModal extends Modal {
|
|||
const editButton = buttonContainer.createEl('button', {
|
||||
text: t('meals.create.editServing'),
|
||||
cls: 'edit-button',
|
||||
});
|
||||
attr: { type: 'button' },
|
||||
});
|
||||
|
||||
this.component.registerDomEvent(editButton, 'click', () => {
|
||||
this.editFoodServing(food);
|
||||
|
|
@ -264,6 +266,7 @@ export class EditMealTemplateModal extends Modal {
|
|||
const addButton = buttonContainer.createEl('button', {
|
||||
text: t('meals.create.addToMeal'),
|
||||
cls: 'add-button',
|
||||
attr: { type: 'button' },
|
||||
});
|
||||
|
||||
this.component.registerDomEvent(addButton, 'click', () => {
|
||||
|
|
@ -385,6 +388,7 @@ export class EditMealTemplateModal extends Modal {
|
|||
const removeButton = itemTag.createEl('button', {
|
||||
text: '×',
|
||||
cls: 'remove-item-button',
|
||||
attr: { type: 'button' },
|
||||
});
|
||||
|
||||
this.component.registerDomEvent(removeButton, 'click', () => {
|
||||
|
|
@ -414,12 +418,14 @@ export class EditMealTemplateModal extends Modal {
|
|||
const cancelButton = buttonContainer.createEl('button', {
|
||||
text: t('general.cancel'),
|
||||
cls: 'cancel-button',
|
||||
});
|
||||
attr: { type: 'button' },
|
||||
});
|
||||
|
||||
this.saveButton = buttonContainer.createEl('button', {
|
||||
text: t('meals.edit.saveChanges'),
|
||||
cls: 'save-button',
|
||||
});
|
||||
attr: { type: 'button' },
|
||||
});
|
||||
|
||||
this.component.registerDomEvent(cancelButton, 'click', () => {
|
||||
this.close();
|
||||
|
|
|
|||
Loading…
Reference in a new issue