diff --git a/apps/client/src/AppRouter.tsx b/apps/client/src/AppRouter.tsx
index 1307b0433d..0248f7bb45 100644
--- a/apps/client/src/AppRouter.tsx
+++ b/apps/client/src/AppRouter.tsx
@@ -28,7 +28,7 @@ const ClockView = React.lazy(() => import('./features/viewers/clock/Clock'));
const Countdown = React.lazy(() => import('./features/viewers/countdown/Countdown'));
const Backstage = React.lazy(() => import('./features/viewers/backstage/Backstage'));
-const Timeline = React.lazy(() => import('./features/viewers/timeline/TimelinePage'));
+const Timeline = React.lazy(() => import('./views/timeline/TimelinePage'));
const Public = React.lazy(() => import('./features/viewers/public/Public'));
const Lower = React.lazy(() => import('./features/viewers/lower-thirds/LowerThird'));
const StudioClock = React.lazy(() => import('./features/viewers/studio/StudioClock'));
diff --git a/apps/client/src/features/viewers/ViewWrapper.tsx b/apps/client/src/features/viewers/ViewWrapper.tsx
index cb488192e9..a0b78bd9bf 100644
--- a/apps/client/src/features/viewers/ViewWrapper.tsx
+++ b/apps/client/src/features/viewers/ViewWrapper.tsx
@@ -86,11 +86,6 @@ const withData =
(Component: ComponentType
) => {
timerType: eventNow?.timerType ?? null,
};
- // // prevent render until we get all the data we need
- // if (!viewSettings) {
- // return null;
- // }
-
return (
<>
diff --git a/apps/client/src/features/viewers/timeline/Timeline.module.scss b/apps/client/src/views/timeline/Timeline.module.scss
similarity index 98%
rename from apps/client/src/features/viewers/timeline/Timeline.module.scss
rename to apps/client/src/views/timeline/Timeline.module.scss
index 7aafe09a32..168daf427b 100644
--- a/apps/client/src/features/viewers/timeline/Timeline.module.scss
+++ b/apps/client/src/views/timeline/Timeline.module.scss
@@ -1,4 +1,4 @@
-@use '../../../theme/viewerDefs' as *;
+@use '../../theme/viewerDefs' as *;
$timeline-height: 1rem;
$view-background: $ui-black;
diff --git a/apps/client/src/features/viewers/timeline/Timeline.tsx b/apps/client/src/views/timeline/Timeline.tsx
similarity index 100%
rename from apps/client/src/features/viewers/timeline/Timeline.tsx
rename to apps/client/src/views/timeline/Timeline.tsx
diff --git a/apps/client/src/features/viewers/timeline/TimelineEntry.tsx b/apps/client/src/views/timeline/TimelineEntry.tsx
similarity index 89%
rename from apps/client/src/features/viewers/timeline/TimelineEntry.tsx
rename to apps/client/src/views/timeline/TimelineEntry.tsx
index b78ef61090..fbb2346e9d 100644
--- a/apps/client/src/features/viewers/timeline/TimelineEntry.tsx
+++ b/apps/client/src/views/timeline/TimelineEntry.tsx
@@ -1,8 +1,8 @@
-import { useTimelineStatus, useTimer } from '../../../common/hooks/useSocket';
-import { getProgress } from '../../../common/utils/getProgress';
-import { alpha, cx } from '../../../common/utils/styleUtils';
-import { formatDuration, formatTime } from '../../../common/utils/time';
-import { useTranslation } from '../../../translation/TranslationProvider';
+import { useTimelineStatus, useTimer } from '../../common/hooks/useSocket';
+import { getProgress } from '../../common/utils/getProgress';
+import { alpha, cx } from '../../common/utils/styleUtils';
+import { formatDuration, formatTime } from '../../common/utils/time';
+import { useTranslation } from '../../translation/TranslationProvider';
import { getStatusLabel, getTimeToStart } from './timeline.utils';
diff --git a/apps/client/src/features/viewers/timeline/TimelinePage.scss b/apps/client/src/views/timeline/TimelinePage.scss
similarity index 98%
rename from apps/client/src/features/viewers/timeline/TimelinePage.scss
rename to apps/client/src/views/timeline/TimelinePage.scss
index 1508647ac3..363e08bf89 100644
--- a/apps/client/src/features/viewers/timeline/TimelinePage.scss
+++ b/apps/client/src/views/timeline/TimelinePage.scss
@@ -1,4 +1,4 @@
-@use '../../../theme/viewerDefs' as *;
+@use '../../theme/viewerDefs' as *;
.timeline {
width: 100vw;
diff --git a/apps/client/src/features/viewers/timeline/TimelinePage.tsx b/apps/client/src/views/timeline/TimelinePage.tsx
similarity index 88%
rename from apps/client/src/features/viewers/timeline/TimelinePage.tsx
rename to apps/client/src/views/timeline/TimelinePage.tsx
index b00faa863f..ac4b7b87e8 100644
--- a/apps/client/src/features/viewers/timeline/TimelinePage.tsx
+++ b/apps/client/src/views/timeline/TimelinePage.tsx
@@ -1,12 +1,12 @@
import { useMemo } from 'react';
import { MaybeString, OntimeEvent, ProjectData, Runtime, Settings } from 'ontime-types';
-import ViewParamsEditor from '../../../common/components/view-params-editor/ViewParamsEditor';
-import { useWindowTitle } from '../../../common/hooks/useWindowTitle';
-import { ViewExtendedTimer } from '../../../common/models/TimeManager.type';
-import { formatDuration, formatTime, getDefaultFormat } from '../../../common/utils/time';
-import { useTranslation } from '../../../translation/TranslationProvider';
-import SuperscriptTime from '../common/superscript-time/SuperscriptTime';
+import ViewParamsEditor from '../../common/components/view-params-editor/ViewParamsEditor';
+import { useWindowTitle } from '../../common/hooks/useWindowTitle';
+import { ViewExtendedTimer } from '../../common/models/TimeManager.type';
+import { formatDuration, formatTime, getDefaultFormat } from '../../common/utils/time';
+import SuperscriptTime from '../../features/viewers/common/superscript-time/SuperscriptTime';
+import { useTranslation } from '../../translation/TranslationProvider';
import Section from './timeline-section/TimelineSection';
import Timeline from './Timeline';
@@ -70,7 +70,6 @@ export default function TimelinePage(props: TimelinePageProps) {
followedByStatus = `T - ${formatDuration(timeToStart)}`;
}
}
-
return (
diff --git a/apps/client/src/features/viewers/timeline/__tests__/timeline.utils.test.ts b/apps/client/src/views/timeline/__tests__/timeline.utils.test.ts
similarity index 100%
rename from apps/client/src/features/viewers/timeline/__tests__/timeline.utils.test.ts
rename to apps/client/src/views/timeline/__tests__/timeline.utils.test.ts
diff --git a/apps/client/src/features/viewers/timeline/timeline-markers/TimelineMarkers.module.scss b/apps/client/src/views/timeline/timeline-markers/TimelineMarkers.module.scss
similarity index 100%
rename from apps/client/src/features/viewers/timeline/timeline-markers/TimelineMarkers.module.scss
rename to apps/client/src/views/timeline/timeline-markers/TimelineMarkers.module.scss
diff --git a/apps/client/src/features/viewers/timeline/timeline-markers/TimelineMarkers.tsx b/apps/client/src/views/timeline/timeline-markers/TimelineMarkers.tsx
similarity index 100%
rename from apps/client/src/features/viewers/timeline/timeline-markers/TimelineMarkers.tsx
rename to apps/client/src/views/timeline/timeline-markers/TimelineMarkers.tsx
diff --git a/apps/client/src/features/viewers/timeline/timeline-section/TimelineSection.tsx b/apps/client/src/views/timeline/timeline-section/TimelineSection.tsx
similarity index 93%
rename from apps/client/src/features/viewers/timeline/timeline-section/TimelineSection.tsx
rename to apps/client/src/views/timeline/timeline-section/TimelineSection.tsx
index 1637d17f12..1e01f98f33 100644
--- a/apps/client/src/features/viewers/timeline/timeline-section/TimelineSection.tsx
+++ b/apps/client/src/views/timeline/timeline-section/TimelineSection.tsx
@@ -1,7 +1,7 @@
import { memo } from 'react';
import { MaybeString } from 'ontime-types';
-import { cx } from '../../../../common/utils/styleUtils';
+import { cx } from '../../../common/utils/styleUtils';
interface SectionProps {
category: 'now' | 'next';
diff --git a/apps/client/src/features/viewers/timeline/timeline.options.ts b/apps/client/src/views/timeline/timeline.options.ts
similarity index 74%
rename from apps/client/src/features/viewers/timeline/timeline.options.ts
rename to apps/client/src/views/timeline/timeline.options.ts
index ca314df522..a1eabb4d8b 100644
--- a/apps/client/src/features/viewers/timeline/timeline.options.ts
+++ b/apps/client/src/views/timeline/timeline.options.ts
@@ -1,5 +1,5 @@
-import { getTimeOption } from '../../../common/components/view-params-editor/constants';
-import { ViewOption } from '../../../common/components/view-params-editor/types';
+import { getTimeOption } from '../../common/components/view-params-editor/constants';
+import { ViewOption } from '../../common/components/view-params-editor/types';
export const getTimelineOptions = (timeFormat: string): ViewOption[] => {
return [
diff --git a/apps/client/src/features/viewers/timeline/timeline.utils.ts b/apps/client/src/views/timeline/timeline.utils.ts
similarity index 96%
rename from apps/client/src/features/viewers/timeline/timeline.utils.ts
rename to apps/client/src/views/timeline/timeline.utils.ts
index 7ff5d689c3..7f5e9c4d56 100644
--- a/apps/client/src/features/viewers/timeline/timeline.utils.ts
+++ b/apps/client/src/views/timeline/timeline.utils.ts
@@ -11,9 +11,9 @@ import {
MILLIS_PER_HOUR,
} from 'ontime-utils';
-import { clamp } from '../../../common/utils/math';
-import { formatDuration } from '../../../common/utils/time';
-import { isStringBoolean } from '../common/viewUtils';
+import { clamp } from '../../common/utils/math';
+import { formatDuration } from '../../common/utils/time';
+import { isStringBoolean } from '../../features/viewers/common/viewUtils';
import type { ProgressStatus } from './TimelineEntry';