Skip to content
Closed
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
76 changes: 50 additions & 26 deletions apps/studio/server/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -361,39 +361,63 @@ export function loadPublishEnv(): PublishEnvResult {

export type PublicStudioConfig = Omit<PublishEnvConfig, "token">;

function publicPublisherPaths(
publisher: SupportedPublisher,
defaultBranch: string,
): Pick<PublicStudioConfig, "owner" | "repo" | "branch"> {
if (publisher === "gitlab") {
return {
owner:
process.env.GITLAB_PROJECT_PATH?.trim() ||
process.env.GITLAB_PROJECT_ID?.trim() ||
"",
repo: "",
branch: process.env.GITLAB_BRANCH?.trim() || defaultBranch,
};
}

if (publisher === "bitbucket") {
return {
owner: process.env.BITBUCKET_WORKSPACE?.trim() || "",
repo: process.env.BITBUCKET_REPO_SLUG?.trim() || "",
branch: process.env.BITBUCKET_BRANCH?.trim() || defaultBranch,
};
}

if (publisher === "wordpress") {
return {
owner: process.env.WORDPRESS_API_URL?.trim() || "",
repo: "",
branch: defaultBranch,
};
}

if (publisher === "ghost") {
return {
owner: process.env.GHOST_ADMIN_URL?.trim() || "",
repo: "",
branch: defaultBranch,
};
}

return {
owner: process.env.GITHUB_OWNER?.trim() || "",
repo: process.env.GITHUB_REPO?.trim() || "",
branch: process.env.GITHUB_BRANCH?.trim() || defaultBranch,
};
}

export function loadPublicConfig(): PublicStudioConfig {
const project = loadProjectConfig();
const rawAdapter = process.env.CMS_ADAPTER?.trim() || project.adapter;
const rawPublisher = process.env.CMS_PUBLISHER?.trim() || project.publisher;
const adapter = resolveAdapter(rawAdapter) ?? "astro-mdx";
const publisher = resolvePublisher(rawPublisher) ?? "github";
const mediaDir = process.env.CMS_MEDIA_DIR?.trim() || project.mediaDir;

let owner = "";
let repo = "";
let branch = project.defaultBranch;

if (publisher === "gitlab") {
owner =
process.env.GITLAB_PROJECT_PATH?.trim() ||
process.env.GITLAB_PROJECT_ID?.trim() ||
"";
branch = process.env.GITLAB_BRANCH?.trim() || project.defaultBranch;
} else if (publisher === "bitbucket") {
owner = process.env.BITBUCKET_WORKSPACE?.trim() || "";
repo = process.env.BITBUCKET_REPO_SLUG?.trim() || "";
branch = process.env.BITBUCKET_BRANCH?.trim() || project.defaultBranch;
} else if (publisher === "wordpress") {
owner = process.env.WORDPRESS_API_URL?.trim() || "";
branch = project.defaultBranch;
} else if (publisher === "ghost") {
owner = process.env.GHOST_ADMIN_URL?.trim() || "";
branch = project.defaultBranch;
} else {
owner = process.env.GITHUB_OWNER?.trim() || "";
repo = process.env.GITHUB_REPO?.trim() || "";
branch = process.env.GITHUB_BRANCH?.trim() || project.defaultBranch;
}
const { owner, repo, branch } = publicPublisherPaths(
publisher,
project.defaultBranch,
);

return {
owner,
Expand Down
27 changes: 9 additions & 18 deletions apps/studio/server/setupHealth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,14 @@ import { validateConfig } from "@sourcedraft/setup";
import { isAuthConfigured } from "./auth.js";
import { loadProjectConfig, loadPublicConfig } from "./config.js";
import {
isBitbucketConfigured,
isBitbucketRepoConfigured,
isBitbucketTokenConfigured,
isBitbucketWorkspaceConfigured,
isDemoModeAvailable,
isDemoModeForced,
isGitHubConfigured,
isGitHubOwnerConfigured,
isGitHubRepoConfigured,
isGitHubTokenConfigured,
isGitLabConfigured,
isGitLabProjectConfigured,
isGitLabTokenConfigured,
isGhostAdminApiKeyConfigured,
Expand Down Expand Up @@ -309,21 +306,15 @@ export function getSetupHealth(): SetupHealthReport {
},
];

let nextAction: string | null = null;

if (demoModeForced) {
nextAction =
"Demo mode is active. Explore Studio locally or configure your publisher and disable SOURCEDRAFT_DEMO_MODE for real publishing.";
} else if (!adminPasswordConfigured && demoModeAvailable) {
nextAction =
"Enter demo mode from the sign-in screen or set SOURCEDRAFT_ADMIN_PASSWORD for password sign-in.";
} else if (!adminPasswordConfigured) {
nextAction = "Set SOURCEDRAFT_ADMIN_PASSWORD in .env and restart the API server.";
} else if (!publisherReady) {
nextAction = publisherSetupMessage(activePublisher);
} else {
nextAction = null;
}
const nextAction = demoModeForced
? "Demo mode is active. Explore Studio locally or configure your publisher and disable SOURCEDRAFT_DEMO_MODE for real publishing."
: !adminPasswordConfigured && demoModeAvailable
? "Enter demo mode from the sign-in screen or set SOURCEDRAFT_ADMIN_PASSWORD for password sign-in."
: !adminPasswordConfigured
? "Set SOURCEDRAFT_ADMIN_PASSWORD in .env and restart the API server."
: !publisherReady
? publisherSetupMessage(activePublisher)
: null;

const validation = validateConfig();
const compatibility: SetupCompatibilityReport = {
Expand Down
17 changes: 15 additions & 2 deletions apps/studio/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,13 @@ function App() {
return;
}

fetchStudioConfig().then((config) => {
let cancelled = false;

void fetchStudioConfig().then((config) => {
if (cancelled) {
return;
}

setStudioConfig(config);
setDemoMode(config.demoMode === true);
setForm((current) => {
Expand All @@ -128,7 +134,14 @@ function App() {
});
});

void refreshPosts();
const postsTimer = window.setTimeout(() => {
void refreshPosts();
}, 0);

return () => {
cancelled = true;
window.clearTimeout(postsTimer);
};
}, [authenticated, refreshPosts]);

const githubReady = useMemo(
Expand Down
28 changes: 1 addition & 27 deletions apps/studio/src/components/MarkdownToolbar.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { useState, type KeyboardEvent, type RefObject } from "react";
import { useState, type RefObject } from "react";
import type { PostSummary } from "../lib/posts.js";
import {
actionForShortcut,
applyMarkdownAction,
applyResultToTextarea,
selectionFromTextarea,
Expand Down Expand Up @@ -185,28 +184,3 @@ export function MarkdownToolbar({
</div>
);
}

export function handleMarkdownShortcut(
event: KeyboardEvent<HTMLTextAreaElement>,
body: string,
onBodyChange: (body: string) => void,
): boolean {
if (!(event.metaKey || event.ctrlKey) || event.altKey || event.shiftKey) {
return false;
}

const action = actionForShortcut(event.key);
if (!action) {
return false;
}

event.preventDefault();
const textarea = event.currentTarget;
const selection = selectionFromTextarea(textarea);
const result = applyMarkdownAction(body, selection, action);
onBodyChange(result.value);
requestAnimationFrame(() => {
applyResultToTextarea(textarea, result);
});
return true;
}
8 changes: 7 additions & 1 deletion apps/studio/src/components/MediaLibrary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,13 @@ export function MediaLibrary({
}, [githubReady]);

useEffect(() => {
void loadLibrary();
const timer = window.setTimeout(() => {
void loadLibrary();
}, 0);

return () => {
window.clearTimeout(timer);
};
}, [loadLibrary, refreshKey]);

async function handleCopy(publicPath: string) {
Expand Down
6 changes: 2 additions & 4 deletions apps/studio/src/components/WritingCanvas.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import { useId, useRef } from "react";
import type { PostSummary } from "../lib/posts";
import { DocumentOutline } from "./DocumentOutline";
import {
handleMarkdownShortcut,
MarkdownToolbar,
} from "./MarkdownToolbar";
import { handleMarkdownShortcut } from "../lib/markdownShortcuts";
import { MarkdownToolbar } from "./MarkdownToolbar";

type WritingCanvasProps = {
title: string;
Expand Down
10 changes: 5 additions & 5 deletions apps/studio/src/hooks/useDocumentAutosave.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export function useDocumentAutosave({
publishing,
enabled,
}: UseDocumentAutosaveOptions): UseDocumentAutosaveResult {
const baselineRef = useRef<DocumentSnapshot>(snapshot);
const [baseline, setBaseline] = useState<DocumentSnapshot>(snapshot);
const [localSavedAt, setLocalSavedAt] = useState<string | null>(null);
const [syncedWithRemote, setSyncedWithRemote] = useState(false);
const [restorePrompt, setRestorePrompt] = useState<AutosaveRecord | null>(
Expand All @@ -60,8 +60,8 @@ export function useDocumentAutosave({
const initialCheckDoneRef = useRef(false);

const isDirty = useMemo(
() => !snapshotsEqual(snapshot, baselineRef.current),
[snapshot],
() => !snapshotsEqual(snapshot, baseline),
[snapshot, baseline],
);

const checkRestorePrompt = useCallback((current: DocumentSnapshot) => {
Expand Down Expand Up @@ -91,11 +91,11 @@ export function useDocumentAutosave({

const commitBaseline = useCallback(
(baseline: DocumentSnapshot, options: CommitBaselineOptions) => {
baselineRef.current = {
setBaseline({
form: { ...baseline.form },
editingPath: baseline.editingPath,
slugAuto: baseline.slugAuto,
};
});
setSyncedWithRemote(options.remoteSync);
setLocalSavedAt(null);
setRestorePrompt(null);
Expand Down
32 changes: 32 additions & 0 deletions apps/studio/src/lib/markdownShortcuts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import type { KeyboardEvent } from "react";
import {
actionForShortcut,
applyMarkdownAction,
applyResultToTextarea,
selectionFromTextarea,
} from "./markdownEditor.js";

export function handleMarkdownShortcut(
event: KeyboardEvent<HTMLTextAreaElement>,
body: string,
onBodyChange: (body: string) => void,
): boolean {
if (!(event.metaKey || event.ctrlKey) || event.altKey || event.shiftKey) {
return false;
}

const action = actionForShortcut(event.key);
if (!action) {
return false;
}

event.preventDefault();
const textarea = event.currentTarget;
const selection = selectionFromTextarea(textarea);
const result = applyMarkdownAction(body, selection, action);
onBodyChange(result.value);
requestAnimationFrame(() => {
applyResultToTextarea(textarea, result);
});
return true;
}