Skip to content

Commit be15d5d

Browse files
committed
gulag vasili
1 parent 33a22f4 commit be15d5d

6 files changed

Lines changed: 173 additions & 51 deletions

File tree

components/forms/AddChannel.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
Controller,
1010
} from 'react-hook-form';
1111
import ChannelMessageIcon from '@/components/icons/ChannelMessageIcon';
12+
import { ChannelMediaIcon } from '@/components/icons/ChannelMediaIcon';
1213

1314
export default function AddChannel({
1415
register,
@@ -103,7 +104,7 @@ export default function AddChannel({
103104
channelType == 'media' ? 'bg-grey-600' : 'bg-grey-700'
104105
} rounded-2xl py-2 pl-6 mt-2 items-center`}
105106
>
106-
<ChannelMessageIcon />
107+
<ChannelMediaIcon />
107108
<label className="ml-1 flex items-center w-full justify-between hover:cursor-pointer">
108109
Voice{' '}
109110
<input

components/home/AddChannelModal.tsx

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,14 @@ import { zodResolver } from '@hookform/resolvers/zod';
88
import { Dispatch, SetStateAction, useRef, useState } from 'react';
99
import { useForm } from 'react-hook-form';
1010
import { useSupabaseClient } from '@supabase/auth-helpers-react';
11+
import { createChannel } from '@/services/channels.service';
12+
import { PostgrestError } from '@supabase/supabase-js';
13+
import {
14+
useGetUserPermsForServer,
15+
useUserPerms,
16+
useUserServerPerms,
17+
} from '@/lib/store';
18+
import { ChannelPermissions } from '@/types/permissions';
1119

1220
export default function AddChannelModal({
1321
showModal,
@@ -26,6 +34,10 @@ export default function AddChannelModal({
2634

2735
const supabase = useSupabaseClient();
2836

37+
const getUserServerPerms = useGetUserPermsForServer();
38+
getUserServerPerms(supabase, serverId);
39+
const userServerPerms = useUserServerPerms();
40+
2941
const {
3042
register,
3143
handleSubmit,
@@ -45,8 +57,33 @@ export default function AddChannelModal({
4557
const onSubmit = async (formData: CreateChannelInput) => {
4658
//
4759
console.log(serverId);
60+
console.log(userPerms & ChannelPermissions.MANAGE_MESSAGES);
61+
const { data, error } = await createChannel(
62+
supabase,
63+
serverId,
64+
formData.name,
65+
formData.description,
66+
formData.isMedia
67+
);
68+
69+
if (error) {
70+
if ((error as PostgrestError).message) {
71+
setServerError((error as PostgrestError).message);
72+
} else {
73+
setServerError(error as string);
74+
}
4875

49-
// setChannelType('text');
76+
setTimeout(() => {
77+
setServerError('');
78+
}, 7000);
79+
return;
80+
} else {
81+
addChannelRef.current?.close();
82+
setChannelType('text');
83+
setSetShowDesc(false);
84+
reset();
85+
setShowModal(false);
86+
}
5087
};
5188

5289
return (

components/home/Chat.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,11 @@ import { useRef, useEffect } from 'react';
33
import styles from '@/styles/Chat.module.css';
44
import { useSupabaseClient, useUser } from '@supabase/auth-helpers-react';
55
import MessageInput from './MessageInput';
6-
import type { MessageWithServerProfile, Message as MessageType } from '@/types/dbtypes';
7-
import { createMessage } from '@/services/message.service';
6+
import type {
7+
MessageWithServerProfile,
8+
Message as MessageType,
9+
} from '@/types/dbtypes';
10+
import { createMessage } from '@/services/message.service';
811
import Message from '@/components/home/Message';
912
import { useChannel, useMessages, useUserPerms } from '@/lib/store';
1013
import { Channel } from '@/types/dbtypes';
@@ -53,7 +56,8 @@ export default function Chat() {
5356
{messages &&
5457
messages.map((value, index: number, array) => {
5558
// Get the previous message, if the authors are the same, we don't need to repeat the header (profile picture, name, etc.)
56-
const previousMessage: MessageWithServerProfile | null = index > 0 ? array[index - 1] : null;
59+
const previousMessage: MessageWithServerProfile | null =
60+
index > 0 ? array[index - 1] : null;
5761

5862
return (
5963
<Message

components/home/ServerList.tsx

Lines changed: 36 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,15 @@ import { useSupabaseClient, useUser } from '@supabase/auth-helpers-react';
66
import styles from '@/styles/Servers.module.css';
77
import AddServerModal from '@/components/home/AddServerModal';
88
import AddChannelModal from '@/components/home/AddChannelModal';
9-
import { useGetServers, useServers } from '@/lib/store';
9+
import {
10+
useGetServers,
11+
useGetUserPermsForServer,
12+
useServers,
13+
useUserServerPerms,
14+
} from '@/lib/store';
1015
import { Tooltip } from 'react-tooltip';
1116
import PlusIcon from '@/components/icons/PlusIcon';
17+
import { ChannelPermissions, ServerPermissions } from '@/types/permissions';
1218

1319
export default function ServerList() {
1420
//TODO: Display default page (when user belongs to and has no servers)
@@ -24,6 +30,11 @@ export default function ServerList() {
2430
const servers = useServers();
2531
const getServers = useGetServers();
2632

33+
const getUserServerPerms = useGetUserPermsForServer();
34+
getUserServerPerms(supabase, expanded);
35+
const userServerPerms = useUserServerPerms();
36+
console.log(userServerPerms & ServerPermissions.OWNER);
37+
2738
useEffect(() => {
2839
if (getServers) {
2940
if (user) {
@@ -105,28 +116,32 @@ export default function ServerList() {
105116
}
106117
})}
107118
</div>
108-
<Tooltip
109-
className="z-20 !opacity-100 font-semibold "
110-
style={{
111-
backgroundColor: '#21282b',
112-
borderRadius: '0.5rem',
113-
fontSize: '1.125rem',
114-
lineHeight: '1.75rem',
115-
}}
116-
id="serverSettings"
117-
clickable
118-
openOnClick={true}
119-
>
120-
<div
121-
className="flex justify-center items-center hover:text-grey-300 cursor-pointer"
122-
onClick={() => {
123-
setShowAddChannelModal(true);
119+
{userServerPerms & ServerPermissions.MANAGE_MESSAGES ? (
120+
<Tooltip
121+
className="z-20 !opacity-100 font-semibold "
122+
style={{
123+
backgroundColor: '#21282b',
124+
borderRadius: '0.5rem',
125+
fontSize: '1.125rem',
126+
lineHeight: '1.75rem',
124127
}}
128+
id="serverSettings"
129+
clickable
130+
openOnClick={true}
125131
>
126-
<PlusIcon width={5} height={5} />
127-
<span className="ml-1">New channel</span>
128-
</div>
129-
</Tooltip>
132+
<div
133+
className="flex justify-center items-center hover:text-grey-300 cursor-pointer"
134+
onClick={() => {
135+
setShowAddChannelModal(true);
136+
}}
137+
>
138+
<PlusIcon width={5} height={5} />
139+
<span className="ml-1">New channel</span>
140+
</div>
141+
</Tooltip>
142+
) : (
143+
''
144+
)}
130145
</div>
131146
);
132147
}

lib/store.ts

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@ import {
88
} from '@/types/dbtypes';
99
import { Database } from '@/types/database.supabase';
1010
import { SupabaseClient } from '@supabase/supabase-js';
11-
import { getServerForUser, getServersForUser } from '@/services/server.service';
11+
import {
12+
getCurrentUserServerPermissions,
13+
getServerForUser,
14+
getServersForUser,
15+
} from '@/services/server.service';
1216
import {
1317
createMessage,
1418
getMessagesInChannelWithUser,
@@ -80,7 +84,10 @@ const useMessagesStore = create<MessagesState>()((set) => ({
8084
channelId: 0,
8185
setChannelId: (chId) => set((state) => ({ channelId: chId })),
8286
addMessage: async (supabase, messageId) => {
83-
const { data, error } = await getMessageWithServerProfile(supabase, messageId);
87+
const { data, error } = await getMessageWithServerProfile(
88+
supabase,
89+
messageId
90+
);
8491

8592
if (error) {
8693
console.error(error);
@@ -94,7 +101,10 @@ const useMessagesStore = create<MessagesState>()((set) => ({
94101
}
95102
},
96103
updateMessage: async (supabase, messageId) => {
97-
const { data, error } = await getMessageWithServerProfile(supabase, messageId);
104+
const { data, error } = await getMessageWithServerProfile(
105+
supabase,
106+
messageId
107+
);
98108

99109
if (error) {
100110
console.error(error);
@@ -141,11 +151,17 @@ const useMessagesStore = create<MessagesState>()((set) => ({
141151

142152
export interface UserPermsState {
143153
userPerms: any;
154+
userServerPerms: any;
144155
getUserPerms: (supabase: SupabaseClient<Database>, channelId: number) => void;
156+
getUserPermsForServer: (
157+
supabase: SupabaseClient<Database>,
158+
server_id: number
159+
) => void;
145160
}
146161

147162
const useUserPermsStore = create<UserPermsState>()((set) => ({
148163
userPerms: [],
164+
userServerPerms: [],
149165
getUserPerms: async (supabase, channelId) => {
150166
const { data, error } = await getCurrentUserChannelPermissions(
151167
supabase,
@@ -160,6 +176,20 @@ const useUserPermsStore = create<UserPermsState>()((set) => ({
160176
set({ userPerms: data });
161177
}
162178
},
179+
getUserPermsForServer: async (supabase, serverId) => {
180+
const { data, error } = await getCurrentUserServerPermissions(
181+
supabase,
182+
serverId
183+
);
184+
185+
if (error) {
186+
console.log(error);
187+
}
188+
// console.log('data', data);
189+
if (data) {
190+
set({ userServerPerms: data });
191+
}
192+
},
163193
}));
164194

165195
export interface ChannelState {
@@ -191,3 +221,7 @@ export const useGetUserPerms = () =>
191221
export const useUserPerms = () => useUserPermsStore((state) => state.userPerms);
192222
export const useSetChannel = () => useChannelStore((state) => state.setChannel);
193223
export const useChannel = () => useChannelStore((state) => state.channel);
224+
export const useGetUserPermsForServer = () =>
225+
useUserPermsStore((state) => state.getUserPermsForServer);
226+
export const useUserServerPerms = () =>
227+
useUserPermsStore((state) => state.userServerPerms);

services/channels.service.ts

Lines changed: 53 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ import { Database } from '@/types/database.supabase';
22
import { Channel } from '@/types/dbtypes';
33
import { SupabaseClient } from '@supabase/supabase-js';
44

5-
export async function getChannelById(supabase: SupabaseClient<Database>, channelId: number) {
5+
export async function getChannelById(
6+
supabase: SupabaseClient<Database>,
7+
channelId: number
8+
) {
69
return await supabase
710
.from('channels')
811
.select('*')
@@ -14,7 +17,10 @@ type ChannelByIdResponse = Awaited<ReturnType<typeof getChannelById>>;
1417
export type ChannelByIdResponseSuccess = ChannelByIdResponse['data'];
1518
export type ChannelByIdResponseError = ChannelByIdResponse['error'];
1619

17-
export async function getChannelsInServer(supabase: SupabaseClient<Database>, serverId: number) {
20+
export async function getChannelsInServer(
21+
supabase: SupabaseClient<Database>,
22+
serverId: number
23+
) {
1824
return await supabase
1925
.from('channels')
2026
.select('*')
@@ -27,7 +33,13 @@ type ChannelsInServerResponse = Awaited<ReturnType<typeof getChannelsInServer>>;
2733
export type ChannelsInServerResponseSuccess = ChannelsInServerResponse['data'];
2834
export type ChannelsInServerResponseError = ChannelsInServerResponse['error'];
2935

30-
export async function createChannel(supabase: SupabaseClient<Database>, serverId: number, name: string, desciption: string | null = null) {
36+
export async function createChannel(
37+
supabase: SupabaseClient<Database>,
38+
serverId: number,
39+
name: string,
40+
desciption: string | null = null,
41+
isMedia: boolean = false
42+
) {
3143
// Validate channel name is present
3244
if (!name) {
3345
return { data: null, error: 'Channel name is required' };
@@ -39,6 +51,7 @@ export async function createChannel(supabase: SupabaseClient<Database>, serverId
3951
server_id: serverId,
4052
name: name,
4153
description: desciption,
54+
is_media: isMedia,
4255
})
4356
.select()
4457
.single();
@@ -48,20 +61,24 @@ type CreateChannelResponse = Awaited<ReturnType<typeof createChannel>>;
4861
export type CreateChannelResponseSuccess = CreateChannelResponse['data'];
4962
export type CreateChannelResponseError = CreateChannelResponse['error'];
5063

51-
export async function deleteChannel(supabase: SupabaseClient<Database>, channelId: number) {
64+
export async function deleteChannel(
65+
supabase: SupabaseClient<Database>,
66+
channelId: number
67+
) {
5268
// NOTE: Supabase has been set up to cascade delete all messages in a channel when the channel is deleted
53-
return await supabase
54-
.from('channels')
55-
.delete()
56-
.eq('id', channelId)
57-
.single();
69+
return await supabase.from('channels').delete().eq('id', channelId).single();
5870
}
5971

6072
type DeleteChannelResponse = Awaited<ReturnType<typeof deleteChannel>>;
6173
export type DeleteChannelResponseSuccess = DeleteChannelResponse['data'];
6274
export type DeleteChannelResponseError = DeleteChannelResponse['error'];
6375

64-
export async function updateChannel(supabase: SupabaseClient<Database>, channelId: number, name: string, description: string | null) {
76+
export async function updateChannel(
77+
supabase: SupabaseClient<Database>,
78+
channelId: number,
79+
name: string,
80+
description: string | null
81+
) {
6582
return await supabase
6683
.from('channels')
6784
.update({
@@ -77,20 +94,34 @@ type UpdateChannelResponse = Awaited<ReturnType<typeof updateChannel>>;
7794
export type UpdateChannelResponseSuccess = UpdateChannelResponse['data'];
7895
export type UpdateChannelResponseError = UpdateChannelResponse['error'];
7996

80-
export async function getAllChannelsForUser(supabase: SupabaseClient<Database>, userId: string) {
81-
return await supabase
82-
.rpc('get_all_channels_for_user', { p_id: userId });
97+
export async function getAllChannelsForUser(
98+
supabase: SupabaseClient<Database>,
99+
userId: string
100+
) {
101+
return await supabase.rpc('get_all_channels_for_user', { p_id: userId });
83102
}
84103

85-
type AllChannelsForUserResponse = Awaited<ReturnType<typeof getAllChannelsForUser>>;
86-
export type AllChannelsForUserResponseSuccess = AllChannelsForUserResponse['data'];
87-
export type AllChannelsForUserResponseError = AllChannelsForUserResponse['error'];
104+
type AllChannelsForUserResponse = Awaited<
105+
ReturnType<typeof getAllChannelsForUser>
106+
>;
107+
export type AllChannelsForUserResponseSuccess =
108+
AllChannelsForUserResponse['data'];
109+
export type AllChannelsForUserResponseError =
110+
AllChannelsForUserResponse['error'];
88111

89-
export async function getCurrentUserChannelPermissions(supabase: SupabaseClient<Database>, channelId: number) {
90-
return await supabase
91-
.rpc('get_channel_permission_flags', { c_id: channelId });
112+
export async function getCurrentUserChannelPermissions(
113+
supabase: SupabaseClient<Database>,
114+
channelId: number
115+
) {
116+
return await supabase.rpc('get_channel_permission_flags', {
117+
c_id: channelId,
118+
});
92119
}
93120

94-
type CurrentUserChannelPermissionsResponse = Awaited<ReturnType<typeof getCurrentUserChannelPermissions>>;
95-
export type CurrentUserChannelPermissionsResponseSuccess = CurrentUserChannelPermissionsResponse['data'];
96-
export type CurrentUserChannelPermissionsResponseError = CurrentUserChannelPermissionsResponse['error'];
121+
type CurrentUserChannelPermissionsResponse = Awaited<
122+
ReturnType<typeof getCurrentUserChannelPermissions>
123+
>;
124+
export type CurrentUserChannelPermissionsResponseSuccess =
125+
CurrentUserChannelPermissionsResponse['data'];
126+
export type CurrentUserChannelPermissionsResponseError =
127+
CurrentUserChannelPermissionsResponse['error'];

0 commit comments

Comments
 (0)