Compare commits
2 Commits
708819629a
...
06e5bd7f46
| Author | SHA1 | Date | |
|---|---|---|---|
| 06e5bd7f46 | |||
| a039c0d401 |
@@ -793,3 +793,15 @@ History search guidance:
|
|||||||
158 - [2026-05-18 23:03:13] - v1.27.0-dev-169-g69356f6de0 - Type: Modified - [repo-diff] [sticky-ui] [navbar] Prevented sticky diff headers from sliding under the persistent navigation bar.
|
158 - [2026-05-18 23:03:13] - v1.27.0-dev-169-g69356f6de0 - Type: Modified - [repo-diff] [sticky-ui] [navbar] Prevented sticky diff headers from sliding under the persistent navigation bar.
|
||||||
- 1 - I updated `web_src/css/repo.css` so the sticky repository diff summary bar, the sticky second-row file headers, and the diff file scroll anchor margin now all include `--persistent-navbar-offset`, keeping them visible below the navbar when `Keep the navigation bar visible while scrolling` is enabled.
|
- 1 - I updated `web_src/css/repo.css` so the sticky repository diff summary bar, the sticky second-row file headers, and the diff file scroll anchor margin now all include `--persistent-navbar-offset`, keeping them visible below the navbar when `Keep the navigation bar visible while scrolling` is enabled.
|
||||||
- 2 - I extended the same offset handling to `#diff-file-tree` so the sticky diff file tree no longer slides under the diff summary bar after the persistent-navbar preference shifts the sticky stack downward.
|
- 2 - I extended the same offset handling to `#diff-file-tree` so the sticky diff file tree no longer slides under the diff summary bar after the persistent-navbar preference shifts the sticky stack downward.
|
||||||
|
|
||||||
|
159 - [2026-05-19 01:10:25] - v1.27.0-dev-171-gc40e1cf08f - Type: Modified - [navbar] [sticky-ui] [user-settings] Added a show/hide toggle tab for the persistent navigation bar.
|
||||||
|
- 1 - I updated `templates/base/head_navbar.tmpl`, `web_src/css/modules/navbar.css`, and `web_src/css/modules/flexcontainer.css` so pages with `Keep the navigation bar visible while scrolling` now show a small bottom-right toggle tab that collapses the sticky navbar to a minimal visible handle and restores it on demand while keeping sticky offsets aligned.
|
||||||
|
- 2 - I updated `web_src/js/features/common-page.ts` so the toggle state is applied on page load and stored in local user settings under `persistent-navbar-collapsed`, preserving the chosen shown/hidden state across navigation.
|
||||||
|
- 3 - I added the new show/hide navbar labels to `options/locale/locale_en-US.json` and `options/locale/locale_ro-RO.json`.
|
||||||
|
- 4 - I refined the navbar toggle geometry in `web_src/css/modules/navbar.css` and `web_src/css/modules/flexcontainer.css` so the handle now sits like a slim tab just below the navbar border, is pushed closer to the right edge, and leaves only the handle visible when the persistent navbar is collapsed.
|
||||||
|
|
||||||
|
160 - [2026-05-19 21:31:45] - v1.27.0-dev-172-g3a6684178a - Type: Modified - [scripts] [smart-build] [darwin] Added macOS amd64/arm64 smart-build support, including SQLite-aware Docker-host handling for containerized workspaces.
|
||||||
|
- 1 - I updated `smart-build.sh` so its interactive architecture menu now offers `macos-amd64`, `macos-arm64`, and includes both Darwin targets in `All Arch`, while preserving the existing `darwin` artifact naming in `dist/`.
|
||||||
|
- 2 - I added a dedicated Darwin SQLite build path in `smart-build.sh` that routes macOS `bindata sqlite sqlite_unlock_notify` builds through `make release-darwin`, and I updated `Makefile` to make `release-darwin` configurable through `DARWIN_ARCHS` so helper scripts can request only `darwin-10.12/amd64` or `darwin-10.12/arm64`.
|
||||||
|
- 3 - I hardened the Darwin SQLite flow in `smart-build.sh` for `code-server`-style containerized workspaces by distinguishing between a missing Docker CLI and an unreachable Docker daemon, by validating that the host Docker daemon can see the same mounted repository `go.mod` path as the current workspace, and by moving the temporary release output under `dist/` instead of `/tmp`.
|
||||||
|
- 4 - I added `SMART_BUILD_DARWIN_HOST_REPO_PATH` support to `smart-build.sh` so Darwin SQLite builds can be redirected to a host-visible repository mount path when the interactive workspace path inside the container differs from the real host path used by the Docker daemon.
|
||||||
|
|||||||
+149
-20
@@ -16,6 +16,73 @@ resolve_build_ref() {
|
|||||||
git describe --tags --exact-match 2>/dev/null || git describe --tags --always
|
git describe --tags --exact-match 2>/dev/null || git describe --tags --always
|
||||||
}
|
}
|
||||||
|
|
||||||
|
require_docker_for_darwin_sqlite() {
|
||||||
|
if ! command -v docker > /dev/null 2>&1; then
|
||||||
|
echo "❌ Docker is required for macOS SQLite cross-builds."
|
||||||
|
echo " Install the Docker CLI in this environment, or use the non-SQLite macOS build option."
|
||||||
|
echo " If you are running inside a code-server container, also mount the host Docker socket."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! docker info > /dev/null 2>&1; then
|
||||||
|
echo "❌ Docker is installed but the daemon is not reachable."
|
||||||
|
echo " Start Docker, or expose the host Docker daemon to this container."
|
||||||
|
echo " For a code-server container, mount /var/run/docker.sock from the host."
|
||||||
|
if [ -n "${DOCKER_HOST:-}" ]; then
|
||||||
|
echo " Current DOCKER_HOST: ${DOCKER_HOST}"
|
||||||
|
else
|
||||||
|
echo " Current DOCKER_HOST is unset."
|
||||||
|
fi
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve_xgo_image() {
|
||||||
|
local xgo_version
|
||||||
|
|
||||||
|
xgo_version="$(awk '$1 == "XGO_VERSION" { print $3; exit }' Makefile 2>/dev/null)"
|
||||||
|
if [ -z "$xgo_version" ]; then
|
||||||
|
xgo_version="go-1.25.x"
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf 'ghcr.io/techknowlogick/xgo:%s' "$xgo_version"
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve_darwin_sqlite_repo_root() {
|
||||||
|
local override_path
|
||||||
|
|
||||||
|
override_path="${SMART_BUILD_DARWIN_HOST_REPO_PATH:-}"
|
||||||
|
if [ -z "$override_path" ]; then
|
||||||
|
pwd -P
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -d "$override_path" ] || [ ! -f "$override_path/go.mod" ]; then
|
||||||
|
echo "❌ SMART_BUILD_DARWIN_HOST_REPO_PATH is set, but the path is not usable in this container:"
|
||||||
|
echo " $override_path"
|
||||||
|
echo " Mount the host repository path into the container at the same absolute path, then retry."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf '%s' "$override_path"
|
||||||
|
}
|
||||||
|
|
||||||
|
validate_repo_bind_mount_for_darwin_sqlite() {
|
||||||
|
local repo_path="$1"
|
||||||
|
local xgo_image
|
||||||
|
|
||||||
|
xgo_image="$(resolve_xgo_image)"
|
||||||
|
|
||||||
|
if ! docker run --rm -v "$repo_path":/probe:ro --entrypoint sh "$xgo_image" -lc 'test -f /probe/go.mod'; then
|
||||||
|
echo "❌ Docker can reach the daemon, but the daemon cannot mount this repository path correctly:"
|
||||||
|
echo " $repo_path"
|
||||||
|
echo " The xgo container only sees an empty or different host path, so /source/go.mod is missing there."
|
||||||
|
echo " If smart-build runs inside a code-server container with the host Docker socket,"
|
||||||
|
echo " the repository must be mounted from a host bind path that exists at the same absolute path."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
write_sha256_file() {
|
write_sha256_file() {
|
||||||
local artifact_path="$1"
|
local artifact_path="$1"
|
||||||
local artifact_dir artifact_name
|
local artifact_dir artifact_name
|
||||||
@@ -169,7 +236,7 @@ fi
|
|||||||
echo ""
|
echo ""
|
||||||
echo "🎯 Select Arch to build:"
|
echo "🎯 Select Arch to build:"
|
||||||
notify_human_interaction
|
notify_human_interaction
|
||||||
arch_options=("linux-amd64" "linux-armv7" "windows-amd64" "All Arch" "Quit")
|
arch_options=("linux-amd64" "linux-armv7" "windows-amd64" "macos-amd64" "macos-arm64" "All Arch" "Quit")
|
||||||
select opt in "${arch_options[@]}"
|
select opt in "${arch_options[@]}"
|
||||||
do
|
do
|
||||||
case $opt in
|
case $opt in
|
||||||
@@ -185,8 +252,16 @@ do
|
|||||||
TARGETS=("windows/amd64")
|
TARGETS=("windows/amd64")
|
||||||
break
|
break
|
||||||
;;
|
;;
|
||||||
|
"macos-amd64")
|
||||||
|
TARGETS=("darwin/amd64")
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
"macos-arm64")
|
||||||
|
TARGETS=("darwin/arm64")
|
||||||
|
break
|
||||||
|
;;
|
||||||
"All Arch")
|
"All Arch")
|
||||||
TARGETS=("linux/amd64" "linux/arm/7" "windows/amd64")
|
TARGETS=("linux/amd64" "linux/arm/7" "windows/amd64" "darwin/amd64" "darwin/arm64")
|
||||||
break
|
break
|
||||||
;;
|
;;
|
||||||
"Quit")
|
"Quit")
|
||||||
@@ -269,6 +344,73 @@ ensure_bindata_assets() {
|
|||||||
|
|
||||||
ensure_bindata_assets
|
ensure_bindata_assets
|
||||||
|
|
||||||
|
build_darwin_sqlite_target() {
|
||||||
|
local arch="$1"
|
||||||
|
local output="$2"
|
||||||
|
local repo_root temp_dist built_file output_abs
|
||||||
|
local built_files=()
|
||||||
|
|
||||||
|
require_docker_for_darwin_sqlite
|
||||||
|
repo_root="$(resolve_darwin_sqlite_repo_root)"
|
||||||
|
validate_repo_bind_mount_for_darwin_sqlite "$repo_root"
|
||||||
|
output_abs="$(pwd -P)/$output"
|
||||||
|
|
||||||
|
temp_dist="$repo_root/dist/.smart-build-darwin-${arch}-$$"
|
||||||
|
rm -rf "$temp_dist"
|
||||||
|
if ! mkdir -p "$temp_dist"; then
|
||||||
|
echo "❌ Failed to create a temporary macOS release directory in dist/."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "📦 Building for darwin/$arch with TAGS=\"$BUILD_TAGS\" via release-darwin..."
|
||||||
|
if ! make -C "$repo_root" release-darwin TAGS="$BUILD_TAGS" DARWIN_ARCHS="darwin-10.12/$arch" DIST="$temp_dist"; then
|
||||||
|
rm -rf "$temp_dist"
|
||||||
|
echo "❌ Fail to build for darwin/$arch with SQLite"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
mapfile -t built_files < <(find "$temp_dist/binaries" -maxdepth 1 -type f | sort)
|
||||||
|
if [ "${#built_files[@]}" -ne 1 ]; then
|
||||||
|
rm -rf "$temp_dist"
|
||||||
|
echo "❌ Unexpected macOS artifact count for darwin/$arch: ${#built_files[@]}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
built_file="${built_files[0]}"
|
||||||
|
|
||||||
|
mv "$built_file" "$output_abs"
|
||||||
|
rm -rf "$temp_dist"
|
||||||
|
|
||||||
|
write_sha256_file "$output_abs"
|
||||||
|
echo "✅ Created: $output_abs"
|
||||||
|
echo "✅ Created: $output_abs.sha256"
|
||||||
|
}
|
||||||
|
|
||||||
|
build_standard_target() {
|
||||||
|
local os="$1"
|
||||||
|
local arch="$2"
|
||||||
|
local arm_ver="$3"
|
||||||
|
local output="$4"
|
||||||
|
local ext="$5"
|
||||||
|
|
||||||
|
export GOOS=$os
|
||||||
|
export GOARCH=$arch
|
||||||
|
export GOARM=$arm_ver
|
||||||
|
export CGO_ENABLED=0
|
||||||
|
if [ "$BUILD_VARIANT" == "sqlite" ]; then
|
||||||
|
export CGO_ENABLED=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if make build TAGS="$BUILD_TAGS"; then
|
||||||
|
mv "gitea$ext" "$output"
|
||||||
|
write_sha256_file "$output"
|
||||||
|
echo "✅ Created: $output"
|
||||||
|
echo "✅ Created: $output.sha256"
|
||||||
|
else
|
||||||
|
echo "❌ Fail to build for $os/$arch${arm_ver:+/v$arm_ver}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
# --- 4. COMPILARE ---
|
# --- 4. COMPILARE ---
|
||||||
mkdir -p dist
|
mkdir -p dist
|
||||||
for TARGET in "${TARGETS[@]}"; do
|
for TARGET in "${TARGETS[@]}"; do
|
||||||
@@ -279,27 +421,14 @@ for TARGET in "${TARGETS[@]}"; do
|
|||||||
VARIANT_SUFFIX="" && [ "$BUILD_VARIANT" == "sqlite" ] && VARIANT_SUFFIX="-sqlite"
|
VARIANT_SUFFIX="" && [ "$BUILD_VARIANT" == "sqlite" ] && VARIANT_SUFFIX="-sqlite"
|
||||||
OUTPUT="dist/gitea-$BUILD_REF-$OS-$PLATFORM$VARIANT_SUFFIX$EXT"
|
OUTPUT="dist/gitea-$BUILD_REF-$OS-$PLATFORM$VARIANT_SUFFIX$EXT"
|
||||||
|
|
||||||
echo "📦 Building for $OS/$ARCH ${ARM_VER:+(v$ARM_VER) }with TAGS=\"$BUILD_TAGS\"..."
|
if [ "$OS" == "darwin" ] && [ "$BUILD_VARIANT" == "sqlite" ]; then
|
||||||
|
build_darwin_sqlite_target "$ARCH" "$OUTPUT"
|
||||||
export GOOS=$OS
|
|
||||||
export GOARCH=$ARCH
|
|
||||||
export GOARM=$ARM_VER
|
|
||||||
export CGO_ENABLED=0
|
|
||||||
if [ "$BUILD_VARIANT" == "sqlite" ]; then
|
|
||||||
export CGO_ENABLED=1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if make build TAGS="$BUILD_TAGS"; then
|
|
||||||
mv "gitea$EXT" "$OUTPUT"
|
|
||||||
write_sha256_file "$OUTPUT"
|
|
||||||
echo "✅ Created: $OUTPUT"
|
|
||||||
echo "✅ Created: $OUTPUT.sha256"
|
|
||||||
else
|
else
|
||||||
echo "❌ Fail to build for $TARGET"
|
echo "📦 Building for $OS/$ARCH ${ARM_VER:+(v$ARM_VER) }with TAGS=\"$BUILD_TAGS\"..."
|
||||||
exit 1
|
build_standard_target "$OS" "$ARCH" "$ARM_VER" "$OUTPUT" "$EXT"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
unset GOOS GOARCH GOARM
|
unset GOOS GOARCH GOARM CGO_ENABLED
|
||||||
done
|
done
|
||||||
|
|
||||||
echo "✨ Buid finished. Get file(s) from /dist"
|
echo "✨ Buid finished. Get file(s) from /dist"
|
||||||
|
|||||||
@@ -107,6 +107,7 @@ endif
|
|||||||
LDFLAGS := $(LDFLAGS) -X "main.Version=$(GITEA_VERSION)" -X "main.Tags=$(TAGS)"
|
LDFLAGS := $(LDFLAGS) -X "main.Version=$(GITEA_VERSION)" -X "main.Tags=$(TAGS)"
|
||||||
|
|
||||||
LINUX_ARCHS ?= linux/amd64,linux/386,linux/arm-5,linux/arm-6,linux/arm64,linux/riscv64
|
LINUX_ARCHS ?= linux/amd64,linux/386,linux/arm-5,linux/arm-6,linux/arm64,linux/riscv64
|
||||||
|
DARWIN_ARCHS ?= darwin-10.12/amd64,darwin-10.12/arm64
|
||||||
|
|
||||||
GO_TEST_PACKAGES ?= $(filter-out $(shell $(GO) list code.gitea.io/gitea/models/migrations/...) code.gitea.io/gitea/tests/integration/migration-test code.gitea.io/gitea/tests code.gitea.io/gitea/tests/integration,$(shell $(GO) list ./... | grep -v /vendor/))
|
GO_TEST_PACKAGES ?= $(filter-out $(shell $(GO) list code.gitea.io/gitea/models/migrations/...) code.gitea.io/gitea/tests/integration/migration-test code.gitea.io/gitea/tests code.gitea.io/gitea/tests/integration,$(shell $(GO) list ./... | grep -v /vendor/))
|
||||||
MIGRATE_TEST_PACKAGES ?= $(shell $(GO) list code.gitea.io/gitea/models/migrations/...)
|
MIGRATE_TEST_PACKAGES ?= $(shell $(GO) list code.gitea.io/gitea/models/migrations/...)
|
||||||
@@ -685,7 +686,7 @@ release-linux: | $(DIST_DIRS)
|
|||||||
|
|
||||||
.PHONY: release-darwin
|
.PHONY: release-darwin
|
||||||
release-darwin: | $(DIST_DIRS)
|
release-darwin: | $(DIST_DIRS)
|
||||||
CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) run $(XGO_PACKAGE) -go $(XGO_VERSION) -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '-s -w $(LDFLAGS)' -targets 'darwin-10.12/amd64,darwin-10.12/arm64' -out gitea-$(VERSION) .
|
CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) run $(XGO_PACKAGE) -go $(XGO_VERSION) -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '-s -w $(LDFLAGS)' -targets '$(DARWIN_ARCHS)' -out gitea-$(VERSION) .
|
||||||
|
|
||||||
.PHONY: release-freebsd
|
.PHONY: release-freebsd
|
||||||
release-freebsd: | $(DIST_DIRS)
|
release-freebsd: | $(DIST_DIRS)
|
||||||
|
|||||||
@@ -189,6 +189,8 @@
|
|||||||
"search.pull_kind": "Search pull requests…",
|
"search.pull_kind": "Search pull requests…",
|
||||||
"search.keyword_search_unavailable": "Searching by keyword is currently not available. Please contact the site administrator.",
|
"search.keyword_search_unavailable": "Searching by keyword is currently not available. Please contact the site administrator.",
|
||||||
"aria.navbar": "Navigation Bar",
|
"aria.navbar": "Navigation Bar",
|
||||||
|
"navbar.show": "Show navigation bar",
|
||||||
|
"navbar.hide": "Hide navigation bar",
|
||||||
"aria.footer": "Footer",
|
"aria.footer": "Footer",
|
||||||
"aria.footer.software": "About Software",
|
"aria.footer.software": "About Software",
|
||||||
"aria.footer.links": "Links",
|
"aria.footer.links": "Links",
|
||||||
|
|||||||
@@ -189,6 +189,8 @@
|
|||||||
"search.pull_kind": "Caută cereri de pull...",
|
"search.pull_kind": "Caută cereri de pull...",
|
||||||
"search.keyword_search_unavailable": "Căutarea după cuvânt cheie nu este disponibilă momentan. Te rugăm să contactezi administratorul site-ului.",
|
"search.keyword_search_unavailable": "Căutarea după cuvânt cheie nu este disponibilă momentan. Te rugăm să contactezi administratorul site-ului.",
|
||||||
"aria.navbar": "Bara de navigare",
|
"aria.navbar": "Bara de navigare",
|
||||||
|
"navbar.show": "Arată bara de navigare",
|
||||||
|
"navbar.hide": "Ascunde bara de navigare",
|
||||||
"aria.footer": "Subsol",
|
"aria.footer": "Subsol",
|
||||||
"aria.footer.software": "Despre software",
|
"aria.footer.software": "Despre software",
|
||||||
"aria.footer.links": "Link-uri",
|
"aria.footer.links": "Link-uri",
|
||||||
|
|||||||
@@ -162,6 +162,21 @@
|
|||||||
</div><!-- end full right menu -->
|
</div><!-- end full right menu -->
|
||||||
|
|
||||||
{{$activeStopwatch := and .PageGlobalData (call .PageGlobalData.GetActiveStopwatch)}}
|
{{$activeStopwatch := and .PageGlobalData (call .PageGlobalData.GetActiveStopwatch)}}
|
||||||
|
{{if .ShowPersistentNavbar}}
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
id="persistent-navbar-visibility-toggle"
|
||||||
|
data-show-text="{{ctx.Locale.Tr "navbar.show"}}"
|
||||||
|
data-hide-text="{{ctx.Locale.Tr "navbar.hide"}}"
|
||||||
|
data-tooltip-content="{{ctx.Locale.Tr "navbar.hide"}}"
|
||||||
|
data-tooltip-placement="left"
|
||||||
|
aria-label="{{ctx.Locale.Tr "navbar.hide"}}"
|
||||||
|
aria-pressed="false"
|
||||||
|
>
|
||||||
|
{{svg "octicon-chevron-down" 16 "persistent-navbar-visibility-icon persistent-navbar-visibility-icon-show tw-hidden"}}
|
||||||
|
{{svg "octicon-chevron-up" 16 "persistent-navbar-visibility-icon persistent-navbar-visibility-icon-hide"}}
|
||||||
|
</button>
|
||||||
|
{{end}}
|
||||||
{{if $activeStopwatch}}
|
{{if $activeStopwatch}}
|
||||||
<div class="active-stopwatch-popup tippy-target">
|
<div class="active-stopwatch-popup tippy-target">
|
||||||
<div class="flex-text-block tw-p-3">
|
<div class="flex-text-block tw-p-3">
|
||||||
|
|||||||
@@ -93,7 +93,13 @@ body.show-sticky-side-menus .page-content.admin .flex-container-nav > .ui.vertic
|
|||||||
|
|
||||||
@media (min-width: 768px) {
|
@media (min-width: 768px) {
|
||||||
body.show-persistent-navbar {
|
body.show-persistent-navbar {
|
||||||
--persistent-navbar-offset: 49px;
|
--persistent-navbar-height: 49px;
|
||||||
|
--persistent-navbar-collapsed-peek: 8px;
|
||||||
|
--persistent-navbar-offset: var(--persistent-navbar-height);
|
||||||
|
}
|
||||||
|
|
||||||
|
body.show-persistent-navbar.persistent-navbar-collapsed {
|
||||||
|
--persistent-navbar-offset: var(--persistent-navbar-collapsed-peek);
|
||||||
}
|
}
|
||||||
|
|
||||||
body.show-sticky-side-menus .page-content.user.settings .flex-container-nav > .ui.vertical.menu,
|
body.show-sticky-side-menus .page-content.user.settings .flex-container-nav > .ui.vertical.menu,
|
||||||
|
|||||||
@@ -2,9 +2,12 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
position: relative;
|
||||||
|
overflow: visible;
|
||||||
background: var(--color-nav-bg);
|
background: var(--color-nav-bg);
|
||||||
border-bottom: 1px solid var(--color-secondary);
|
border-bottom: 1px solid var(--color-secondary);
|
||||||
padding: 0 10px;
|
padding: 0 10px;
|
||||||
|
transition: transform 0.2s ease, margin-bottom 0.2s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
body.show-persistent-navbar #navbar {
|
body.show-persistent-navbar #navbar {
|
||||||
@@ -13,6 +16,10 @@ body.show-persistent-navbar #navbar {
|
|||||||
z-index: 10;
|
z-index: 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#persistent-navbar-visibility-toggle {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
/* When notification message is present after navbar, hide border to avoid double border */
|
/* When notification message is present after navbar, hide border to avoid double border */
|
||||||
#navbar:has(+ .ui.message) {
|
#navbar:has(+ .ui.message) {
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
@@ -112,6 +119,43 @@ body.show-persistent-navbar #navbar {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
body.show-persistent-navbar.persistent-navbar-collapsed #navbar {
|
||||||
|
transform: translateY(calc(var(--persistent-navbar-offset, 0px) - var(--persistent-navbar-height, 49px)));
|
||||||
|
margin-bottom: calc(var(--persistent-navbar-offset, 0px) - var(--persistent-navbar-height, 49px));
|
||||||
|
}
|
||||||
|
|
||||||
|
body.show-persistent-navbar #persistent-navbar-visibility-toggle {
|
||||||
|
position: absolute;
|
||||||
|
right: 5px;
|
||||||
|
bottom: -11px;
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-end;
|
||||||
|
justify-content: center;
|
||||||
|
width: 50px;
|
||||||
|
height: 11px;
|
||||||
|
padding: 0;
|
||||||
|
/* padding-bottom: 1px; */
|
||||||
|
color: var(--color-nav-text);
|
||||||
|
background: var(--color-nav-bg);
|
||||||
|
border: 1px solid var(--color-secondary);
|
||||||
|
border-top: none;
|
||||||
|
border-radius: 0 0 10px 10px;
|
||||||
|
box-shadow: 0 2px 6px var(--color-shadow);
|
||||||
|
cursor: pointer;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.show-persistent-navbar #persistent-navbar-visibility-toggle:hover {
|
||||||
|
background: var(--color-nav-hover-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
body.show-persistent-navbar #persistent-navbar-visibility-toggle .svg {
|
||||||
|
width: 12px;
|
||||||
|
height: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#navbar a.item:hover .notification_count,
|
#navbar a.item:hover .notification_count,
|
||||||
#navbar a.item:hover .header-stopwatch-dot,
|
#navbar a.item:hover .header-stopwatch-dot,
|
||||||
#navbar .item.active .navbar-admin-badge {
|
#navbar .item.active .navbar-admin-badge {
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
import {GET, POST} from '../modules/fetch.ts';
|
import {GET, POST} from '../modules/fetch.ts';
|
||||||
import {showGlobalErrorMessage} from '../modules/errors.ts';
|
import {showGlobalErrorMessage} from '../modules/errors.ts';
|
||||||
import {fomanticQuery} from '../modules/fomantic/base.ts';
|
import {fomanticQuery} from '../modules/fomantic/base.ts';
|
||||||
|
import {localUserSettings} from '../modules/user-settings.ts';
|
||||||
import {addDelegatedEventListener, queryElems} from '../utils/dom.ts';
|
import {addDelegatedEventListener, queryElems} from '../utils/dom.ts';
|
||||||
import {registerGlobalInitFunc, registerGlobalSelectorFunc} from '../modules/observer.ts';
|
import {registerGlobalInitFunc, registerGlobalSelectorFunc} from '../modules/observer.ts';
|
||||||
import {initAvatarUploaderWithCropper} from './comp/Cropper.ts';
|
import {initAvatarUploaderWithCropper} from './comp/Cropper.ts';
|
||||||
import {initCompSearchRepoBox} from './comp/SearchRepoBox.ts';
|
import {initCompSearchRepoBox} from './comp/SearchRepoBox.ts';
|
||||||
|
|
||||||
const {appUrl, appSubUrl} = window.config;
|
const {appUrl, appSubUrl} = window.config;
|
||||||
|
const persistentNavbarCollapsedKey = 'persistent-navbar-collapsed';
|
||||||
|
|
||||||
function initHeadNavbarContentToggle() {
|
function initHeadNavbarContentToggle() {
|
||||||
const navbar = document.querySelector('#navbar');
|
const navbar = document.querySelector('#navbar');
|
||||||
@@ -20,6 +22,35 @@ function initHeadNavbarContentToggle() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setPersistentNavbarCollapsedState(collapsed: boolean) {
|
||||||
|
document.body.classList.toggle('persistent-navbar-collapsed', collapsed);
|
||||||
|
|
||||||
|
const btn = document.querySelector<HTMLButtonElement>('#persistent-navbar-visibility-toggle');
|
||||||
|
if (!btn) return;
|
||||||
|
|
||||||
|
const text = btn.getAttribute(collapsed ? 'data-show-text' : 'data-hide-text') ?? '';
|
||||||
|
btn.setAttribute('aria-pressed', String(collapsed));
|
||||||
|
btn.setAttribute('aria-label', text);
|
||||||
|
btn.setAttribute('data-tooltip-content', text);
|
||||||
|
btn.querySelector('.persistent-navbar-visibility-icon-show')?.classList.toggle('tw-hidden', !collapsed);
|
||||||
|
btn.querySelector('.persistent-navbar-visibility-icon-hide')?.classList.toggle('tw-hidden', collapsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
function initPersistentNavbarVisibilityToggle() {
|
||||||
|
if (!document.body.classList.contains('show-persistent-navbar')) return;
|
||||||
|
|
||||||
|
const btn = document.querySelector<HTMLButtonElement>('#persistent-navbar-visibility-toggle');
|
||||||
|
if (!btn) return;
|
||||||
|
|
||||||
|
setPersistentNavbarCollapsedState(localUserSettings.getBoolean(persistentNavbarCollapsedKey, false));
|
||||||
|
|
||||||
|
btn.addEventListener('click', () => {
|
||||||
|
const collapsed = !document.body.classList.contains('persistent-navbar-collapsed');
|
||||||
|
localUserSettings.setBoolean(persistentNavbarCollapsedKey, collapsed);
|
||||||
|
setPersistentNavbarCollapsedState(collapsed);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function initFooterLanguageMenu() {
|
function initFooterLanguageMenu() {
|
||||||
document.querySelector('.ui.dropdown .menu.language-menu')?.addEventListener('click', async (e) => {
|
document.querySelector('.ui.dropdown .menu.language-menu')?.addEventListener('click', async (e) => {
|
||||||
const item = (e.target as HTMLElement).closest('.item');
|
const item = (e.target as HTMLElement).closest('.item');
|
||||||
@@ -57,8 +88,8 @@ export function initStickySideMenuIndicators(root: ParentNode = document) {
|
|||||||
const repoActionsMenuScrollKey = 'sticky-side-menu-scroll:repo-actions';
|
const repoActionsMenuScrollKey = 'sticky-side-menu-scroll:repo-actions';
|
||||||
|
|
||||||
for (const menu of menus) {
|
for (const menu of menus) {
|
||||||
if (menu.dataset.stickySideMenuIndicatorsInitialized === 'true') continue;
|
if (menu.getAttribute('data-sticky-side-menu-indicators-initialized') === 'true') continue;
|
||||||
menu.dataset.stickySideMenuIndicatorsInitialized = 'true';
|
menu.setAttribute('data-sticky-side-menu-indicators-initialized', 'true');
|
||||||
|
|
||||||
const isUserSettingsMenu = Boolean(menu.closest('.page-content.user.settings'));
|
const isUserSettingsMenu = Boolean(menu.closest('.page-content.user.settings'));
|
||||||
const isRepoActionsMenu = Boolean(menu.closest('.page-content.repository.actions'));
|
const isRepoActionsMenu = Boolean(menu.closest('.page-content.repository.actions'));
|
||||||
@@ -112,6 +143,7 @@ export function initStickySideMenuIndicators(root: ParentNode = document) {
|
|||||||
|
|
||||||
export function initCommmPageComponents() {
|
export function initCommmPageComponents() {
|
||||||
initHeadNavbarContentToggle();
|
initHeadNavbarContentToggle();
|
||||||
|
initPersistentNavbarVisibilityToggle();
|
||||||
initFooterLanguageMenu();
|
initFooterLanguageMenu();
|
||||||
initFooterThemeSelector();
|
initFooterThemeSelector();
|
||||||
initStickySideMenuIndicators();
|
initStickySideMenuIndicators();
|
||||||
|
|||||||
Reference in New Issue
Block a user