mirror of
https://github.com/h3pdesign/Neon-Vision-Editor
synced 2026-04-21 13:27:16 +00:00
fix: ios toolbar alignment and release script hardening
This commit is contained in:
parent
9a7b086a74
commit
4a9064bfb5
7 changed files with 113 additions and 26 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -4,6 +4,7 @@
|
|||
# Xcode
|
||||
DerivedData/
|
||||
.DerivedData/
|
||||
DerivedData-*/
|
||||
*.xcresult
|
||||
*.xcuserstate
|
||||
*.xcuserdata/
|
||||
|
|
|
|||
|
|
@ -358,7 +358,7 @@
|
|||
CODE_SIGNING_ALLOWED = YES;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 252;
|
||||
CURRENT_PROJECT_VERSION = 253;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEVELOPMENT_TEAM = CS727NF72U;
|
||||
ENABLE_APP_SANDBOX = YES;
|
||||
|
|
@ -438,7 +438,7 @@
|
|||
CODE_SIGNING_ALLOWED = YES;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 252;
|
||||
CURRENT_PROJECT_VERSION = 253;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEVELOPMENT_TEAM = CS727NF72U;
|
||||
ENABLE_APP_SANDBOX = YES;
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@
|
|||
"appearance" : "dark",
|
||||
"value" : {
|
||||
"linear-gradient" : [
|
||||
"srgb:0.11000,0.11000,0.14000,1.00000",
|
||||
"srgb:0.02000,0.02000,0.04000,1.00000"
|
||||
"srgb:0.10980,0.10980,0.11765,1.00000",
|
||||
"srgb:0.10980,0.10980,0.11765,1.00000"
|
||||
],
|
||||
"orientation" : {
|
||||
"start" : {
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ extension ContentView {
|
|||
}
|
||||
.labelsHidden()
|
||||
.help("Language")
|
||||
.frame(width: isIPadToolbarLayout ? 160 : 120)
|
||||
.frame(width: isIPadToolbarLayout ? 160 : 98)
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
|
|
@ -184,6 +184,42 @@ extension ContentView {
|
|||
.keyboardShortcut("f", modifiers: .command)
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
private var brainDumpControl: some View {
|
||||
Button(action: {
|
||||
viewModel.isBrainDumpMode.toggle()
|
||||
UserDefaults.standard.set(viewModel.isBrainDumpMode, forKey: "BrainDumpModeEnabled")
|
||||
}) {
|
||||
Image(systemName: "note.text")
|
||||
.symbolVariant(viewModel.isBrainDumpMode ? .fill : .none)
|
||||
}
|
||||
.help("Brain Dump Mode")
|
||||
.accessibilityLabel("Brain Dump Mode")
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
private var welcomeTourControl: some View {
|
||||
Button(action: {
|
||||
showWelcomeTour = true
|
||||
}) {
|
||||
Image(systemName: "sparkles.rectangle.stack")
|
||||
}
|
||||
.help("Welcome Tour")
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
private var translucentWindowControl: some View {
|
||||
Button(action: {
|
||||
enableTranslucentWindow.toggle()
|
||||
UserDefaults.standard.set(enableTranslucentWindow, forKey: "EnableTranslucentWindow")
|
||||
NotificationCenter.default.post(name: .toggleTranslucencyRequested, object: enableTranslucentWindow)
|
||||
}) {
|
||||
Image(systemName: enableTranslucentWindow ? "rectangle.fill" : "rectangle")
|
||||
}
|
||||
.help("Toggle Translucent Window Background")
|
||||
.accessibilityLabel("Translucent Window Background")
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
private var iPadPromotedActions: some View {
|
||||
if iPadPromotedActionsCount >= 1 { openFileControl }
|
||||
|
|
@ -198,6 +234,18 @@ extension ContentView {
|
|||
@ViewBuilder
|
||||
private var moreActionsControl: some View {
|
||||
Menu {
|
||||
Button(action: {
|
||||
showSettingsSheet = true
|
||||
}) {
|
||||
Label("Settings", systemImage: "gearshape")
|
||||
}
|
||||
|
||||
Button(action: {
|
||||
requestClearEditorContent()
|
||||
}) {
|
||||
Label("Clear Editor", systemImage: "trash")
|
||||
}
|
||||
|
||||
Button(action: { insertTemplateForCurrentLanguage() }) {
|
||||
Label("Insert Template", systemImage: "doc.badge.plus")
|
||||
}
|
||||
|
|
@ -261,15 +309,9 @@ extension ContentView {
|
|||
|
||||
@ViewBuilder
|
||||
private var iOSToolbarControls: some View {
|
||||
languagePickerControl
|
||||
newTabControl
|
||||
openFileControl
|
||||
saveFileControl
|
||||
findReplaceControl
|
||||
activeProviderBadgeControl
|
||||
clearEditorControl
|
||||
settingsControl
|
||||
moreActionsControl
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
|
|
@ -288,15 +330,19 @@ extension ContentView {
|
|||
@ToolbarContentBuilder
|
||||
var editorToolbarContent: some ToolbarContent {
|
||||
#if os(iOS)
|
||||
ToolbarItemGroup(placement: .topBarTrailing) {
|
||||
HStack(spacing: 14) {
|
||||
if isIPadToolbarLayout {
|
||||
if isIPadToolbarLayout {
|
||||
ToolbarItemGroup(placement: .topBarTrailing) {
|
||||
HStack(spacing: 14) {
|
||||
iPadDistributedToolbarControls
|
||||
} else {
|
||||
iOSToolbarControls
|
||||
}
|
||||
.frame(maxWidth: iPadToolbarMaxWidth, alignment: .trailing)
|
||||
}
|
||||
} else {
|
||||
ToolbarItemGroup(placement: .topBarTrailing) {
|
||||
languagePickerControl
|
||||
iOSToolbarControls
|
||||
moreActionsControl
|
||||
}
|
||||
.frame(maxWidth: isIPadToolbarLayout ? iPadToolbarMaxWidth : .infinity, alignment: .trailing)
|
||||
}
|
||||
#else
|
||||
ToolbarItemGroup(placement: .automatic) {
|
||||
|
|
|
|||
|
|
@ -564,11 +564,11 @@ func currentEditorTheme(colorScheme: ColorScheme) -> EditorTheme {
|
|||
comment: comment,
|
||||
attribute: property,
|
||||
variable: property,
|
||||
def: keyword,
|
||||
def: type,
|
||||
property: property,
|
||||
meta: builtin,
|
||||
tag: keyword,
|
||||
atom: number,
|
||||
atom: builtin,
|
||||
builtin: builtin,
|
||||
type: type
|
||||
)
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ usage() {
|
|||
Run end-to-end release flow in one command.
|
||||
|
||||
Usage:
|
||||
scripts/release_all.sh <tag> [notarized] [--date YYYY-MM-DD] [--skip-notarized] [--self-hosted] [--github-hosted] [--enterprise-selfhosted] [--dry-run]
|
||||
scripts/release_all.sh <tag> [notarized] [--date YYYY-MM-DD] [--skip-notarized] [--self-hosted] [--github-hosted] [--enterprise-selfhosted] [--autostash] [--dry-run]
|
||||
|
||||
Examples:
|
||||
scripts/release_all.sh v0.4.9
|
||||
|
|
@ -15,6 +15,7 @@ Examples:
|
|||
scripts/release_all.sh v0.4.9 --self-hosted
|
||||
scripts/release_all.sh v0.4.9 --enterprise-selfhosted
|
||||
scripts/release_all.sh v0.4.9 --github-hosted
|
||||
scripts/release_all.sh v0.4.9 --autostash
|
||||
scripts/release_all.sh v0.4.9 --dry-run
|
||||
|
||||
What it does:
|
||||
|
|
@ -46,6 +47,7 @@ DATE_ARG=()
|
|||
TRIGGER_NOTARIZED=1
|
||||
USE_SELF_HOSTED=0
|
||||
ENTERPRISE_SELF_HOSTED=0
|
||||
AUTOSTASH=0
|
||||
DRY_RUN=0
|
||||
|
||||
while [[ "${1:-}" != "" ]]; do
|
||||
|
|
@ -74,6 +76,9 @@ while [[ "${1:-}" != "" ]]; do
|
|||
ENTERPRISE_SELF_HOSTED=1
|
||||
USE_SELF_HOSTED=1
|
||||
;;
|
||||
--autostash)
|
||||
AUTOSTASH=1
|
||||
;;
|
||||
--dry-run)
|
||||
DRY_RUN=1
|
||||
;;
|
||||
|
|
@ -91,6 +96,35 @@ if ! command -v gh >/dev/null 2>&1; then
|
|||
exit 1
|
||||
fi
|
||||
|
||||
if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
||||
echo "This command must run inside a git repository." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ROOT="$(git rev-parse --show-toplevel)"
|
||||
cd "$ROOT"
|
||||
|
||||
AUTO_STASHED=0
|
||||
cleanup_autostash() {
|
||||
if [[ "$AUTO_STASHED" -eq 1 ]]; then
|
||||
if git stash pop --index >/dev/null 2>&1; then
|
||||
echo "Restored stashed working tree changes."
|
||||
else
|
||||
echo "Auto-stash restore had conflicts. Changes remain in stash list; resolve manually." >&2
|
||||
fi
|
||||
fi
|
||||
}
|
||||
trap cleanup_autostash EXIT
|
||||
|
||||
if [[ "$AUTOSTASH" -eq 1 ]]; then
|
||||
if [[ -n "$(git status --porcelain)" ]]; then
|
||||
STASH_MSG="release_all autostash ${TAG} $(date +%Y-%m-%dT%H:%M:%S)"
|
||||
git stash push --include-untracked -m "$STASH_MSG" >/dev/null
|
||||
AUTO_STASHED=1
|
||||
echo "Auto-stashed dirty working tree before release."
|
||||
fi
|
||||
fi
|
||||
|
||||
wait_for_pre_release_ci() {
|
||||
local sha="$1"
|
||||
local timeout_seconds=1800
|
||||
|
|
@ -133,6 +167,11 @@ wait_for_pre_release_ci() {
|
|||
return 1
|
||||
}
|
||||
|
||||
if [[ "$AUTOSTASH" -eq 0 && -n "$(git status --porcelain)" ]]; then
|
||||
echo "Working tree is not clean. Commit/stash changes first, or rerun with --autostash." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Verifying release docs are up to date for ${TAG}..."
|
||||
docs_check_cmd=(scripts/prepare_release_docs.py "$TAG" --check)
|
||||
if [[ ${#DATE_ARG[@]} -gt 0 ]]; then
|
||||
|
|
|
|||
|
|
@ -80,22 +80,23 @@ if [[ ! -f "$PBXPROJ_FILE" ]]; then
|
|||
echo "Missing ${PBXPROJ_FILE}; cannot validate MARKETING_VERSION." >&2
|
||||
exit 1
|
||||
fi
|
||||
CURRENT_VERSION="$(
|
||||
MARKETING_VERSIONS="$(
|
||||
if command -v rg >/dev/null 2>&1; then
|
||||
rg --no-filename --only-matching 'MARKETING_VERSION = [0-9]+\.[0-9]+\.[0-9]+' "$PBXPROJ_FILE"
|
||||
else
|
||||
grep -Eo 'MARKETING_VERSION = [0-9]+\.[0-9]+\.[0-9]+' "$PBXPROJ_FILE"
|
||||
fi \
|
||||
| awk '{print $3}' \
|
||||
| sort -u \
|
||||
| head -n1
|
||||
| sort -u
|
||||
)"
|
||||
if [[ -z "${CURRENT_VERSION}" ]]; then
|
||||
if [[ -z "${MARKETING_VERSIONS}" ]]; then
|
||||
echo "Could not read MARKETING_VERSION from ${PBXPROJ_FILE}." >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ "$CURRENT_VERSION" != "$EXPECTED_VERSION" ]]; then
|
||||
echo "Version mismatch: tag ${TAG} requires MARKETING_VERSION ${EXPECTED_VERSION}, found ${CURRENT_VERSION}." >&2
|
||||
if ! printf '%s\n' "$MARKETING_VERSIONS" | grep -Fxq "$EXPECTED_VERSION"; then
|
||||
echo "Version mismatch: tag ${TAG} requires MARKETING_VERSION ${EXPECTED_VERSION}." >&2
|
||||
echo "Found MARKETING_VERSION values:" >&2
|
||||
printf ' - %s\n' $MARKETING_VERSIONS >&2
|
||||
echo "Update MARKETING_VERSION or use a matching tag before running release." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
|
|
|||
Loading…
Reference in a new issue