@sendbird/uikit-utils 2.3.0 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/commonjs/hooks/index.js +38 -1
- package/lib/commonjs/hooks/index.js.map +1 -1
- package/lib/commonjs/hooks/react-native.js +5 -7
- package/lib/commonjs/hooks/react-native.js.map +1 -1
- package/lib/commonjs/index.js +25 -1
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/sendbird/channel.js +29 -1
- package/lib/commonjs/sendbird/channel.js.map +1 -1
- package/lib/commonjs/sendbird/message.js +56 -1
- package/lib/commonjs/sendbird/message.js.map +1 -1
- package/lib/commonjs/sendbird/user.js +0 -6
- package/lib/commonjs/sendbird/user.js.map +1 -1
- package/lib/commonjs/shared/index.js +12 -0
- package/lib/commonjs/shared/index.js.map +1 -1
- package/lib/commonjs/types.js.map +1 -1
- package/lib/commonjs/ui-format/openChannel.js +22 -0
- package/lib/commonjs/ui-format/openChannel.js.map +1 -0
- package/lib/module/hooks/index.js +29 -1
- package/lib/module/hooks/index.js.map +1 -1
- package/lib/module/hooks/react-native.js +6 -8
- package/lib/module/hooks/react-native.js.map +1 -1
- package/lib/module/index.js +8 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/sendbird/channel.js +23 -1
- package/lib/module/sendbird/channel.js.map +1 -1
- package/lib/module/sendbird/message.js +51 -1
- package/lib/module/sendbird/message.js.map +1 -1
- package/lib/module/sendbird/user.js +0 -4
- package/lib/module/sendbird/user.js.map +1 -1
- package/lib/module/shared/index.js +10 -0
- package/lib/module/shared/index.js.map +1 -1
- package/lib/module/types.js.map +1 -1
- package/lib/module/ui-format/openChannel.js +10 -0
- package/lib/module/ui-format/openChannel.js.map +1 -0
- package/lib/typescript/src/hooks/index.d.ts +3 -0
- package/lib/typescript/src/index.d.ts +7 -2
- package/lib/typescript/src/sendbird/channel.d.ts +10 -1
- package/lib/typescript/src/sendbird/message.d.ts +3 -0
- package/lib/typescript/src/sendbird/user.d.ts +0 -2
- package/lib/typescript/src/shared/index.d.ts +6 -0
- package/lib/typescript/src/types.d.ts +8 -3
- package/lib/typescript/src/ui-format/openChannel.d.ts +3 -0
- package/package.json +4 -4
- package/src/hooks/index.ts +31 -1
- package/src/hooks/react-native.ts +6 -8
- package/src/index.ts +17 -1
- package/src/sendbird/channel.ts +33 -2
- package/src/sendbird/message.ts +54 -1
- package/src/sendbird/user.ts +0 -7
- package/src/shared/index.ts +10 -0
- package/src/types.ts +17 -2
- package/src/ui-format/openChannel.ts +11 -0
package/src/hooks/index.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
2
|
import type { DependencyList } from 'react';
|
|
3
|
-
import { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react';
|
|
3
|
+
import { useCallback, useEffect, useLayoutEffect, useReducer, useRef, useState } from 'react';
|
|
4
4
|
|
|
5
5
|
type Destructor = () => void;
|
|
6
6
|
type AsyncEffectCallback = () => void | Destructor | Promise<void> | Promise<Destructor>;
|
|
@@ -13,6 +13,11 @@ export const useUniqId = (key: string) => {
|
|
|
13
13
|
})[0];
|
|
14
14
|
};
|
|
15
15
|
|
|
16
|
+
export const useUniqHandlerId = (name: string) => {
|
|
17
|
+
const id = useUniqId(name);
|
|
18
|
+
return `${name}_${id}`;
|
|
19
|
+
};
|
|
20
|
+
|
|
16
21
|
export const useForceUpdate = () => {
|
|
17
22
|
const [, updater] = useState(0);
|
|
18
23
|
return useCallback(() => updater((prev) => prev + 1), []);
|
|
@@ -72,3 +77,28 @@ export const useFreshCallback = <T extends (...args: any[]) => any>(callback: T)
|
|
|
72
77
|
ref.current = callback;
|
|
73
78
|
return useCallback(((...args) => ref.current(...args)) as T, []);
|
|
74
79
|
};
|
|
80
|
+
|
|
81
|
+
export const useDebounceEffect = (action: () => void, delay: number, deps: DependencyList = []) => {
|
|
82
|
+
const timeoutRef = useRef<NodeJS.Timeout>();
|
|
83
|
+
|
|
84
|
+
useEffect(() => {
|
|
85
|
+
timeoutRef.current = setTimeout(async () => {
|
|
86
|
+
try {
|
|
87
|
+
await action();
|
|
88
|
+
} finally {
|
|
89
|
+
timeoutRef.current = undefined;
|
|
90
|
+
}
|
|
91
|
+
}, delay);
|
|
92
|
+
|
|
93
|
+
return () => {
|
|
94
|
+
if (timeoutRef.current) {
|
|
95
|
+
clearTimeout(timeoutRef.current);
|
|
96
|
+
timeoutRef.current = undefined;
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
}, [delay, ...deps]);
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
export const usePartialState = <S>(initialState: S) => {
|
|
103
|
+
return useReducer((prev: S, state: Partial<S>) => ({ ...prev, ...state }), initialState);
|
|
104
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useEffect,
|
|
1
|
+
import { useEffect, useRef } from 'react';
|
|
2
2
|
import { AppState, AppStateEvent, AppStateStatus } from 'react-native';
|
|
3
3
|
import { EdgeInsets, useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
4
4
|
|
|
@@ -22,13 +22,11 @@ export const useSafeAreaPadding = <
|
|
|
22
22
|
edges: T[],
|
|
23
23
|
): Result => {
|
|
24
24
|
const safeAreaInsets = useSafeAreaInsets();
|
|
25
|
-
return
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}, {} as { [key in EdgePaddingMap[T]]: EdgeInsets[T] });
|
|
31
|
-
}, edges) as Result;
|
|
25
|
+
return edges.reduce((map, edge) => {
|
|
26
|
+
const paddingKey = edgePaddingMap[edge];
|
|
27
|
+
map[paddingKey] = safeAreaInsets[edge];
|
|
28
|
+
return map;
|
|
29
|
+
}, {} as { [key in EdgePaddingMap[T]]: EdgeInsets[T] }) as Result;
|
|
32
30
|
};
|
|
33
31
|
|
|
34
32
|
type AppStateListener = (status: AppStateStatus) => void;
|
package/src/index.ts
CHANGED
|
@@ -24,6 +24,7 @@ export * from './shared';
|
|
|
24
24
|
export * from './hooks';
|
|
25
25
|
export * from './hooks/react-native';
|
|
26
26
|
export * from './ui-format/groupChannel';
|
|
27
|
+
export * from './ui-format/openChannel';
|
|
27
28
|
export * from './ui-format/common';
|
|
28
29
|
export * from './sendbird/channel';
|
|
29
30
|
export * from './sendbird/message';
|
|
@@ -34,9 +35,19 @@ export const NOOP: () => void = () => void 0;
|
|
|
34
35
|
export const ASYNC_NOOP = async () => void 0;
|
|
35
36
|
export const PASS = <T>(val: T) => val;
|
|
36
37
|
export const toMegabyte = (byte: number) => byte / 1024 / 1024;
|
|
37
|
-
export const isFunction =
|
|
38
|
+
export const isFunction = (param?: unknown): param is Function => typeof param === 'function';
|
|
39
|
+
|
|
40
|
+
export function ifThenOr<T>(cond: boolean, then: T): T | undefined;
|
|
41
|
+
export function ifThenOr<T, V>(cond: boolean, then: T, or: V): T | V;
|
|
42
|
+
export function ifThenOr(cond: boolean, then: unknown, or?: unknown) {
|
|
43
|
+
if (cond) return then;
|
|
44
|
+
return or;
|
|
45
|
+
}
|
|
46
|
+
|
|
38
47
|
export const SBErrorCode = {
|
|
39
48
|
NON_AUTHORIZED: 400108,
|
|
49
|
+
CHANNEL_NOT_FOUND_SERVER: 400201,
|
|
50
|
+
CHANNEL_NOT_FOUND_SDK: 900500,
|
|
40
51
|
};
|
|
41
52
|
export const SBErrorMessage = {
|
|
42
53
|
ACL:
|
|
@@ -54,6 +65,7 @@ export type {
|
|
|
54
65
|
PartialDeep,
|
|
55
66
|
Optional,
|
|
56
67
|
ContextValue,
|
|
68
|
+
OnBeforeHandler,
|
|
57
69
|
SendbirdMessage,
|
|
58
70
|
SendbirdChatSDK,
|
|
59
71
|
SendbirdChannel,
|
|
@@ -79,6 +91,7 @@ export type {
|
|
|
79
91
|
SendbirdDataPayload,
|
|
80
92
|
SendbirdPreviousMessageListQuery,
|
|
81
93
|
SendbirdSendableMessage,
|
|
94
|
+
SendbirdOpenChannelListQuery,
|
|
82
95
|
SendbirdGroupChannelListQuery,
|
|
83
96
|
SendbirdGroupChannelUpdateParams,
|
|
84
97
|
SendbirdUserMessageUpdateParams,
|
|
@@ -89,4 +102,7 @@ export type {
|
|
|
89
102
|
SendbirdEmojiContainer,
|
|
90
103
|
SendbirdEmoji,
|
|
91
104
|
SendbirdEmojiCategory,
|
|
105
|
+
SendbirdOpenChannelUpdateParams,
|
|
106
|
+
SendbirdOpenChannelCreateParams,
|
|
107
|
+
SendbirdParticipant,
|
|
92
108
|
} from './types';
|
package/src/sendbird/channel.ts
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { BufferedRequest } from '../shared/bufferedRequest';
|
|
2
|
-
import type {
|
|
2
|
+
import type {
|
|
3
|
+
SendbirdBaseChannel,
|
|
4
|
+
SendbirdChannel,
|
|
5
|
+
SendbirdGroupChannel,
|
|
6
|
+
SendbirdGroupChannelCreateParams,
|
|
7
|
+
SendbirdOpenChannel,
|
|
8
|
+
} from '../types';
|
|
3
9
|
|
|
4
10
|
/**
|
|
5
11
|
* Diff utils for channel
|
|
@@ -13,12 +19,21 @@ export function isDifferentChannel<T extends SendbirdBaseChannel>(a?: T, b?: T):
|
|
|
13
19
|
}
|
|
14
20
|
|
|
15
21
|
export const getGroupChannelChatAvailableState = (channel: SendbirdGroupChannel) => {
|
|
16
|
-
const
|
|
22
|
+
const isOperator = channel.myRole === 'operator';
|
|
23
|
+
const frozen = channel.isFrozen && !isOperator;
|
|
17
24
|
const muted = channel.myMutedState === 'muted';
|
|
18
25
|
const disabled = frozen || muted;
|
|
19
26
|
return { disabled, frozen, muted };
|
|
20
27
|
};
|
|
21
28
|
|
|
29
|
+
export const getOpenChannelChatAvailableState = async (channel: SendbirdOpenChannel, userId: string) => {
|
|
30
|
+
const isOperator = channel.isOperator(userId);
|
|
31
|
+
const frozen = channel.isFrozen && !isOperator;
|
|
32
|
+
const muted = (await channel.getMyMutedInfo()).isMuted;
|
|
33
|
+
const disabled = frozen || muted;
|
|
34
|
+
return { disabled, frozen, muted };
|
|
35
|
+
};
|
|
36
|
+
|
|
22
37
|
export const confirmAndMarkAsRead = async (channels: SendbirdBaseChannel[]) => {
|
|
23
38
|
channels
|
|
24
39
|
.filter((it): it is SendbirdGroupChannel => it.isGroupChannel() && it.unreadMessageCount > 0)
|
|
@@ -50,3 +65,19 @@ export function getOpenChannels(channels: SendbirdChannel[]): SendbirdOpenChanne
|
|
|
50
65
|
export function getChannelUniqId(channel: SendbirdChannel) {
|
|
51
66
|
return channel.url;
|
|
52
67
|
}
|
|
68
|
+
|
|
69
|
+
export function getDefaultGroupChannelCreateParams(params: {
|
|
70
|
+
invitedUserIds: string[];
|
|
71
|
+
currentUserId?: string;
|
|
72
|
+
}): SendbirdGroupChannelCreateParams {
|
|
73
|
+
const createParams: SendbirdGroupChannelCreateParams = {
|
|
74
|
+
name: '',
|
|
75
|
+
coverUrl: '',
|
|
76
|
+
isDistinct: false,
|
|
77
|
+
invitedUserIds: params.invitedUserIds,
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
if (params.currentUserId) createParams.operatorUserIds = [params.currentUserId];
|
|
81
|
+
|
|
82
|
+
return createParams;
|
|
83
|
+
}
|
package/src/sendbird/message.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getFileExtension, getFileType } from '../shared/regex';
|
|
1
2
|
import type {
|
|
2
3
|
SendbirdBaseChannel,
|
|
3
4
|
SendbirdBaseMessage,
|
|
@@ -114,9 +115,61 @@ export function parseSendbirdNotification(dataPayload: RawSendbirdDataPayload):
|
|
|
114
115
|
}
|
|
115
116
|
|
|
116
117
|
export function shouldRenderReaction(channel: SendbirdBaseChannel, reactionEnabled: boolean) {
|
|
117
|
-
|
|
118
|
+
if (channel.isOpenChannel()) {
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (channel.isGroupChannel()) {
|
|
123
|
+
if (channel.isBroadcast) return false;
|
|
124
|
+
if (channel.isSuper) return false;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return reactionEnabled;
|
|
118
128
|
}
|
|
119
129
|
|
|
120
130
|
export function getReactionCount(reaction: SendbirdReaction) {
|
|
121
131
|
return reaction.userIds.length;
|
|
122
132
|
}
|
|
133
|
+
|
|
134
|
+
type MessageType =
|
|
135
|
+
| 'user'
|
|
136
|
+
| 'admin'
|
|
137
|
+
| 'file'
|
|
138
|
+
| 'unknown'
|
|
139
|
+
| `user.${'opengraph'}`
|
|
140
|
+
| `file.${'image' | 'video' | 'audio'}`;
|
|
141
|
+
|
|
142
|
+
export function getFileTypeFromMessage(message: SendbirdFileMessage) {
|
|
143
|
+
return getFileType(message.type || getFileExtension(message.name));
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export function getMessageType(message: SendbirdMessage): MessageType {
|
|
147
|
+
if (message.isAdminMessage()) {
|
|
148
|
+
return 'admin';
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (message.isUserMessage()) {
|
|
152
|
+
if (message.ogMetaData) {
|
|
153
|
+
return 'user.opengraph';
|
|
154
|
+
}
|
|
155
|
+
return 'user';
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (message.isFileMessage()) {
|
|
159
|
+
const fileType = getFileTypeFromMessage(message);
|
|
160
|
+
switch (fileType) {
|
|
161
|
+
case 'image':
|
|
162
|
+
case 'video': {
|
|
163
|
+
return `file.${fileType}`;
|
|
164
|
+
}
|
|
165
|
+
case 'audio': {
|
|
166
|
+
return `file.${fileType}`;
|
|
167
|
+
}
|
|
168
|
+
default: {
|
|
169
|
+
return 'file';
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return 'unknown';
|
|
175
|
+
}
|
package/src/sendbird/user.ts
CHANGED
|
@@ -9,13 +9,6 @@ export function ifOperator(role: Role, then: unknown, or?: unknown) {
|
|
|
9
9
|
return or;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
export function ifMuted<T>(muted: boolean, then: T): T | undefined;
|
|
13
|
-
export function ifMuted<T, V>(muted: boolean, then: T, or: V): T | V;
|
|
14
|
-
export function ifMuted(muted: boolean, then: unknown, or?: unknown) {
|
|
15
|
-
if (muted) return then;
|
|
16
|
-
return or;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
12
|
export function getUserUniqId<T extends UserStruct>(user: T) {
|
|
20
13
|
return user.userId;
|
|
21
14
|
}
|
package/src/shared/index.ts
CHANGED
|
@@ -54,3 +54,13 @@ export function shouldCompressImage(filePath: string, compressionEnabled = true)
|
|
|
54
54
|
const extension = getFileExtension(filePath);
|
|
55
55
|
return Boolean(extension.match(/jpg|jpeg|png/i) && compressionEnabled);
|
|
56
56
|
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Returns the picked data from object.
|
|
60
|
+
* */
|
|
61
|
+
export function pick<T extends { [key: string]: unknown }, Keys extends keyof T>(obj: T, keys: Keys[]) {
|
|
62
|
+
return keys.reduce((pickedObj, key) => {
|
|
63
|
+
pickedObj[key] = obj[key];
|
|
64
|
+
return pickedObj;
|
|
65
|
+
}, {} as { [key in Keys]: T[key] });
|
|
66
|
+
}
|
package/src/types.ts
CHANGED
|
@@ -9,6 +9,7 @@ import type {
|
|
|
9
9
|
Emoji,
|
|
10
10
|
EmojiCategory,
|
|
11
11
|
EmojiContainer,
|
|
12
|
+
Participant,
|
|
12
13
|
RestrictedUser,
|
|
13
14
|
SendbirdError as SBError,
|
|
14
15
|
User,
|
|
@@ -24,7 +25,12 @@ import type {
|
|
|
24
25
|
Member,
|
|
25
26
|
MessageCollection,
|
|
26
27
|
} from '@sendbird/chat/groupChannel';
|
|
27
|
-
import type {
|
|
28
|
+
import type {
|
|
29
|
+
ModuleNamespaces,
|
|
30
|
+
OpenChannelCreateParams,
|
|
31
|
+
OpenChannelUpdateParams,
|
|
32
|
+
SendableMessage,
|
|
33
|
+
} from '@sendbird/chat/lib/__definition';
|
|
28
34
|
import type {
|
|
29
35
|
AdminMessage,
|
|
30
36
|
BaseMessage,
|
|
@@ -37,7 +43,7 @@ import type {
|
|
|
37
43
|
UserMessageCreateParams,
|
|
38
44
|
UserMessageUpdateParams,
|
|
39
45
|
} from '@sendbird/chat/message';
|
|
40
|
-
import type { OpenChannel, OpenChannelModule } from '@sendbird/chat/openChannel';
|
|
46
|
+
import type { OpenChannel, OpenChannelListQuery, OpenChannelModule } from '@sendbird/chat/openChannel';
|
|
41
47
|
|
|
42
48
|
export type FilterByValueType<T extends object, Type> = {
|
|
43
49
|
[K in keyof T as T[K] extends Type ? K : never]: T[K];
|
|
@@ -65,6 +71,8 @@ export type Optional<T> = T | undefined;
|
|
|
65
71
|
|
|
66
72
|
export type ContextValue<T extends React.Context<any>> = T extends React.Context<infer V> ? V : never;
|
|
67
73
|
|
|
74
|
+
export type OnBeforeHandler<T> = (params: T) => T | Promise<T>;
|
|
75
|
+
|
|
68
76
|
export interface UserStruct {
|
|
69
77
|
userId: string;
|
|
70
78
|
}
|
|
@@ -81,12 +89,18 @@ export type SendbirdFileMessageCreateParams = FileMessageCreateParams;
|
|
|
81
89
|
export type SendbirdFileMessageUpdateParams = FileMessageUpdateParams;
|
|
82
90
|
export type SendbirdUserMessageCreateParams = UserMessageCreateParams;
|
|
83
91
|
export type SendbirdUserMessageUpdateParams = UserMessageUpdateParams;
|
|
92
|
+
|
|
84
93
|
export type SendbirdGroupChannelCreateParams = GroupChannelCreateParams;
|
|
85
94
|
export type SendbirdGroupChannelUpdateParams = GroupChannelUpdateParams;
|
|
95
|
+
export type SendbirdOpenChannelCreateParams = OpenChannelCreateParams;
|
|
96
|
+
export type SendbirdOpenChannelUpdateParams = OpenChannelUpdateParams;
|
|
97
|
+
|
|
86
98
|
export type SendbirdUserUpdateParams = UserUpdateParams;
|
|
87
99
|
export type SendbirdUser = User;
|
|
88
100
|
export type SendbirdRestrictedUser = RestrictedUser;
|
|
89
101
|
export type SendbirdMember = Member;
|
|
102
|
+
export type SendbirdParticipant = Participant;
|
|
103
|
+
|
|
90
104
|
export type SendbirdGroupChannel = GroupChannel;
|
|
91
105
|
export type SendbirdBaseChannel = BaseChannel;
|
|
92
106
|
export type SendbirdOpenChannel = OpenChannel;
|
|
@@ -98,6 +112,7 @@ export type SendbirdEmojiContainer = EmojiContainer;
|
|
|
98
112
|
|
|
99
113
|
export type SendbirdGroupChannelCollection = GroupChannelCollection;
|
|
100
114
|
export type SendbirdGroupChannelListQuery = GroupChannelListQuery;
|
|
115
|
+
export type SendbirdOpenChannelListQuery = OpenChannelListQuery;
|
|
101
116
|
export type SendbirdMessageCollection = MessageCollection;
|
|
102
117
|
export type SendbirdPreviousMessageListQuery = PreviousMessageListQuery;
|
|
103
118
|
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { SendbirdOpenChannel } from '../types';
|
|
2
|
+
|
|
3
|
+
export const getOpenChannelTitle = (channel: SendbirdOpenChannel, DEFAULT_CHANNEL_NAME = 'Open Channel') => {
|
|
4
|
+
const trimmedChannelName = channel.name.trim();
|
|
5
|
+
if (trimmedChannelName === '') return DEFAULT_CHANNEL_NAME;
|
|
6
|
+
return trimmedChannelName;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export const getOpenChannelParticipants = (channel: SendbirdOpenChannel) => {
|
|
10
|
+
return `${channel.participantCount} participants`;
|
|
11
|
+
};
|