diff --git a/apps/web/src/app/(protected)/settings/channel/create/page.tsx b/apps/web/src/app/(protected)/create/page.tsx
similarity index 83%
rename from apps/web/src/app/(protected)/settings/channel/create/page.tsx
rename to apps/web/src/app/(protected)/create/page.tsx
index 27e49a9..562b8c1 100644
--- a/apps/web/src/app/(protected)/settings/channel/create/page.tsx
+++ b/apps/web/src/app/(protected)/create/page.tsx
@@ -1,8 +1,13 @@
+'use client'
+
import { UniversalForm } from "@/components/app/UniversalForm/UniversalForm";
import { createChannel } from "@/lib/form/actions";
import { Hash } from "lucide-react";
+import { useRouter } from "next/navigation";
function CreateChannelPage() {
+ const router = useRouter();
+
return (
@@ -26,6 +31,13 @@ function CreateChannelPage() {
]}
schemaName="createChannel"
action={createChannel}
+ onActionComplete={(r) => {
+ // @ts-expect-error
+ const channelName = r?.channel;
+ if (channelName) {
+ router.push(`/${channelName}`);
+ }
+ }}
/>
diff --git a/apps/web/src/app/(protected)/settings/channel/[channelName]/page.client.tsx b/apps/web/src/app/(protected)/settings/channel/[channelName]/page.client.tsx
index fb0b062..24adae8 100644
--- a/apps/web/src/app/(protected)/settings/channel/[channelName]/page.client.tsx
+++ b/apps/web/src/app/(protected)/settings/channel/[channelName]/page.client.tsx
@@ -1,6 +1,6 @@
'use client';
-import { useEffect, useState } from 'react';
+import { useState } from 'react';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { Badge } from '@/components/ui/badge';
@@ -44,6 +44,9 @@ import { parseAsString, useQueryState } from 'nuqs';
import { Write } from '@/components/ui/channel-desc-fancy-area/write';
import { Preview } from '@/components/ui/channel-desc-fancy-area/preview';
import { UploadButton } from '@/lib/uploadthing';
+import { useOwnedChannels } from '@/lib/hooks/useUserList';
+import { ChannelSelect } from '@/components/app/ChannelSelect/ChannelSelect';
+import { useRouter } from 'next/navigation';
interface ChannelSettingsClientProps {
channel: Channel & {
@@ -73,6 +76,8 @@ export default function ChannelSettingsClient({
const [selTab, setSelTab] = useQueryState('tabs', parseAsString.withDefault('general'));
const [isUploading, setIsUploading] = useState(false);
const [uploadError, setUploadError] = useState
(null);
+ const channelList = useOwnedChannels();
+ const router = useRouter();
const copyStreamKey = async () => {
if (streamKey) {
@@ -105,7 +110,7 @@ export default function ChannelSettingsClient({
return (
-
+
@@ -122,6 +127,20 @@ export default function ChannelSettingsClient({
+
+
+ c.channel)}
+ value={channel.name}
+ onSelect={(value) => {
+ if (value === 'create') {
+ router.push('/create');
+ } else {
+ router.push(`/settings/channel/${value}`);
+ }
+ }}
+ />
+
diff --git a/apps/web/src/app/(protected)/settings/channel/page.tsx b/apps/web/src/app/(protected)/settings/channel/page.tsx
new file mode 100644
index 0000000..e0df91c
--- /dev/null
+++ b/apps/web/src/app/(protected)/settings/channel/page.tsx
@@ -0,0 +1,12 @@
+import { resolvePersonalChannel } from "@/lib/auth/resolve";
+import { redirect } from "next/navigation";
+
+export default async function ChannelSettingsRedirector() {
+ const personalChannel = await resolvePersonalChannel();
+ if (personalChannel) {
+ return redirect(`/settings/channel/${personalChannel.name}`);
+ }
+
+ // lil easter egg which i doubt anyone will see
+ return erm
;
+}
\ No newline at end of file
diff --git a/apps/web/src/components/app/ChannelSelect/ChannelSelect.tsx b/apps/web/src/components/app/ChannelSelect/ChannelSelect.tsx
new file mode 100644
index 0000000..ec1ddb8
--- /dev/null
+++ b/apps/web/src/components/app/ChannelSelect/ChannelSelect.tsx
@@ -0,0 +1,46 @@
+'use client'
+
+import type { Channel } from "@hctv/db";
+import * as React from 'react';
+import { Plus } from 'lucide-react';
+import {
+ Select,
+ SelectContent,
+ SelectItem,
+ SelectTrigger,
+ SelectValue,
+} from '@/components/ui/select';
+import { Avatar, AvatarImage, AvatarFallback } from '@/components/ui/avatar';
+
+export function ChannelSelect(props: Props) {
+ const { channelList } = props;
+ return (
+
+ );
+}
+
+interface Props {
+ channelList: Channel[];
+ value?: string;
+ onSelect: (value: string) => void;
+}
\ No newline at end of file
diff --git a/apps/web/src/components/app/EditLivestream/dialog.tsx b/apps/web/src/components/app/EditLivestream/dialog.tsx
index f419096..e698366 100644
--- a/apps/web/src/components/app/EditLivestream/dialog.tsx
+++ b/apps/web/src/components/app/EditLivestream/dialog.tsx
@@ -63,7 +63,7 @@ export default function EditLivestreamDialog(props: Props) {
setSelectedChannel('');
// using window location href as a really janky way to just close the dialog
// TODO: use a proper dialog close method
- window.location.href = '/settings/channel/create';
+ window.location.href = '/create';
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [selectedChannel]);
diff --git a/apps/web/src/lib/form/actions.ts b/apps/web/src/lib/form/actions.ts
index 0fcb435..f54fc29 100644
--- a/apps/web/src/lib/form/actions.ts
+++ b/apps/web/src/lib/form/actions.ts
@@ -155,7 +155,7 @@ export async function createChannel(prev: any, formData: FormData) {
await initializeStreamInfo(createdChannel.id);
- return { success: true };
+ return { success: true, channel: createdChannel.name };
}
export async function updateChannelSettings(prev: any, formData: FormData) {