Skip to content

Commit b99ee24

Browse files
committed
Web: Add extension visibility
1 parent af65975 commit b99ee24

File tree

12 files changed

+162
-38
lines changed

12 files changed

+162
-38
lines changed

.changeset/polite-worms-fix.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@pulse-editor/shared-utils": patch
3+
"@pulse-editor/react-api": patch
4+
---
5+
6+
Add extension package visibility

.changeset/pre.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,11 @@
2828
"large-moose-tap",
2929
"lazy-zebras-mate",
3030
"mighty-ghosts-crash",
31+
"polite-worms-fix",
3132
"real-knives-rest",
3233
"rude-ducks-design",
3334
"sad-tables-join",
35+
"shiny-doodles-jump",
3436
"slick-roses-fix",
3537
"social-donkeys-cross",
3638
"stale-groups-poke",

.changeset/shiny-doodles-jump.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@pulse-editor/shared-utils": patch
3+
"@pulse-editor/react-api": patch
4+
---
5+
6+
Remove visibility in extension config

package-lock.json

Lines changed: 42 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

web/app/(extension-layout)/extension/layout.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import RemoteModuleProvider from "@/components/providers/remote-module-provider";
22
import { ReactNode, Suspense } from "react";
3+
import { Analytics } from "@vercel/analytics/next";
34

45
export default function ExtensionLayout({ children }: { children: ReactNode }) {
56
return (
@@ -10,6 +11,7 @@ export default function ExtensionLayout({ children }: { children: ReactNode }) {
1011
width: "100vw",
1112
}}
1213
>
14+
<Analytics />
1315
<RemoteModuleProvider isPreventingCSS={false}>
1416
<Suspense>{children}</Suspense>
1517
</RemoteModuleProvider>

web/app/(main-layout)/layout.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import RemoteModuleProvider from "@/components/providers/remote-module-provider"
99
import InterModuleCommunicationProvider from "@/components/providers/imc-provider";
1010
import Nav from "@/components/interface/nav";
1111
import { Suspense } from "react";
12+
import { Analytics } from "@vercel/analytics/next";
1213

1314
export const metadata: Metadata = {
1415
title: "Pulse Editor",
@@ -23,6 +24,7 @@ export default function RootLayout({
2324
return (
2425
<html lang="en" suppressHydrationWarning>
2526
<body className={`h-[100dvh] w-[100dvw] antialiased`}>
27+
<Analytics />
2628
<Suspense>
2729
<CapacitorProvider>
2830
<WrappedHeroUIProvider>

web/components/interface/extension-suggestion-overlay.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ import ExtensionPreview from "../extension/preview";
33
export default function ExtensionSuggestionOverlay() {
44
return (
55
<div className="absolute top-0 left-0 h-full w-full backdrop-blur-xs backdrop-invert-25">
6-
<div className="flex h-full w-full grid-rows-[max-content_auto] flex-col items-center pb-10 pt-4">
6+
<div className="flex h-full w-full grid-rows-[max-content_auto] flex-col items-center pt-4 pb-10">
77
<div className="bg-content1 responsive-content h-20 rounded-lg"></div>
8-
<div className="h-full flex flex-col justify-center pb-20">
8+
<div className="flex h-full flex-col justify-center pb-20">
99
<div className="responsive-content flex gap-2">
1010
<ExtensionPreview
1111
showInstalledChip
@@ -15,6 +15,7 @@ export default function ExtensionSuggestionOverlay() {
1515
displayName: "Extension Name",
1616
description: "Extension Description",
1717
version: "1.0.0",
18+
visibility: "public",
1819
},
1920
isEnabled: false,
2021
remoteOrigin: "https://cdn.pulse-editor.com/extension",
@@ -28,6 +29,7 @@ export default function ExtensionSuggestionOverlay() {
2829
displayName: "Extension Name",
2930
description: "Extension Description",
3031
version: "1.0.0",
32+
visibility: "public",
3133
},
3234
isEnabled: false,
3335
remoteOrigin: "https://cdn.pulse-editor.com/extension",
@@ -41,6 +43,7 @@ export default function ExtensionSuggestionOverlay() {
4143
displayName: "Extension Name",
4244
description: "Extension Description",
4345
version: "1.0.0",
46+
visibility: "public",
4447
},
4548
isEnabled: false,
4649
remoteOrigin: "https://cdn.pulse-editor.com/extension",

web/components/modals/app-settings-modal.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -887,6 +887,7 @@ function DevExtensionSettings({
887887
config: {
888888
id: devExtensionId,
889889
version: devExtensionVersion,
890+
visibility: "private",
890891
},
891892
isEnabled: true,
892893
};

web/components/modals/extension-marketplace-modal.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ export default function ExtensionMarketplaceModal({
5959
org: {
6060
name: string;
6161
};
62+
visibility: string;
6263
}[] = body;
6364
const extensions: Extension[] = fetchedExts.map((ext) => {
6465
return {
@@ -68,6 +69,7 @@ export default function ExtensionMarketplaceModal({
6869
author: ext.user ? ext.user.name : ext.org.name,
6970
description: ext.description ?? "No description available",
7071
displayName: ext.displayName ?? ext.name,
72+
visibility: ext.visibility,
7173
},
7274
isEnabled: true,
7375
remoteOrigin: `https://cdn.pulse-editor.com/extension`,

web/components/modals/sharing-modal.tsx

Lines changed: 90 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1-
import { Button } from "@heroui/react";
1+
import { Button, Select, SelectItem } from "@heroui/react";
22
import ModalWrapper from "./modal-wrapper";
33
import { useSearchParams } from "next/navigation";
44
import QRDisplay from "../misc/qr-display";
55
import Tabs from "../misc/tabs";
66
import { TabItem } from "@/lib/types";
7-
import { useState } from "react";
7+
import { useEffect, useState } from "react";
88
import Icon from "../misc/icon";
99
import toast from "react-hot-toast";
10+
import { useAuth } from "@/lib/hooks/use-auth";
1011

1112
export default function SharingModal({
1213
isOpen,
@@ -34,6 +35,37 @@ export default function SharingModal({
3435
tabItems[0],
3536
);
3637

38+
const visibilityOptions = ["public", "unlisted", "private"];
39+
const [selectedVisibility, setSelectedVisibility] = useState<
40+
string | undefined
41+
>(undefined);
42+
43+
const { session } = useAuth();
44+
const [isDeveloper, setIsDeveloper] = useState(false);
45+
46+
// Load app visibility
47+
useEffect(() => {
48+
async function getVisibility() {
49+
if (!app) return;
50+
51+
const url = new URL(`https://pulse-editor.com/api/extension/get`);
52+
url.searchParams.append("app", app);
53+
url.searchParams.append("latest", "true");
54+
55+
const res = await fetch(url, {
56+
credentials: "include",
57+
});
58+
59+
const data: {
60+
visibility: string;
61+
}[] = await res.json();
62+
if (data) {
63+
const ext = data[0];
64+
setSelectedVisibility(ext.visibility);
65+
}
66+
}
67+
}, []);
68+
3769
return (
3870
<ModalWrapper
3971
isOpen={isOpen}
@@ -42,39 +74,65 @@ export default function SharingModal({
4274
placement={"center"}
4375
>
4476
<div className="flex w-full flex-col items-center gap-2">
45-
<Tabs
46-
tabItems={tabItems}
47-
selectedItem={selectedTab}
48-
setSelectedItem={setSelectedTab}
49-
/>
50-
51-
{selectedTab?.name === tabItems[0].name && (
52-
<div className="flex flex-col items-center gap-y-1">
53-
<p className="text-content4-foreground text-sm">
54-
Share your workspace via this QR Code
55-
</p>
56-
<QRDisplay url={window.location.href} />
57-
</div>
77+
{app && (
78+
<Select
79+
label="Visibility"
80+
placeholder="Select visibility"
81+
onChange={(e) => {
82+
setSelectedVisibility(e.target.value);
83+
}}
84+
isDisabled={!isDeveloper}
85+
>
86+
{visibilityOptions.map((option) => (
87+
<SelectItem key={option}>{option}</SelectItem>
88+
))}
89+
</Select>
5890
)}
5991

60-
{selectedTab?.name === tabItems[1].name && (
61-
<div className="flex flex-col items-center gap-y-1">
62-
<p className="text-content4-foreground text-sm">
63-
Share your workspace via this URL
64-
</p>
92+
{!selectedVisibility && app ? (
93+
<p>Select a visibility option to see sharing options.</p>
94+
) : selectedVisibility === "private" && app ? (
95+
<p>Your workspace is private.</p>
96+
) : (
97+
<>
98+
<Tabs
99+
tabItems={tabItems}
100+
selectedItem={selectedTab}
101+
setSelectedItem={setSelectedTab}
102+
/>
103+
104+
{selectedTab?.name === tabItems[0].name && (
105+
<div className="flex flex-col items-center gap-y-1">
106+
<p className="text-content4-foreground text-sm">
107+
Share your workspace via this QR Code
108+
</p>
109+
<QRDisplay url={window.location.href} />
110+
</div>
111+
)}
112+
113+
{selectedTab?.name === tabItems[1].name && (
114+
<div className="flex flex-col items-center gap-y-1">
115+
<p className="text-content4-foreground text-sm">
116+
Share your workspace via this URL
117+
</p>
65118

66-
<p className="font-bold break-all">{window.location.href}</p>
67-
<Button
68-
color="primary"
69-
onPress={() => {
70-
navigator.clipboard.writeText(window.location.href);
71-
toast.success("URL copied to clipboard");
72-
}}
73-
>
74-
<Icon name="content_copy" className="text-primary-foreground!" />
75-
Copy
76-
</Button>
77-
</div>
119+
<p className="font-bold break-all">{window.location.href}</p>
120+
<Button
121+
color="primary"
122+
onPress={() => {
123+
navigator.clipboard.writeText(window.location.href);
124+
toast.success("URL copied to clipboard");
125+
}}
126+
>
127+
<Icon
128+
name="content_copy"
129+
className="text-primary-foreground!"
130+
/>
131+
Copy
132+
</Button>
133+
</div>
134+
)}
135+
</>
78136
)}
79137
</div>
80138
</ModalWrapper>

0 commit comments

Comments
 (0)