shared/domain/module/body/
video.rs

1use crate::domain::module::{
2    body::{Body, BodyExt, ModeExt, StepExt, ThemeId, _groups::design::*},
3    ModuleKind,
4};
5use serde::{Deserialize, Serialize};
6use std::collections::HashSet;
7
8use super::BodyConvert;
9
10/// The body for [`Video`](crate::domain::module::ModuleKind::Video) modules.
11#[derive(Default, Clone, Serialize, Deserialize, Debug)]
12pub struct ModuleData {
13    /// The content
14    pub content: Option<Content>,
15}
16
17impl BodyExt<Mode, Step> for ModuleData {
18    fn as_body(&self) -> Body {
19        Body::Video(self.clone())
20    }
21
22    fn is_complete(&self) -> bool {
23        self.content.is_some()
24    }
25
26    fn kind() -> ModuleKind {
27        ModuleKind::Video
28    }
29
30    fn new_with_mode_and_theme(mode: Mode, theme: ThemeId) -> Self {
31        ModuleData {
32            content: Some(Content {
33                mode,
34                base: BaseContent {
35                    theme,
36                    ..Default::default()
37                },
38                ..Default::default()
39            }),
40        }
41    }
42
43    fn mode(&self) -> Option<Mode> {
44        self.content.as_ref().map(|c| c.mode.clone())
45    }
46
47    fn requires_choose_mode(&self) -> bool {
48        self.content.is_none()
49    }
50
51    fn set_editor_state_step(&mut self, step: Step) {
52        if let Some(content) = self.content.as_mut() {
53            content.editor_state.step = step;
54        }
55    }
56    fn set_editor_state_steps_completed(&mut self, steps_completed: HashSet<Step>) {
57        if let Some(content) = self.content.as_mut() {
58            content.editor_state.steps_completed = steps_completed;
59        }
60    }
61
62    fn get_editor_state_step(&self) -> Option<Step> {
63        self.content
64            .as_ref()
65            .map(|content| content.editor_state.step)
66    }
67
68    fn get_editor_state_steps_completed(&self) -> Option<HashSet<Step>> {
69        self.content
70            .as_ref()
71            .map(|content| content.editor_state.steps_completed.clone())
72    }
73
74    fn set_theme(&mut self, theme_id: ThemeId) {
75        if let Some(content) = self.content.as_mut() {
76            content.base.theme = theme_id;
77        }
78    }
79
80    fn get_theme(&self) -> Option<ThemeId> {
81        self.content.as_ref().map(|content| content.base.theme)
82    }
83}
84
85impl BodyConvert for ModuleData {}
86
87impl TryFrom<Body> for ModuleData {
88    type Error = &'static str;
89
90    fn try_from(body: Body) -> Result<Self, Self::Error> {
91        match body {
92            Body::Video(data) => Ok(data),
93            _ => Err("cannot convert body to video!"),
94        }
95    }
96}
97
98/// The body for [`Video`](crate::domain::module::ModuleKind::Video) modules.
99#[derive(Default, Clone, Serialize, Deserialize, Debug)]
100pub struct Content {
101    /// The editor state
102    pub editor_state: EditorState,
103
104    /// The mode
105    pub mode: Mode,
106
107    /// The base content for all design modules
108    pub base: BaseContent,
109}
110
111/// Editor state
112#[derive(Default, Clone, Serialize, Deserialize, Debug)]
113pub struct EditorState {
114    /// the current step
115    pub step: Step,
116
117    /// the completed steps
118    pub steps_completed: HashSet<Step>,
119}
120
121#[derive(Clone, Copy, Serialize, Deserialize, Debug, PartialEq, Eq, Hash)]
122/// The mode
123pub enum Mode {
124    /// Introduction
125    Introduction,
126    /// Story
127    Story,
128    /// Song
129    Song,
130    /// Howto
131    Howto,
132}
133
134impl Default for Mode {
135    fn default() -> Self {
136        Self::Introduction
137    }
138}
139
140impl ModeExt for Mode {
141    fn get_list() -> Vec<Self> {
142        vec![Self::Introduction, Self::Story, Self::Song, Self::Howto]
143    }
144
145    fn as_str_id(&self) -> &'static str {
146        match self {
147            Self::Introduction => "introduction",
148            Self::Story => "story",
149            Self::Song => "song",
150            Self::Howto => "howto",
151        }
152    }
153
154    fn label(&self) -> &'static str {
155        const STR_INTRODUCTION_LABEL: &'static str = "Introduce Your Topic";
156        const STR_STORY_LABEL: &'static str = "Tell a Story";
157        const STR_SONG_LABEL: &'static str = "Play a Song";
158        const STR_HOWTO_LABEL: &'static str = "How to";
159
160        match self {
161            Self::Introduction => STR_INTRODUCTION_LABEL,
162            Self::Story => STR_STORY_LABEL,
163            Self::Song => STR_SONG_LABEL,
164            Self::Howto => STR_HOWTO_LABEL,
165        }
166    }
167}
168
169/// The Steps
170#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
171pub enum Step {
172    /// Step 1
173    One,
174    /// Step 2
175    Two,
176    /// Step 3
177    Three,
178    /// Step 4
179    Four,
180}
181
182impl Default for Step {
183    fn default() -> Self {
184        Self::One
185    }
186}
187
188impl StepExt for Step {
189    fn next(&self) -> Option<Self> {
190        match self {
191            Self::One => Some(Self::Two),
192            Self::Two => Some(Self::Three),
193            Self::Three => Some(Self::Four),
194            Self::Four => None,
195        }
196    }
197
198    fn as_number(&self) -> usize {
199        match self {
200            Self::One => 1,
201            Self::Two => 2,
202            Self::Three => 3,
203            Self::Four => 4,
204        }
205    }
206
207    fn label(&self) -> &'static str {
208        //TODO - localizaton
209        const STR_BACKGROUND: &'static str = "Design";
210        const STR_CONTENT: &'static str = "Content";
211        const STR_SETTINGS: &'static str = "Settings";
212        const STR_PREVIEW: &'static str = "Preview";
213
214        match self {
215            Self::One => STR_BACKGROUND,
216            Self::Two => STR_CONTENT,
217            Self::Three => STR_SETTINGS,
218            Self::Four => STR_PREVIEW,
219        }
220    }
221
222    fn get_list() -> Vec<Self> {
223        vec![Self::One, Self::Two, Self::Three, Self::Four]
224    }
225    fn get_preview() -> Self {
226        Self::Four
227    }
228}