Skip to content

Commit

Permalink
feat: add announcement banner (#256)(#266)
Browse files Browse the repository at this point in the history
  • Loading branch information
mikitabut authored Nov 30, 2023
1 parent 8a14c43 commit b403788
Show file tree
Hide file tree
Showing 8 changed files with 113 additions and 12 deletions.
3 changes: 3 additions & 0 deletions .env.development
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,6 @@ REQUEST_API_KEY_CODE=""

## Warning regarding code generation
CODE_GENERATION_WARNING="Full responsibility for code correctness, security and licensing lies solely with the user, not with DIAL platform or LLM vendor."

## Text for announcement banner
ANNOUNCEMENT="Welcome to AI Dial Chat application!"
38 changes: 38 additions & 0 deletions src/components/Common/AnnouncementBanner.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { IconSpeakerphone, IconX } from '@tabler/icons-react';

import { useAppDispatch, useAppSelector } from '@/src/store/hooks';
import { SettingsSelectors } from '@/src/store/settings/settings.reducers';
import { UIActions, UISelectors } from '@/src/store/ui/ui.reducers';

export const AnnouncementsBanner = () => {
const dispatch = useAppDispatch();
const textOfClosedAnnouncement = useAppSelector(
UISelectors.selectTextOfClosedAnnouncement,
);
const announcement = useAppSelector(SettingsSelectors.selectAnnouncement);

if (
!announcement ||
textOfClosedAnnouncement === undefined ||
textOfClosedAnnouncement === announcement
) {
return null;
}

return (
<div className="relative flex items-center justify-center bg-gradient-to-r from-green to-violet text-gray-100">
<div className="flex grow items-center justify-center gap-2 py-2 pl-2 pr-8 text-center md:gap-3 md:px-14">
<IconSpeakerphone size={24} strokeWidth={1.5} className="shrink-0" />
<span dangerouslySetInnerHTML={{ __html: announcement }}></span>
</div>
<button
className="absolute right-2 top-[calc(50%_-_12px)] shrink-0"
onClick={() => {
dispatch(UIActions.closeAnnouncement({ announcement }));
}}
>
<IconX size={24} strokeWidth={1.5} />
</button>
</div>
);
};
5 changes: 4 additions & 1 deletion src/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { UISelectors } from '@/src/store/ui/ui.reducers';

import { authOptions } from '@/src/pages/api/auth/[...nextauth]';

import { AnnouncementsBanner } from '../components/Common/AnnouncementBanner';
import { Chat } from '@/src/components/Chat/Chat';
import { Chatbar } from '@/src/components/Chatbar/Chatbar';
import Header from '@/src/components/Header/Header';
Expand Down Expand Up @@ -150,7 +151,8 @@ export default function Home({ initialState }: Props) {
<div className="flex w-full grow overflow-auto">
{enabledFeatures.has(Feature.ConversationsSection) && <Chatbar />}

<div className="flex min-w-0 flex-1">
<div className="flex min-w-0 flex-1 flex-col">
<AnnouncementsBanner />
<Chat />
</div>

Expand Down Expand Up @@ -208,6 +210,7 @@ export const getServerSideProps: GetServerSideProps = async ({
),
isAuthDisabled: process.env.AUTH_DISABLED === 'true',
storageType: process.env.STORAGE_TYPE || 'browserStorage',
announcement: process.env.ANNOUNCEMENT || '',
};

return {
Expand Down
6 changes: 6 additions & 0 deletions src/store/settings/settings.reducers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export interface SettingsState {
footerHtmlMessage: string;
enabledFeatures: Feature[];
codeWarning: string;
announcement: string;
defaultModelId: string | undefined;
defaultRecentModelsIds: string[];
defaultRecentAddonsIds: string[];
Expand All @@ -26,6 +27,7 @@ const initialState: SettingsState = {
footerHtmlMessage: '',
enabledFeatures: [],
codeWarning: '',
announcement: '',
defaultModelId: undefined,
defaultRecentModelsIds: [],
defaultRecentAddonsIds: [],
Expand Down Expand Up @@ -144,6 +146,9 @@ const selectIsAuthDisabled = createSelector([rootSelector], (state) => {
const selectStorageType = createSelector([rootSelector], (state) => {
return state.storageType;
});
const selectAnnouncement = createSelector([rootSelector], (state) => {
return state.announcement;
});

export const SettingsActions = settingsSlice.actions;
export const SettingsSelectors = {
Expand All @@ -158,4 +163,5 @@ export const SettingsSelectors = {
selectDefaultRecentAddonsIds,
selectIsAuthDisabled,
selectStorageType,
selectAnnouncement,
};
44 changes: 34 additions & 10 deletions src/store/ui/ui.epics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,32 @@ const initEpic: AppEpic = (action$) =>
showChatbar: DataService.getShowChatbar(),
showPromptbar: DataService.getShowPromptbar(),
openedFoldersIds: DataService.getOpenedFolderIds(),
textOfClosedAnnouncement: DataService.getClosedAnnouncement(),
}),
),
switchMap(({ theme, openedFoldersIds, showChatbar, showPromptbar }) => {
const actions = [];

actions.push(UIActions.setTheme(theme));
actions.push(UIActions.setShowChatbar(showChatbar));
actions.push(UIActions.setShowPromptbar(showPromptbar));
actions.push(UIActions.setOpenedFoldersIds(openedFoldersIds));

return concat(actions);
}),
switchMap(
({
theme,
openedFoldersIds,
showChatbar,
showPromptbar,
textOfClosedAnnouncement,
}) => {
const actions = [];

actions.push(UIActions.setTheme(theme));
actions.push(UIActions.setShowChatbar(showChatbar));
actions.push(UIActions.setShowPromptbar(showPromptbar));
actions.push(UIActions.setOpenedFoldersIds(openedFoldersIds));
actions.push(
UIActions.closeAnnouncement({
announcement: textOfClosedAnnouncement,
}),
);

return concat(actions);
},
),
);

const saveThemeEpic: AppEpic = (action$) =>
Expand Down Expand Up @@ -109,6 +123,15 @@ const showToastErrorEpic: AppEpic = (action$) =>
ignoreElements(),
);

const closeAnnouncementEpic: AppEpic = (action$) =>
action$.pipe(
filter(UIActions.closeAnnouncement.match),
switchMap(({ payload }) =>
DataService.setClosedAnnouncement(payload.announcement),
),
ignoreElements(),
);

const saveOpenedFoldersIdsEpic: AppEpic = (action$, state$) =>
action$.pipe(
filter(
Expand All @@ -135,6 +158,7 @@ const UIEpics = combineEpics(
saveShowPromptbarEpic,
showToastErrorEpic,
saveOpenedFoldersIdsEpic,
closeAnnouncementEpic,
);

export default UIEpics;
15 changes: 15 additions & 0 deletions src/store/ui/ui.reducers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export interface UIState {
isProfileOpen: boolean;
isCompareMode: boolean;
openedFoldersIds: string[];
textOfClosedAnnouncement?: string | undefined;
}

const initialState: UIState = {
Expand All @@ -22,6 +23,7 @@ const initialState: UIState = {
isProfileOpen: false,
isCompareMode: false,
openedFoldersIds: [],
textOfClosedAnnouncement: undefined,
};

export const uiSlice = createSlice({
Expand Down Expand Up @@ -101,6 +103,12 @@ export const uiSlice = createSlice({
);
}
},
closeAnnouncement: (
state,
{ payload }: PayloadAction<{ announcement: string | undefined }>,
) => {
state.textOfClosedAnnouncement = payload.announcement;
},
},
});

Expand Down Expand Up @@ -139,6 +147,12 @@ const selectIsFolderOpened = createSelector(
return ids.includes(id);
},
);
const selectTextOfClosedAnnouncement = createSelector(
[rootSelector],
(state) => {
return state.textOfClosedAnnouncement;
},
);

export const UIActions = uiSlice.actions;

Expand All @@ -151,4 +165,5 @@ export const UISelectors = {
selectIsCompareMode,
selectOpenedFoldersIds,
selectIsFolderOpened,
selectTextOfClosedAnnouncement,
};
11 changes: 11 additions & 0 deletions src/utils/app/data/data-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,17 @@ export class DataService {
): Observable<void> {
return BrowserStorage.setData('openedFoldersIds', openedFolderIds);
}
public static getClosedAnnouncement(): Observable<string | undefined> {
return BrowserStorage.getData('textOfClosedAnnouncement', '');
}
public static setClosedAnnouncement(
closedAnnouncementText: string | undefined,
): Observable<void> {
return BrowserStorage.setData(
'textOfClosedAnnouncement',
closedAnnouncementText || '',
);
}

public static sendFile(
formData: FormData,
Expand Down
3 changes: 2 additions & 1 deletion src/utils/app/data/storages/browser-storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ type UIStorageKeys =
| 'settings'
| 'showChatbar'
| 'showPromptbar'
| 'openedFoldersIds';
| 'openedFoldersIds'
| 'textOfClosedAnnouncement';

export class BrowserStorage implements DialStorage {
private static storage: globalThis.Storage | undefined;
Expand Down

0 comments on commit b403788

Please sign in to comment.