Vue initialization and FloatingMenu codebase refactoring and cleanup (#649)

* Clean up Vue initialization-related code

* Rename folder: dispatcher -> interop

* Rename folder: state -> providers

* Comments and clarification

* Rename JS dispatcher to subscription router

* Assorted cleanup and renaming

* Rename: js-messages.ts -> messages.ts

* Comments

* Remove unused Vue component injects

* Clean up coming soon and add warning about freezing the app

* Further cleanup

* Dangerous changes

* Simplify App.vue code

* Move more disparate init code from components into managers

* Rename folder: providers -> state-providers

* Other

* Move Document panel options bar separator to backend

* Add destructors to managers to fix HMR

* Comments and code style

* Rename variable: font -> font_file_url

* Fix async font loading; refactor janky floating menu openness and min-width measurement; fix Vetur errors

* Fix misaligned canvas in viewport until panning on page (re)load

* Add Vue bidirectional props documentation

* More folder renaming for better terminology; add some documentation
This commit is contained in:
Keavon Chambers
2022-05-21 19:46:15 -07:00
parent c450bbf028
commit ef53577b20
73 changed files with 1572 additions and 1462 deletions

View File

@@ -73,7 +73,7 @@ pub enum DocumentMessage {
affected_folder_path: Vec<LayerId>,
},
FontLoaded {
font: String,
font_file_url: String,
data: Vec<u8>,
is_default: bool,
},
@@ -82,7 +82,7 @@ pub enum DocumentMessage {
affected_layer_path: Vec<LayerId>,
},
LoadFont {
font: String,
font_file_url: String,
},
MoveSelectedLayersTo {
folder_path: Vec<LayerId>,

View File

@@ -523,6 +523,7 @@ impl DocumentMessageHandler {
}
}
// TODO: Loading the default font should happen on a per-application basis, not a per-document basis
pub fn load_default_font(&self, responses: &mut VecDeque<Message>) {
if !self.graphene_document.font_cache.has_default() {
responses.push_back(FrontendMessage::TriggerFontLoadDefault.into())
@@ -669,30 +670,36 @@ impl DocumentMessageHandler {
}]);
let document_mode_layout = WidgetLayout::new(vec![LayoutRow::Row {
widgets: vec![WidgetHolder::new(Widget::DropdownInput(DropdownInput {
entries: vec![vec![
DropdownEntryData {
label: DocumentMode::DesignMode.to_string(),
icon: DocumentMode::DesignMode.icon_name(),
..DropdownEntryData::default()
},
DropdownEntryData {
label: DocumentMode::SelectMode.to_string(),
icon: DocumentMode::SelectMode.icon_name(),
on_update: WidgetCallback::new(|_| DialogMessage::RequestComingSoonDialog { issue: Some(330) }.into()),
..DropdownEntryData::default()
},
DropdownEntryData {
label: DocumentMode::GuideMode.to_string(),
icon: DocumentMode::GuideMode.icon_name(),
on_update: WidgetCallback::new(|_| DialogMessage::RequestComingSoonDialog { issue: Some(331) }.into()),
..DropdownEntryData::default()
},
]],
selected_index: Some(self.document_mode as u32),
draw_icon: true,
..Default::default()
}))],
widgets: vec![
WidgetHolder::new(Widget::DropdownInput(DropdownInput {
entries: vec![vec![
DropdownEntryData {
label: DocumentMode::DesignMode.to_string(),
icon: DocumentMode::DesignMode.icon_name(),
..DropdownEntryData::default()
},
DropdownEntryData {
label: DocumentMode::SelectMode.to_string(),
icon: DocumentMode::SelectMode.icon_name(),
on_update: WidgetCallback::new(|_| DialogMessage::RequestComingSoonDialog { issue: Some(330) }.into()),
..DropdownEntryData::default()
},
DropdownEntryData {
label: DocumentMode::GuideMode.to_string(),
icon: DocumentMode::GuideMode.icon_name(),
on_update: WidgetCallback::new(|_| DialogMessage::RequestComingSoonDialog { issue: Some(331) }.into()),
..DropdownEntryData::default()
},
]],
selected_index: Some(self.document_mode as u32),
draw_icon: true,
..Default::default()
})),
WidgetHolder::new(Widget::Separator(Separator {
separator_type: SeparatorType::Section,
direction: SeparatorDirection::Horizontal,
})),
],
}]);
responses.push_back(
@@ -1107,8 +1114,8 @@ impl MessageHandler<DocumentMessage, &InputPreprocessorMessageHandler> for Docum
let affected_layer_path = affected_folder_path;
responses.extend([LayerChanged { affected_layer_path }.into(), DocumentStructureChanged.into()]);
}
FontLoaded { font, data, is_default } => {
self.graphene_document.font_cache.insert(font, data, is_default);
FontLoaded { font_file_url, data, is_default } => {
self.graphene_document.font_cache.insert(font_file_url, data, is_default);
responses.push_back(DocumentMessage::DirtyRenderDocument.into());
}
GroupSelectedLayers => {
@@ -1147,9 +1154,9 @@ impl MessageHandler<DocumentMessage, &InputPreprocessorMessageHandler> for Docum
responses.push_back(PropertiesPanelMessage::CheckSelectedWasUpdated { path: affected_layer_path }.into());
self.update_layer_tree_options_bar_widgets(responses);
}
LoadFont { font } => {
if !self.graphene_document.font_cache.loaded_font(&font) {
responses.push_front(FrontendMessage::TriggerFontLoad { font }.into());
LoadFont { font_file_url } => {
if !self.graphene_document.font_cache.loaded_font(&font_file_url) {
responses.push_front(FrontendMessage::TriggerFontLoad { font_file_url }.into());
}
}
MoveSelectedLayersTo {

View File

@@ -79,6 +79,7 @@ impl PortfolioMessageHandler {
new_document.update_layer_tree_options_bar_widgets(responses);
new_document.load_image_data(responses, &new_document.graphene_document.root.data, Vec::new());
// TODO: Loading the default font should happen on a per-application basis, not a per-document basis
new_document.load_default_font(responses);
self.documents.insert(document_id, new_document);

View File

@@ -714,12 +714,12 @@ fn node_section_font(layer: &TextLayer) -> LayoutRow {
is_style_picker: false,
font_family: layer.font_family.clone(),
font_style: layer.font_style.clone(),
font_file: String::new(),
font_file_url: String::new(),
on_update: WidgetCallback::new(move |font_input: &FontInput| {
PropertiesPanelMessage::ModifyFont {
font_family: font_input.font_family.clone(),
font_style: font_input.font_style.clone(),
font_file: Some(font_input.font_file.clone()),
font_file: Some(font_input.font_file_url.clone()),
size,
}
.into()
@@ -741,12 +741,12 @@ fn node_section_font(layer: &TextLayer) -> LayoutRow {
is_style_picker: true,
font_family: layer.font_family.clone(),
font_style: layer.font_style.clone(),
font_file: String::new(),
font_file_url: String::new(),
on_update: WidgetCallback::new(move |font_input: &FontInput| {
PropertiesPanelMessage::ModifyFont {
font_family: font_input.font_family.clone(),
font_style: font_input.font_style.clone(),
font_file: Some(font_input.font_file.clone()),
font_file: Some(font_input.font_file_url.clone()),
size,
}
.into()

View File

@@ -22,7 +22,7 @@ pub enum FrontendMessage {
// Trigger prefix: cause a browser API to do something
TriggerFileDownload { document: String, name: String },
TriggerFileUpload,
TriggerFontLoad { font: String },
TriggerFontLoad { font_file_url: String },
TriggerFontLoadDefault,
TriggerIndexedDbRemoveDocument { document_id: u64 },
TriggerIndexedDbWriteDocument { document: String, details: FrontendDocumentDetails, version: String },

View File

@@ -95,17 +95,17 @@ impl MessageHandler<LayoutMessage, ()> for LayoutMessageHandler {
let update_value = value.as_object().expect("FontInput update was not of type: object");
let font_family_value = update_value.get("fontFamily").expect("FontInput update does not have a fontFamily");
let font_style_value = update_value.get("fontStyle").expect("FontInput update does not have a fontStyle");
let font_file_value = update_value.get("fontFile").expect("FontInput update does not have a fontFile");
let font_file_url_value = update_value.get("fontFileUrl").expect("FontInput update does not have a fontFileUrl");
let font_family = font_family_value.as_str().expect("FontInput update fontFamily was not of type: string");
let font_style = font_style_value.as_str().expect("FontInput update fontStyle was not of type: string");
let font_file = font_file_value.as_str().expect("FontInput update fontFile was not of type: string");
let font_file_url = font_file_url_value.as_str().expect("FontInput update fontFileUrl was not of type: string");
font_input.font_family = font_family.into();
font_input.font_style = font_style.into();
font_input.font_file = font_file.into();
font_input.font_file_url = font_file_url.into();
responses.push_back(DocumentMessage::LoadFont { font: font_file.into() }.into());
responses.push_back(DocumentMessage::LoadFont { font_file_url: font_file_url.into() }.into());
let callback_message = (font_input.on_update.callback)(font_input);
responses.push_back(callback_message);
}

View File

@@ -49,6 +49,7 @@ impl WidgetLayout {
pub type SubLayout = Vec<LayoutRow>;
// TODO: Rename LayoutRow to something more generic
#[remain::sorted]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum LayoutRow {
@@ -254,8 +255,8 @@ pub struct FontInput {
pub font_family: String,
#[serde(rename = "fontStyle")]
pub font_style: String,
#[serde(rename = "fontFile")]
pub font_file: String,
#[serde(rename = "fontFileUrl")]
pub font_file_url: String,
#[serde(skip)]
#[derivative(Debug = "ignore", PartialEq = "ignore")]
pub on_update: WidgetCallback<FontInput>,

View File

@@ -84,7 +84,7 @@ impl PropertyHolder for TextTool {
TextMessage::UpdateOptions(TextOptionsUpdate::Font {
family: font_input.font_family.clone(),
style: font_input.font_style.clone(),
file: font_input.font_file.clone(),
file: font_input.font_file_url.clone(),
})
.into()
}),
@@ -102,7 +102,7 @@ impl PropertyHolder for TextTool {
TextMessage::UpdateOptions(TextOptionsUpdate::Font {
family: font_input.font_family.clone(),
style: font_input.font_style.clone(),
file: font_input.font_file.clone(),
file: font_input.font_file_url.clone(),
})
.into()
}),