diff --git a/services/web/app/views/project/editor/meta.pug b/services/web/app/views/project/editor/meta.pug index 73c610ee8b..0c9c72eb76 100644 --- a/services/web/app/views/project/editor/meta.pug +++ b/services/web/app/views/project/editor/meta.pug @@ -39,6 +39,7 @@ meta(name="ol-showPersonalAccessToken", data-type="boolean" content=showPersonal meta(name="ol-isReviewPanelReact", data-type="boolean" content=isReviewPanelReact) meta(name="ol-hasTrackChangesFeature", data-type="boolean" content=hasTrackChangesFeature) meta(name="ol-mathJax3Path" content=mathJax3Path) +meta(name="ol-completedTutorials", data-type="json" content=user.completedTutorials) - var fileActionI18n = ['edited', 'renamed', 'created', 'deleted'].reduce((acc, i) => {acc[i] = translate('file_action_' + i); return acc}, {}) meta(name="ol-fileActionI18n" data-type="json" content=fileActionI18n) diff --git a/services/web/frontend/extracted-translations.json b/services/web/frontend/extracted-translations.json index fbe8793efb..eeecf87e52 100644 --- a/services/web/frontend/extracted-translations.json +++ b/services/web/frontend/extracted-translations.json @@ -798,6 +798,9 @@ "quoted_text_in": "", "raw_logs": "", "raw_logs_description": "", + "react_history_tutorial_content": "", + "react_history_tutorial_learn_more": "", + "react_history_tutorial_title": "", "reactivate_subscription": "", "read_only": "", "read_only_token": "", diff --git a/services/web/frontend/js/features/history/components/change-list/all-history-list.tsx b/services/web/frontend/js/features/history/components/change-list/all-history-list.tsx index e1c7d576b0..807155cfb4 100644 --- a/services/web/frontend/js/features/history/components/change-list/all-history-list.tsx +++ b/services/web/frontend/js/features/history/components/change-list/all-history-list.tsx @@ -3,10 +3,23 @@ import HistoryVersion from './history-version' import LoadingSpinner from '../../../../shared/components/loading-spinner' import { OwnerPaywallPrompt } from './owner-paywall-prompt' import { NonOwnerPaywallPrompt } from './non-owner-paywall-prompt' -import { isVersionSelected } from '../../utils/history-details' +import { + isVersionSelected, + ItemSelectionState, +} from '../../utils/history-details' import { useUserContext } from '../../../../shared/context/user-context' import useDropdownActiveItem from '../../hooks/use-dropdown-active-item' import { useHistoryContext } from '../../context/history-context' +import getMeta from '../../../../utils/meta' + +type CompletedTutorials = { + 'react-history-buttons-tutorial': Date +} + +const unselectedStates: ItemSelectionState[] = [ + 'aboveSelected', + 'belowSelected', +] function AllHistoryList() { const { id: currentUserId } = useUserContext() @@ -84,6 +97,27 @@ function AllHistoryList() { } }, [updatesLoadingState]) + const completedTutorials: CompletedTutorials = getMeta( + 'ol-completedTutorials' + ) + + // only show tutorial popover if they havent dismissed ("completed") it yet + const hasCompletedHistTutorial = Boolean( + completedTutorials?.['react-history-buttons-tutorial'] + ) + + // only show tutorial popover on the first icon + const firstUnselectedIndex = visibleUpdates.findIndex(update => { + const selectionState = isVersionSelected( + selection, + update.fromV, + update.toV + ) + return unselectedStates.includes(selectionState) + }) + + const [showTutorial, setShowTutorial] = useState(!hasCompletedHistTutorial) + return (