feat: add stable macOS app download to website
CI/CD / preconditions (pull_request) Successful in 1s
Native JavaScript checks / Native launcher and release tests (pull_request) Successful in 1m3s
macOS checks / Native Rust tests and unsigned build (pull_request) Successful in 1m41s
CI/CD / test_and_check_app (pull_request) Successful in 6m53s
CI/CD / Publish immutable image (pull_request) Skipped
CI/CD / preconditions (pull_request) Successful in 1s
Native JavaScript checks / Native launcher and release tests (pull_request) Successful in 1m3s
macOS checks / Native Rust tests and unsigned build (pull_request) Successful in 1m41s
CI/CD / test_and_check_app (pull_request) Successful in 6m53s
CI/CD / Publish immutable image (pull_request) Skipped
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { Link, usePage } from '@inertiajs/vue3';
|
||||
import { Monitor, Moon, Plus, Sun } from 'lucide-vue-next';
|
||||
import { Download, Monitor, Moon, Plus, Sun } from 'lucide-vue-next';
|
||||
import { computed } from 'vue';
|
||||
import Breadcrumbs from '@/components/Breadcrumbs.vue';
|
||||
import UserMenuContent from '@/components/UserMenuContent.vue';
|
||||
@@ -23,6 +23,7 @@ import {
|
||||
} from '@/composables/useAppearance';
|
||||
import { useCurrentUrl } from '@/composables/useCurrentUrl';
|
||||
import { useLocalization } from '@/composables/useLocalization';
|
||||
import { useMacDownload } from '@/composables/useMacDownload';
|
||||
import { create as createProject } from '@/routes/projects';
|
||||
import { index as board } from '@/routes/projects/board';
|
||||
import { create as createTicket } from '@/routes/projects/tickets';
|
||||
@@ -35,6 +36,7 @@ const page = usePage();
|
||||
const { project } = useAppNavigation();
|
||||
const { isCurrentUrl } = useCurrentUrl();
|
||||
const { t } = useLocalization();
|
||||
const { macDownloadUrl, showMacDownload } = useMacDownload();
|
||||
const { appearance, updateAppearance } = useAppearance();
|
||||
const themeIcon = computed(
|
||||
() => ({ light: Sun, dark: Moon, system: Monitor })[appearance.value],
|
||||
@@ -69,6 +71,21 @@ const createAction = computed(() => {
|
||||
<span v-else class="truncate font-semibold">KanbanGit</span>
|
||||
</div>
|
||||
<div class="flex shrink-0 items-center gap-1 sm:gap-2">
|
||||
<Button
|
||||
v-if="showMacDownload"
|
||||
as-child
|
||||
variant="outline"
|
||||
:aria-label="t('navigation.downloadAppAppleSilicon')"
|
||||
:title="t('navigation.downloadAppAppleSilicon')"
|
||||
class="px-3"
|
||||
>
|
||||
<a :href="macDownloadUrl"
|
||||
><Download aria-hidden="true" /><span
|
||||
class="hidden sm:inline"
|
||||
>{{ t('navigation.downloadApp') }}</span
|
||||
></a
|
||||
>
|
||||
</Button>
|
||||
<Button
|
||||
v-if="createAction"
|
||||
as-child
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
import { onMounted, ref } from 'vue';
|
||||
import updateSource from '../../../native/update-source.json';
|
||||
|
||||
export const macDownloadUrl = `${updateSource.baseUrl}/aarch64-apple-darwin/KanbanGit.dmg`;
|
||||
|
||||
export function isMacDownloadAvailable(
|
||||
userAgent: string,
|
||||
maxTouchPoints: number,
|
||||
isTauri: unknown,
|
||||
): boolean {
|
||||
return (
|
||||
userAgent.includes('Macintosh') &&
|
||||
maxTouchPoints < 2 &&
|
||||
isTauri !== true
|
||||
);
|
||||
}
|
||||
|
||||
export function useMacDownload() {
|
||||
const showMacDownload = ref(false);
|
||||
|
||||
onMounted(() => {
|
||||
showMacDownload.value = isMacDownloadAvailable(
|
||||
navigator.userAgent,
|
||||
navigator.maxTouchPoints,
|
||||
Reflect.get(window, 'isTauri'),
|
||||
);
|
||||
});
|
||||
|
||||
return { macDownloadUrl, showMacDownload };
|
||||
}
|
||||
@@ -1,20 +1,23 @@
|
||||
<script setup lang="ts">
|
||||
import { Link } from '@inertiajs/vue3';
|
||||
import { ShieldCheck } from 'lucide-vue-next';
|
||||
import { Download, ShieldCheck } from 'lucide-vue-next';
|
||||
import type { Component } from 'vue';
|
||||
import AppLogo from '@/components/AppLogo.vue';
|
||||
import AppearanceTabs from '@/components/AppearanceTabs.vue';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { useLocalization } from '@/composables/useLocalization';
|
||||
import { useMacDownload } from '@/composables/useMacDownload';
|
||||
import { home } from '@/routes/index';
|
||||
|
||||
defineProps<{ title: string; description: string; icon?: Component }>();
|
||||
const { t } = useLocalization();
|
||||
const { macDownloadUrl, showMacDownload } = useMacDownload();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="bg-background text-foreground flex min-h-dvh flex-col">
|
||||
<header
|
||||
class="bg-card px-page flex justify-center border-b py-4 sm:justify-start"
|
||||
class="bg-card px-page flex items-center justify-between gap-3 border-b py-4"
|
||||
>
|
||||
<Link
|
||||
:href="home()"
|
||||
@@ -22,6 +25,21 @@ const { t } = useLocalization();
|
||||
class="focus-visible:ring-ring/35 rounded-md outline-none focus-visible:ring-2"
|
||||
><AppLogo
|
||||
/></Link>
|
||||
<Button
|
||||
v-if="showMacDownload"
|
||||
as-child
|
||||
variant="outline"
|
||||
size="sm"
|
||||
:aria-label="t('navigation.downloadAppAppleSilicon')"
|
||||
:title="t('navigation.downloadAppAppleSilicon')"
|
||||
>
|
||||
<a :href="macDownloadUrl"
|
||||
><Download aria-hidden="true" /><span
|
||||
class="hidden sm:inline"
|
||||
>{{ t('navigation.downloadApp') }}</span
|
||||
></a
|
||||
>
|
||||
</Button>
|
||||
</header>
|
||||
<main
|
||||
class="gap-column sm:px-page mx-auto flex w-full max-w-md flex-1 flex-col justify-center px-4 py-8 sm:py-12"
|
||||
|
||||
@@ -718,6 +718,7 @@ export const en = {
|
||||
'welcome.action.dashboard': 'Open dashboard',
|
||||
'welcome.action.dashboardShort': 'Dashboard',
|
||||
'welcome.actionHint': 'One workspace for boards, tickets, and Git context.',
|
||||
'welcome.downloadAppHint': 'For Macs with Apple Silicon.',
|
||||
'welcome.preview.label': 'KanbanGit board preview',
|
||||
'welcome.preview.project': 'Product delivery board',
|
||||
'welcome.preview.connected': 'Git connected',
|
||||
@@ -899,6 +900,9 @@ export const en = {
|
||||
'settings.eyebrow': 'Account settings',
|
||||
'navigation.createTicket': 'New ticket',
|
||||
'navigation.createProject': 'New project',
|
||||
'navigation.downloadApp': 'Download App',
|
||||
'navigation.downloadAppAppleSilicon':
|
||||
'Download App for Macs with Apple Silicon',
|
||||
'navigation.open': 'Open navigation',
|
||||
'navigation.close': 'Close navigation',
|
||||
'navigation.expand': 'Expand sidebar',
|
||||
|
||||
@@ -1,13 +1,21 @@
|
||||
<script setup lang="ts">
|
||||
import { Head, Link } from '@inertiajs/vue3';
|
||||
import { ArrowRight, Columns3, GitBranch, ListChecks } from 'lucide-vue-next';
|
||||
import {
|
||||
ArrowRight,
|
||||
Columns3,
|
||||
Download,
|
||||
GitBranch,
|
||||
ListChecks,
|
||||
} from 'lucide-vue-next';
|
||||
import { computed } from 'vue';
|
||||
import AppLogo from '@/components/AppLogo.vue';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { useLocalization } from '@/composables/useLocalization';
|
||||
import { useMacDownload } from '@/composables/useMacDownload';
|
||||
import { dashboard, home, login } from '@/routes/index';
|
||||
|
||||
const { t } = useLocalization();
|
||||
const { macDownloadUrl, showMacDownload } = useMacDownload();
|
||||
|
||||
const features = computed(() => [
|
||||
{
|
||||
@@ -112,16 +120,38 @@ const previewColumns = computed(() => [
|
||||
{{ t('welcome.description') }}
|
||||
</p>
|
||||
</div>
|
||||
<Button as-child size="lg">
|
||||
<Link v-if="$page.props.auth.user" :href="dashboard()">
|
||||
{{ t('welcome.action.dashboard') }}
|
||||
<ArrowRight aria-hidden="true" />
|
||||
</Link>
|
||||
<Link v-else :href="login()">
|
||||
{{ t('welcome.action.signIn') }}
|
||||
<ArrowRight aria-hidden="true" />
|
||||
</Link>
|
||||
</Button>
|
||||
<div
|
||||
class="flex flex-wrap items-start justify-center gap-3"
|
||||
>
|
||||
<Button as-child size="lg">
|
||||
<Link
|
||||
v-if="$page.props.auth.user"
|
||||
:href="dashboard()"
|
||||
>
|
||||
{{ t('welcome.action.dashboard') }}
|
||||
<ArrowRight aria-hidden="true" />
|
||||
</Link>
|
||||
<Link v-else :href="login()">
|
||||
{{ t('welcome.action.signIn') }}
|
||||
<ArrowRight aria-hidden="true" />
|
||||
</Link>
|
||||
</Button>
|
||||
<div
|
||||
v-if="showMacDownload"
|
||||
class="grid justify-items-center gap-1"
|
||||
>
|
||||
<Button as-child size="lg" variant="outline">
|
||||
<a :href="macDownloadUrl"
|
||||
><Download aria-hidden="true" />{{
|
||||
t('navigation.downloadApp')
|
||||
}}</a
|
||||
>
|
||||
</Button>
|
||||
<p class="text-caption text-muted-foreground">
|
||||
{{ t('welcome.downloadAppHint') }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-caption text-muted-foreground">
|
||||
{{ t('welcome.actionHint') }}
|
||||
</p>
|
||||
|
||||
Reference in New Issue
Block a user