Skip to content

Commit 1d070cd

Browse files
committed
- chore: setup and apply prettier/eslint
- chore: theming base setup
1 parent a54de63 commit 1d070cd

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+621
-148
lines changed

.eslintignore

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
node_modules
2+
lib
3+
android
4+
ios

.eslintrc.js

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
module.exports = {
2+
'env': {
3+
'es2021': true
4+
},
5+
'extends': ['eslint:recommended', 'plugin:@typescript-eslint/recommended'],
6+
'parser': '@typescript-eslint/parser',
7+
'parserOptions': {
8+
'ecmaVersion': 12,
9+
'sourceType': 'module'
10+
},
11+
'plugins': ['@typescript-eslint'],
12+
'rules': {
13+
'linebreak-style': [2, 'unix'],
14+
'no-console': 1,
15+
'curly': [1, 'multi-line'],
16+
'semi': [1, 'always'],
17+
'quotes': [1, 'single'],
18+
'arrow-parens': [1, 'always'],
19+
'eol-last': [1, 'always'],
20+
'multiline-ternary': [1, 'always-multiline'],
21+
'no-nested-ternary': 1,
22+
'comma-dangle': [1, 'always-multiline'],
23+
'@typescript-eslint/ban-types': 0
24+
}
25+
};

.prettierrc

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"printWidth": 120,
3+
"tabWidth": 2,
4+
"useTabs": false,
5+
"semi": true,
6+
"singleQuote": true,
7+
"quoteProps": "preserve",
8+
"trailingComma": "all",
9+
"bracketSpacing": true,
10+
"arrowParens": "always",
11+
"importOrder": ["<THIRD_PARTY_MODULES>", "@sendbird[./]?", "^[./]"],
12+
"importOrderSeparation": true,
13+
"importOrderSortSpecifiers": true,
14+
"importOrderCaseInsensitive": false
15+
}

package.json

+6-1
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,14 @@
2222
"w": "sh -c 'yarn workspace ${0} ${1} ${2} ${3}'",
2323
"w:create": "npx create-react-native-library",
2424
"w:clean": "lerna run clean",
25-
"w:build": "lerna run prepare"
25+
"w:build": "lerna run prepare",
26+
"w:lint:eslint": "eslint packages/**/src --ext ts,tsx ",
27+
"w:lint:prettier": "prettier --check packages/**/src/**/*.{ts,tsx}",
28+
"fix:eslint": "eslint --fix sample packages/**/src --ext ts,tsx -c ./.eslintrc.js",
29+
"fix:prettier": "prettier --write sample/src/**.{ts,tsx} packages/**/src/**/*.{ts,tsx}"
2630
},
2731
"devDependencies": {
32+
"@trivago/prettier-plugin-sort-imports": "^3.1.1",
2833
"@types/jest": "^27.4.0",
2934
"@typescript-eslint/eslint-plugin": "^5.9.1",
3035
"@typescript-eslint/parser": "^5.9.1",

packages/chat-react-hooks/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"lib",
1313
"!**/__tests__"
1414
],
15+
"sideEffects": false,
1516
"scripts": {
1617
"test": "jest",
1718
"prepare": "bob build",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
2+
import type Sendbird from 'sendbird';
3+
4+
import type { GroupChannelListHook } from '../types';
5+
import { arrayToMap } from '../utils';
6+
7+
type GroupChannelMap = Record<string, Sendbird.GroupChannel>;
8+
type Options = {
9+
comparator: (a: Sendbird.GroupChannel, b: Sendbird.GroupChannel) => number;
10+
query: Sendbird.GroupChannelListQuery;
11+
};
12+
13+
const createDefaultGroupChannelListQuery = (sdk: Sendbird.SendBirdInstance) => {
14+
const query = sdk.GroupChannel.createMyGroupChannelListQuery();
15+
query.memberStateFilter = 'all';
16+
query.order = 'latest_last_message';
17+
query.includeEmpty = true;
18+
query.limit = 10;
19+
20+
return query;
21+
};
22+
23+
const useGroupChannelList = (
24+
sdk: Sendbird.SendBirdInstance,
25+
userId: string,
26+
options?: Options,
27+
): GroupChannelListHook => {
28+
const queryRef = useRef(options?.query);
29+
const [groupChannelMap, setGroupChannelMap] = useState<GroupChannelMap>({});
30+
31+
const init = useCallback(
32+
async (uid: string) => {
33+
if (uid) {
34+
let groupQuery = options?.query;
35+
if (!groupQuery) groupQuery = createDefaultGroupChannelListQuery(sdk);
36+
queryRef.current = groupQuery;
37+
38+
const channels = await groupQuery.next();
39+
setGroupChannelMap((prev) => ({
40+
...prev,
41+
...arrayToMap(channels, 'url'),
42+
}));
43+
channels.forEach((channel) => sdk.markAsDelivered(channel.url));
44+
} else {
45+
setGroupChannelMap({});
46+
}
47+
},
48+
[sdk, options?.query],
49+
);
50+
51+
useEffect(() => {
52+
init(userId);
53+
}, [init, userId]);
54+
55+
const groupChannels = useMemo(
56+
() => Object.values(groupChannelMap).sort(options?.comparator),
57+
[groupChannelMap, options?.comparator],
58+
);
59+
60+
const refresh = useCallback(() => init(userId), [init, userId]);
61+
62+
const update = useCallback(
63+
(channel: Sendbird.GroupChannel) => {
64+
sdk.markAsDelivered(channel.url);
65+
setGroupChannelMap((prev) => ({ ...prev, [channel.url]: channel }));
66+
},
67+
[sdk],
68+
);
69+
70+
const loadPrev = useCallback(async () => {
71+
if (queryRef.current?.hasNext) {
72+
const channels = await queryRef.current.next();
73+
setGroupChannelMap((prev) => ({
74+
...prev,
75+
...arrayToMap(channels, 'url'),
76+
}));
77+
channels.forEach((channel) => sdk.markAsDelivered(channel.url));
78+
}
79+
}, [sdk]);
80+
return { groupChannels, update, refresh, loadPrev };
81+
};
82+
83+
export default useGroupChannelList;
+1-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1 @@
1-
export function chatReactHooksMultiply(a: number, b: number): Promise<number> {
2-
return Promise.resolve(a * b);
3-
}
4-
5-
import Sendbird from "sendbird";
6-
export default Sendbird;
1+
export { default as useGroupChannelList } from './channel/useGroupChannelList';
+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import type Sendbird from 'sendbird';
2+
3+
export type FilterByValueType<T extends object, Type> = {
4+
[K in keyof T as T[K] extends Type ? K : never]: T[K];
5+
};
6+
7+
export interface GroupChannelListHook {
8+
groupChannels: Sendbird.GroupChannel[];
9+
update: (channel: Sendbird.GroupChannel) => void;
10+
loadPrev: () => Promise<void>;
11+
refresh: () => Promise<void>;
12+
}
+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import type { FilterByValueType } from './types';
2+
3+
export function arrayToMap<T extends Record<K, unknown>, K extends keyof T = keyof T>(
4+
arr: T[],
5+
selector: K,
6+
fallbackSelector: K,
7+
): Record<string, T>;
8+
9+
export function arrayToMap<T extends Record<K, unknown>, K extends keyof T = keyof T>(
10+
arr: T[],
11+
selector: keyof FilterByValueType<T, string | number>,
12+
): Record<string, T>;
13+
14+
export function arrayToMap<T extends Record<K, unknown>, K extends keyof T = keyof T>(
15+
arr: T[],
16+
selector: K,
17+
fallbackSelector?: K,
18+
) {
19+
return arr.reduce((accum, curr) => {
20+
const _key = (curr[selector] || curr[fallbackSelector as K]) as string;
21+
accum[_key] = curr;
22+
23+
return accum;
24+
}, {} as Record<string, T>);
25+
}

packages/uikit-react-core/src/index.tsx

-7
This file was deleted.

packages/uikit-react-core/README.md renamed to packages/uikit-react-native-core/README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@ react-native-uikit
55
## Installation
66

77
```sh
8-
npm install @sendbird/uikit-react-core
8+
npm install @sendbird/uikit-react-native-core
99
```
1010

1111
## Usage
1212

1313
```js
14-
import { multiply } from "@sendbird/uikit-react-core";
14+
import { multiply } from "@sendbird/uikit-react-native-core";
1515

1616
// ...
1717

packages/uikit-react-core/package.json renamed to packages/uikit-react-native-core/package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"name": "@sendbird/uikit-react-core",
2+
"name": "@sendbird/uikit-react-native-core",
33
"version": "0.1.0",
44
"description": "SendbirdUIKit Core utilities for building UIKit",
55
"main": "lib/commonjs/index",
@@ -12,6 +12,7 @@
1212
"lib",
1313
"!**/__tests__"
1414
],
15+
"sideEffects": false,
1516
"scripts": {
1617
"test": "jest",
1718
"prepare": "bob build",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export async function multiply(a: number, b: number): Promise<number> {
2+
return a * b;
3+
}

packages/uikit-react-native/package.json

+4
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"lib",
1313
"!**/__tests__"
1414
],
15+
"sideEffects": false,
1516
"scripts": {
1617
"test": "jest",
1718
"prepare": "bob build",
@@ -35,6 +36,9 @@
3536
"publishConfig": {
3637
"registry": "https://registry.npmjs.org/"
3738
},
39+
"dependencies": {
40+
"@sendbird/uikit-react-native-core": "0.1.0"
41+
},
3842
"devDependencies": {
3943
"@types/react": "^16.9.19",
4044
"@types/react-native": "0.62.13",
+7-19
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,8 @@
1-
import React from "react";
1+
export { default as UIKitThemeContext } from './theme/UIKitThemeContext';
2+
export { default as UIKitThemeProvider } from './theme/UIKitThemeProvider';
3+
export { default as useUIKitTheme } from './theme/useUIKitTheme';
4+
export { default as LightUIKitTheme } from './theme/LightUIKitTheme';
5+
export { default as DarkUIKitTheme } from './theme/DarkUIKitTheme';
6+
export { default as Palette } from './theme/Palette';
27

3-
export function multiply(a: number, b: number): Promise<number> {
4-
return Promise.resolve(a * b);
5-
}
6-
7-
const UIKitThemeContext = React.createContext<{
8-
appearance: "light" | "dark";
9-
} | null>(null);
10-
11-
export const UIKitThemeProvider: React.FC<{ appearance: "dark" | "light" }> = ({
12-
children,
13-
appearance,
14-
}) => {
15-
return (
16-
<UIKitThemeContext.Provider value={{ appearance }}>
17-
{children}
18-
</UIKitThemeContext.Provider>
19-
);
20-
};
8+
export type { AppearanceHelper, UIKitColors, UIKitTheme, UIKitAppearance, InputState, ButtonState } from './types';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import type { UIKitTheme } from '../types';
2+
import appearanceHelperFactory from '../utils/appearanceHelper';
3+
import Palette from './Palette';
4+
5+
const appearance = 'dark';
6+
const DarkUIKitTheme: UIKitTheme = {
7+
...appearanceHelperFactory(appearance),
8+
appearance,
9+
palette: Palette,
10+
colors: {
11+
primary: Palette.primary200,
12+
background: Palette.background600,
13+
card: Palette.background400,
14+
text: Palette.onBackgroundDark01,
15+
border: Palette.onBackgroundDark04,
16+
notification: Palette.error200,
17+
onBackground01: Palette.onBackgroundDark01,
18+
onBackground02: Palette.onBackgroundDark02,
19+
onBackground03: Palette.onBackgroundDark03,
20+
onBackground04: Palette.onBackgroundDark04,
21+
onBackgroundReverse01: Palette.onBackgroundLight01,
22+
onBackgroundReverse02: Palette.onBackgroundLight02,
23+
onBackgroundReverse03: Palette.onBackgroundLight03,
24+
onBackgroundReverse04: Palette.onBackgroundLight04,
25+
secondary: Palette.secondary200,
26+
error: Palette.error200,
27+
ui: {
28+
input: {
29+
text: Palette.onBackgroundDark01,
30+
background: Palette.background400,
31+
placeholder: {
32+
active: Palette.onBackgroundDark03,
33+
disabled: Palette.onBackgroundDark04,
34+
},
35+
},
36+
button: {
37+
contained: {
38+
background: {
39+
enabled: Palette.primary200,
40+
pressed: Palette.primary300,
41+
disabled: Palette.background500,
42+
},
43+
text: {
44+
enabled: Palette.onBackgroundLight01,
45+
pressed: Palette.onBackgroundLight01,
46+
disabled: Palette.onBackgroundDark04,
47+
},
48+
},
49+
text: {
50+
background: {
51+
enabled: Palette.transparent,
52+
pressed: Palette.background500,
53+
disabled: Palette.transparent,
54+
},
55+
text: {
56+
enabled: Palette.primary200,
57+
pressed: Palette.primary200,
58+
disabled: Palette.onBackgroundDark04,
59+
},
60+
},
61+
},
62+
},
63+
},
64+
};
65+
66+
export default DarkUIKitTheme;

0 commit comments

Comments
 (0)