Skip to content
Merged

UI #253

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion apps/desktop/scripts/release-local.sh
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,11 @@ node -e '
echo "▸ [5/5] Publishing to ${PUBLIC_REPO} ..."
gh release create "$TAG" --repo "$PUBLIC_REPO" \
--title "MyDevTools $TAG" --notes "MyDevTools desktop $TAG"
# MyDevTools.dmg (version-less copy) keeps the website's download button URL
# stable: .../releases/latest/download/MyDevTools.dmg always serves the newest.
cp "$DMG" "$OUT/MyDevTools.dmg"
gh release upload "$TAG" --repo "$PUBLIC_REPO" --clobber \
"$DMG" "$TARGZ" "$SIG" "$LATEST"
"$DMG" "$OUT/MyDevTools.dmg" "$TARGZ" "$SIG" "$LATEST"

echo ""
echo "✅ Published v$VERSION. Installed apps will offer the update on next launch."
Expand Down
25 changes: 11 additions & 14 deletions apps/web/src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ import {
Users,
Building2,
Check,
Download as DownloadIcon,
} from "lucide-react";
import { AppleGlyph, DMG_URL } from "@/components/download-desktop-button";
import { sidebarData } from "@/components/sidebar/data/sidebar-data";
import { homepageFaqItems } from "@/lib/seo/structured-data";
import MdtAurora from "@/components/mdt-aurora";
Expand Down Expand Up @@ -352,32 +354,27 @@ export default function Page() {
className="flex flex-col sm:flex-row items-center justify-center gap-3 pt-2"
>
<Magnetic strength={0.4} className="w-full sm:w-auto">
<button
onClick={goToLogin}
className="mdt-btn-grad inline-flex items-center justify-center h-12 px-8 rounded-full text-sm font-medium w-full sm:w-auto"
<a
href={DMG_URL}
download
className="mdt-btn-grad inline-flex items-center justify-center gap-2 h-12 px-8 rounded-full text-sm font-medium w-full sm:w-auto"
>
Get Started
<ArrowRight className="ml-2 h-4 w-4" />
</button>
<AppleGlyph className="h-4 w-4" />
Download for macOS
<DownloadIcon className="h-4 w-4 opacity-80" />
</a>
</Magnetic>
<Link
href="/developer-tools"
className="inline-flex items-center justify-center h-12 px-8 rounded-full text-sm font-medium border border-border/60 dark:border-white/10 bg-background/50 backdrop-blur-md text-foreground hover:bg-muted hover:scale-[1.04] active:scale-[0.98] transition-all duration-300 w-full sm:w-auto"
>
Explore Platform
</Link>
</motion.div>

{/* Stats row */}
<motion.div
variants={fadeUp}
transition={{ duration: 0.6, delay: 0.32 }}
className="mt-7 mx-auto grid max-w-lg grid-cols-3 overflow-hidden rounded-2xl border border-white/10 bg-[#0a0b12]/80 backdrop-blur-md divide-x divide-white/10 shadow-xl shadow-black/40"
className="mt-7 mx-auto grid max-w-lg grid-cols-2 overflow-hidden rounded-2xl border border-white/10 bg-[#0a0b12]/80 backdrop-blur-md divide-x divide-white/10 shadow-xl shadow-black/40"
>
{[
{ value: "80+", label: "Built-in Tools" },
{ value: "AES-256", label: "Encrypted Sync" },
{ value: "Free", label: "To Get Started" },
].map((s, i) => (
<div key={i} className="px-2 py-4 text-center">
<div className="text-lg sm:text-xl md:text-2xl font-bold tracking-tight whitespace-nowrap mdt-grad-text">
Expand Down
63 changes: 9 additions & 54 deletions apps/web/src/components/download-desktop-button.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,16 @@
"use client";

import { useEffect, useState } from "react";
import { Download, Loader2 } from "lucide-react";
import { Download } from "lucide-react";

import { Button } from "@/components/ui/button";

/**
* "Download for macOS" button. Reads the latest published GitHub release via the
* API and links straight to its universal .dmg asset, so the link stays current
* across releases without editing the site. Falls back to the releases page if
* the API is unreachable or no asset is found yet.
* GitHub's permanent "latest release" redirect — always serves the newest DMG.
* release-local.sh uploads a version-less MyDevTools.dmg to every release.
*/
// Public releases-mirror repo (source repo is private, so its release assets
// aren't publicly downloadable). CI mirrors the DMG + latest.json here.
const REPO = "mydevtools-tech/mydevtools-releases";
const RELEASES_PAGE = `https://github.com/${REPO}/releases/latest`;

type Asset = { name: string; browser_download_url: string };
export const DMG_URL =
"https://github.com/mydevtools-tech/mydevtools-releases/releases/latest/download/MyDevTools.dmg";

/** Minimal Apple logo (lucide has no Apple icon in this version). */
function AppleGlyph({ className }: { className?: string }) {
export function AppleGlyph({ className }: { className?: string }) {
return (
<svg viewBox="0 0 384 512" aria-hidden className={className} fill="currentColor">
<path d="M318.7 268.7c-.2-36.7 16.4-64.4 50-84.8-18.8-26.9-47.2-41.7-84.7-44.6-35.5-2.8-74.3 20.7-88.5 20.7-15 0-49.4-19.7-76.4-19.7C63.3 141.2 4 184.8 4 273.5q0 39.3 14.4 81.2c12.8 36.7 59 126.7 107.2 125.2 25.2-.6 43-17.9 75.8-17.9 31.8 0 48.3 17.9 76.4 17.9 48.6-.7 90.4-82.5 102.6-119.3-65.2-30.7-61.7-90-61.7-91.9zm-56.6-164.2c27.3-32.4 24.8-61.9 24-72.5-24.1 1.4-52 16.4-67.9 34.9-17.5 19.8-27.8 44.3-25.6 71.9 26.1 2 49.9-11.4 69.5-34.3z" />
Expand All @@ -34,53 +25,17 @@ export function DownloadDesktopButton({
size?: "default" | "sm" | "lg";
className?: string;
}) {
const [dmgUrl, setDmgUrl] = useState<string | null>(null);
const [version, setVersion] = useState<string | null>(null);
const [loading, setLoading] = useState(true);

useEffect(() => {
let active = true;
fetch(`https://api.github.com/repos/${REPO}/releases/latest`, {
headers: { Accept: "application/vnd.github+json" },
})
.then((r) => (r.ok ? r.json() : Promise.reject(new Error(String(r.status)))))
.then((d) => {
if (!active) return;
const assets: Asset[] = Array.isArray(d.assets) ? d.assets : [];
const dmg =
assets.find((a) => /universal.*\.dmg$/i.test(a.name)) ||
assets.find((a) => a.name.toLowerCase().endsWith(".dmg"));
setDmgUrl(dmg?.browser_download_url ?? null);
setVersion(typeof d.tag_name === "string" ? d.tag_name : null);
})
.catch(() => {
/* offline / rate-limited / no release yet — fall back to releases page */
})
.finally(() => {
if (active) setLoading(false);
});
return () => {
active = false;
};
}, []);

const href = dmgUrl ?? RELEASES_PAGE;

return (
<div className={className}>
<Button asChild size={size} className="gap-2">
<a href={href} download>
{loading ? (
<Loader2 className="h-4 w-4 animate-spin" />
) : (
<AppleGlyph className="h-4 w-4" />
)}
<a href={DMG_URL} download>
<AppleGlyph className="h-4 w-4" />
Download for macOS
<Download className="h-4 w-4 opacity-70" />
</a>
</Button>
<p className="mt-2 text-sm text-muted-foreground">
{version ? `${version} · ` : ""}Universal (Apple Silicon &amp; Intel) · macOS 12+
Universal (Apple Silicon &amp; Intel) · macOS 12+
</p>
</div>
);
Expand Down