mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-25 07:08:12 +08:00
Standardize FrontendMessage message names
This commit is contained in:
@@ -24,8 +24,8 @@ pub struct Dispatcher {
|
|||||||
const SIDE_EFFECT_FREE_MESSAGES: &[MessageDiscriminant] = &[
|
const SIDE_EFFECT_FREE_MESSAGES: &[MessageDiscriminant] = &[
|
||||||
MessageDiscriminant::Portfolio(PortfolioMessageDiscriminant::Document(DocumentMessageDiscriminant::RenderDocument)),
|
MessageDiscriminant::Portfolio(PortfolioMessageDiscriminant::Document(DocumentMessageDiscriminant::RenderDocument)),
|
||||||
MessageDiscriminant::Portfolio(PortfolioMessageDiscriminant::Document(DocumentMessageDiscriminant::FolderChanged)),
|
MessageDiscriminant::Portfolio(PortfolioMessageDiscriminant::Document(DocumentMessageDiscriminant::FolderChanged)),
|
||||||
MessageDiscriminant::Frontend(FrontendMessageDiscriminant::UpdateLayer),
|
MessageDiscriminant::Frontend(FrontendMessageDiscriminant::UpdateDocumentLayer),
|
||||||
MessageDiscriminant::Frontend(FrontendMessageDiscriminant::DisplayFolderTreeStructure),
|
MessageDiscriminant::Frontend(FrontendMessageDiscriminant::DisplayDocumentLayerTreeStructure),
|
||||||
MessageDiscriminant::Frontend(FrontendMessageDiscriminant::UpdateOpenDocumentsList),
|
MessageDiscriminant::Frontend(FrontendMessageDiscriminant::UpdateOpenDocumentsList),
|
||||||
MessageDiscriminant::Tool(ToolMessageDiscriminant::DocumentIsDirty),
|
MessageDiscriminant::Tool(ToolMessageDiscriminant::DocumentIsDirty),
|
||||||
];
|
];
|
||||||
@@ -78,7 +78,7 @@ impl Dispatcher {
|
|||||||
if log::max_level() == log::LevelFilter::Trace
|
if log::max_level() == log::LevelFilter::Trace
|
||||||
&& !(matches!(
|
&& !(matches!(
|
||||||
message,
|
message,
|
||||||
InputPreprocessor(_) | Frontend(FrontendMessage::SetCanvasZoom { .. }) | Frontend(FrontendMessage::SetCanvasRotation { .. })
|
InputPreprocessor(_) | Frontend(FrontendMessage::UpdateCanvasZoom { .. }) | Frontend(FrontendMessage::UpdateCanvasRotation { .. })
|
||||||
) || MessageDiscriminant::from(message).local_name().ends_with("MouseMove"))
|
) || MessageDiscriminant::from(message).local_name().ends_with("MouseMove"))
|
||||||
{
|
{
|
||||||
log::trace!("Message: {:?}", message);
|
log::trace!("Message: {:?}", message);
|
||||||
|
|||||||
@@ -68,14 +68,14 @@ impl MessageHandler<ArtboardMessage, (&mut LayerMetadata, &GrapheneDocument, &In
|
|||||||
// Render an infinite canvas if there are no artboards
|
// Render an infinite canvas if there are no artboards
|
||||||
if self.artboard_ids.is_empty() {
|
if self.artboard_ids.is_empty() {
|
||||||
responses.push_back(
|
responses.push_back(
|
||||||
FrontendMessage::UpdateArtboards {
|
FrontendMessage::UpdateDocumentArtboards {
|
||||||
svg: r##"<rect width="100%" height="100%" fill="#ffffff" />"##.to_string(),
|
svg: r##"<rect width="100%" height="100%" fill="#ffffff" />"##.to_string(),
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
responses.push_back(
|
responses.push_back(
|
||||||
FrontendMessage::UpdateArtboards {
|
FrontendMessage::UpdateDocumentArtboards {
|
||||||
svg: self.artboards_graphene_document.render_root(ViewMode::Normal),
|
svg: self.artboards_graphene_document.render_root(ViewMode::Normal),
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
|
|||||||
@@ -243,7 +243,7 @@ impl DocumentMessageHandler {
|
|||||||
if let Some(layer) = self.layer_metadata.get_mut(path) {
|
if let Some(layer) = self.layer_metadata.get_mut(path) {
|
||||||
layer.selected = true;
|
layer.selected = true;
|
||||||
let data = self.layer_panel_entry(path.to_vec()).ok()?;
|
let data = self.layer_panel_entry(path.to_vec()).ok()?;
|
||||||
(!path.is_empty()).then(|| FrontendMessage::UpdateLayer { data }.into())
|
(!path.is_empty()).then(|| FrontendMessage::UpdateDocumentLayer { data }.into())
|
||||||
} else {
|
} else {
|
||||||
log::warn!("Tried to select non existing layer {:?}", path);
|
log::warn!("Tried to select non existing layer {:?}", path);
|
||||||
None
|
None
|
||||||
@@ -594,7 +594,7 @@ impl MessageHandler<DocumentMessage, &InputPreprocessor> for DocumentMessageHand
|
|||||||
false => self.name.clone() + FILE_EXPORT_SUFFIX,
|
false => self.name.clone() + FILE_EXPORT_SUFFIX,
|
||||||
};
|
};
|
||||||
responses.push_back(
|
responses.push_back(
|
||||||
FrontendMessage::ExportDocument {
|
FrontendMessage::TriggerFileDownload {
|
||||||
document: format!(
|
document: format!(
|
||||||
r#"<svg xmlns="http://www.w3.org/2000/svg" viewBox="{} {} {} {}">{}{}</svg>"#,
|
r#"<svg xmlns="http://www.w3.org/2000/svg" viewBox="{} {} {} {}">{}{}</svg>"#,
|
||||||
bbox[0].x,
|
bbox[0].x,
|
||||||
@@ -620,7 +620,7 @@ impl MessageHandler<DocumentMessage, &InputPreprocessor> for DocumentMessageHand
|
|||||||
false => self.name.clone() + FILE_SAVE_SUFFIX,
|
false => self.name.clone() + FILE_SAVE_SUFFIX,
|
||||||
};
|
};
|
||||||
responses.push_back(
|
responses.push_back(
|
||||||
FrontendMessage::SaveDocument {
|
FrontendMessage::TriggerFileDownload {
|
||||||
document: self.serialize_document(),
|
document: self.serialize_document(),
|
||||||
name,
|
name,
|
||||||
}
|
}
|
||||||
@@ -830,11 +830,11 @@ impl MessageHandler<DocumentMessage, &InputPreprocessor> for DocumentMessageHand
|
|||||||
}
|
}
|
||||||
DocumentStructureChanged => {
|
DocumentStructureChanged => {
|
||||||
let data_buffer: RawBuffer = self.serialize_root().into();
|
let data_buffer: RawBuffer = self.serialize_root().into();
|
||||||
responses.push_back(FrontendMessage::DisplayFolderTreeStructure { data_buffer }.into())
|
responses.push_back(FrontendMessage::DisplayDocumentLayerTreeStructure { data_buffer }.into())
|
||||||
}
|
}
|
||||||
LayerChanged(path) => {
|
LayerChanged(path) => {
|
||||||
if let Ok(layer_entry) = self.layer_panel_entry(path) {
|
if let Ok(layer_entry) = self.layer_panel_entry(path) {
|
||||||
responses.push_back(FrontendMessage::UpdateLayer { data: layer_entry }.into());
|
responses.push_back(FrontendMessage::UpdateDocumentLayer { data: layer_entry }.into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DispatchOperation(op) => match self.graphene_document.handle_operation(&op) {
|
DispatchOperation(op) => match self.graphene_document.handle_operation(&op) {
|
||||||
@@ -866,7 +866,7 @@ impl MessageHandler<DocumentMessage, &InputPreprocessor> for DocumentMessageHand
|
|||||||
},
|
},
|
||||||
RenderDocument => {
|
RenderDocument => {
|
||||||
responses.push_back(
|
responses.push_back(
|
||||||
FrontendMessage::UpdateArtwork {
|
FrontendMessage::UpdateDocumentArtwork {
|
||||||
svg: self.graphene_document.render_root(self.view_mode),
|
svg: self.graphene_document.render_root(self.view_mode),
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
@@ -892,7 +892,7 @@ impl MessageHandler<DocumentMessage, &InputPreprocessor> for DocumentMessageHand
|
|||||||
let ruler_origin = self.graphene_document.root.transform.transform_point2(DVec2::ZERO);
|
let ruler_origin = self.graphene_document.root.transform.transform_point2(DVec2::ZERO);
|
||||||
|
|
||||||
responses.push_back(
|
responses.push_back(
|
||||||
FrontendMessage::UpdateScrollbars {
|
FrontendMessage::UpdateDocumentScrollbars {
|
||||||
position: scrollbar_position.into(),
|
position: scrollbar_position.into(),
|
||||||
size: scrollbar_size.into(),
|
size: scrollbar_size.into(),
|
||||||
multiplier: scrollbar_multiplier.into(),
|
multiplier: scrollbar_multiplier.into(),
|
||||||
@@ -901,7 +901,7 @@ impl MessageHandler<DocumentMessage, &InputPreprocessor> for DocumentMessageHand
|
|||||||
);
|
);
|
||||||
|
|
||||||
responses.push_back(
|
responses.push_back(
|
||||||
FrontendMessage::UpdateRulers {
|
FrontendMessage::UpdateDocumentRulers {
|
||||||
origin: ruler_origin.into(),
|
origin: ruler_origin.into(),
|
||||||
spacing: ruler_spacing,
|
spacing: ruler_spacing,
|
||||||
interval: ruler_interval,
|
interval: ruler_interval,
|
||||||
|
|||||||
@@ -235,7 +235,7 @@ impl MessageHandler<MovementMessage, (&Document, &InputPreprocessor)> for Moveme
|
|||||||
}
|
}
|
||||||
SetCanvasZoom(new) => {
|
SetCanvasZoom(new) => {
|
||||||
self.zoom = new.clamp(VIEWPORT_ZOOM_SCALE_MIN, VIEWPORT_ZOOM_SCALE_MAX);
|
self.zoom = new.clamp(VIEWPORT_ZOOM_SCALE_MIN, VIEWPORT_ZOOM_SCALE_MAX);
|
||||||
responses.push_back(FrontendMessage::SetCanvasZoom { new_zoom: self.snapped_scale() }.into());
|
responses.push_back(FrontendMessage::UpdateCanvasZoom { factor: self.snapped_scale() }.into());
|
||||||
responses.push_back(ToolMessage::DocumentIsDirty.into());
|
responses.push_back(ToolMessage::DocumentIsDirty.into());
|
||||||
responses.push_back(DocumentMessage::DirtyRenderDocumentInOutlineView.into());
|
responses.push_back(DocumentMessage::DirtyRenderDocumentInOutlineView.into());
|
||||||
self.create_document_transform(&ipp.viewport_bounds, responses);
|
self.create_document_transform(&ipp.viewport_bounds, responses);
|
||||||
@@ -275,7 +275,7 @@ impl MessageHandler<MovementMessage, (&Document, &InputPreprocessor)> for Moveme
|
|||||||
self.tilt = new_radians;
|
self.tilt = new_radians;
|
||||||
self.create_document_transform(&ipp.viewport_bounds, responses);
|
self.create_document_transform(&ipp.viewport_bounds, responses);
|
||||||
responses.push_back(ToolMessage::DocumentIsDirty.into());
|
responses.push_back(ToolMessage::DocumentIsDirty.into());
|
||||||
responses.push_back(FrontendMessage::SetCanvasRotation { new_radians: self.snapped_angle() }.into());
|
responses.push_back(FrontendMessage::UpdateCanvasRotation { angle_radians: self.snapped_angle() }.into());
|
||||||
}
|
}
|
||||||
FitViewportToBounds {
|
FitViewportToBounds {
|
||||||
bounds: [bounds_corner_a, bounds_corner_b],
|
bounds: [bounds_corner_a, bounds_corner_b],
|
||||||
@@ -301,7 +301,7 @@ impl MessageHandler<MovementMessage, (&Document, &InputPreprocessor)> for Moveme
|
|||||||
self.zoom = 1.
|
self.zoom = 1.
|
||||||
}
|
}
|
||||||
|
|
||||||
responses.push_back(FrontendMessage::SetCanvasZoom { new_zoom: self.zoom }.into());
|
responses.push_back(FrontendMessage::UpdateCanvasZoom { factor: self.zoom }.into());
|
||||||
responses.push_back(ToolMessage::DocumentIsDirty.into());
|
responses.push_back(ToolMessage::DocumentIsDirty.into());
|
||||||
responses.push_back(DocumentMessage::DirtyRenderDocumentInOutlineView.into());
|
responses.push_back(DocumentMessage::DirtyRenderDocumentInOutlineView.into());
|
||||||
self.create_document_transform(&ipp.viewport_bounds, responses);
|
self.create_document_transform(&ipp.viewport_bounds, responses);
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ impl MessageHandler<OverlayMessage, (&mut LayerMetadata, &Document, &InputPrepro
|
|||||||
|
|
||||||
// Render overlays
|
// Render overlays
|
||||||
responses.push_back(
|
responses.push_back(
|
||||||
FrontendMessage::UpdateOverlays {
|
FrontendMessage::UpdateDocumentOverlays {
|
||||||
svg: self.overlays_graphene_document.render_root(ViewMode::Normal),
|
svg: self.overlays_graphene_document.render_root(ViewMode::Normal),
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ impl PortfolioMessageHandler {
|
|||||||
.layer_metadata
|
.layer_metadata
|
||||||
.keys()
|
.keys()
|
||||||
.filter_map(|path| new_document.layer_panel_entry_from_path(path))
|
.filter_map(|path| new_document.layer_panel_entry_from_path(path))
|
||||||
.map(|entry| FrontendMessage::UpdateLayer { data: entry }.into())
|
.map(|entry| FrontendMessage::UpdateDocumentLayer { data: entry }.into())
|
||||||
.collect::<Vec<_>>(),
|
.collect::<Vec<_>>(),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -181,7 +181,7 @@ impl MessageHandler<PortfolioMessage, &InputPreprocessor> for PortfolioMessageHa
|
|||||||
use PortfolioMessage::*;
|
use PortfolioMessage::*;
|
||||||
match message {
|
match message {
|
||||||
RequestAboutGraphiteDialog => {
|
RequestAboutGraphiteDialog => {
|
||||||
responses.push_back(FrontendMessage::DisplayAboutGraphiteDialog.into());
|
responses.push_back(FrontendMessage::DisplayDialogAboutGraphite.into());
|
||||||
}
|
}
|
||||||
Document(message) => self.active_document_mut().process_action(message, ipp, responses),
|
Document(message) => self.active_document_mut().process_action(message, ipp, responses),
|
||||||
SelectDocument(id) => {
|
SelectDocument(id) => {
|
||||||
@@ -190,7 +190,7 @@ impl MessageHandler<PortfolioMessage, &InputPreprocessor> for PortfolioMessageHa
|
|||||||
responses.push_back(PortfolioMessage::AutoSaveDocument(self.active_document_id).into());
|
responses.push_back(PortfolioMessage::AutoSaveDocument(self.active_document_id).into());
|
||||||
}
|
}
|
||||||
self.active_document_id = id;
|
self.active_document_id = id;
|
||||||
responses.push_back(FrontendMessage::SetActiveDocument { document_id: id }.into());
|
responses.push_back(FrontendMessage::UpdateActiveDocument { document_id: id }.into());
|
||||||
responses.push_back(RenderDocument.into());
|
responses.push_back(RenderDocument.into());
|
||||||
responses.push_back(DocumentMessage::DocumentStructureChanged.into());
|
responses.push_back(DocumentMessage::DocumentStructureChanged.into());
|
||||||
for layer in self.active_document().layer_metadata.keys() {
|
for layer in self.active_document().layer_metadata.keys() {
|
||||||
@@ -259,8 +259,8 @@ impl MessageHandler<PortfolioMessage, &InputPreprocessor> for PortfolioMessageHa
|
|||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
responses.push_back(FrontendMessage::UpdateOpenDocumentsList { open_documents }.into());
|
responses.push_back(FrontendMessage::UpdateOpenDocumentsList { open_documents }.into());
|
||||||
responses.push_back(FrontendMessage::SetActiveDocument { document_id: self.active_document_id }.into());
|
responses.push_back(FrontendMessage::UpdateActiveDocument { document_id: self.active_document_id }.into());
|
||||||
responses.push_back(FrontendMessage::RemoveAutoSaveDocument { document_id: id }.into());
|
responses.push_back(FrontendMessage::TriggerIndexedDbRemoveDocument { document_id: id }.into());
|
||||||
responses.push_back(RenderDocument.into());
|
responses.push_back(RenderDocument.into());
|
||||||
responses.push_back(DocumentMessage::DocumentStructureChanged.into());
|
responses.push_back(DocumentMessage::DocumentStructureChanged.into());
|
||||||
for layer in self.active_document().layer_metadata.keys() {
|
for layer in self.active_document().layer_metadata.keys() {
|
||||||
@@ -275,7 +275,7 @@ impl MessageHandler<PortfolioMessage, &InputPreprocessor> for PortfolioMessageHa
|
|||||||
self.load_document(new_document, document_id, false, responses);
|
self.load_document(new_document, document_id, false, responses);
|
||||||
}
|
}
|
||||||
OpenDocument => {
|
OpenDocument => {
|
||||||
responses.push_back(FrontendMessage::OpenDocumentBrowse.into());
|
responses.push_back(FrontendMessage::TriggerFileUpload.into());
|
||||||
}
|
}
|
||||||
OpenDocumentFile(document_name, document) => {
|
OpenDocumentFile(document_name, document) => {
|
||||||
responses.push_back(
|
responses.push_back(
|
||||||
@@ -301,7 +301,7 @@ impl MessageHandler<PortfolioMessage, &InputPreprocessor> for PortfolioMessageHa
|
|||||||
self.load_document(document, document_id, true, responses);
|
self.load_document(document, document_id, true, responses);
|
||||||
}
|
}
|
||||||
Err(e) => responses.push_back(
|
Err(e) => responses.push_back(
|
||||||
FrontendMessage::DisplayError {
|
FrontendMessage::DisplayDialogError {
|
||||||
title: "Failed to open document".to_string(),
|
title: "Failed to open document".to_string(),
|
||||||
description: e.to_string(),
|
description: e.to_string(),
|
||||||
}
|
}
|
||||||
@@ -327,7 +327,7 @@ impl MessageHandler<PortfolioMessage, &InputPreprocessor> for PortfolioMessageHa
|
|||||||
AutoSaveDocument(id) => {
|
AutoSaveDocument(id) => {
|
||||||
let document = self.documents.get(&id).unwrap();
|
let document = self.documents.get(&id).unwrap();
|
||||||
responses.push_back(
|
responses.push_back(
|
||||||
FrontendMessage::AutoSaveDocument {
|
FrontendMessage::TriggerIndexedDbWriteDocument {
|
||||||
document: document.serialize_document(),
|
document: document.serialize_document(),
|
||||||
details: FrontendDocumentDetails {
|
details: FrontendDocumentDetails {
|
||||||
is_saved: document.is_saved(),
|
is_saved: document.is_saved(),
|
||||||
|
|||||||
@@ -15,28 +15,30 @@ pub struct FrontendDocumentDetails {
|
|||||||
#[impl_message(Message, Frontend)]
|
#[impl_message(Message, Frontend)]
|
||||||
#[derive(PartialEq, Clone, Deserialize, Serialize, Debug)]
|
#[derive(PartialEq, Clone, Deserialize, Serialize, Debug)]
|
||||||
pub enum FrontendMessage {
|
pub enum FrontendMessage {
|
||||||
DisplayFolderTreeStructure { data_buffer: RawBuffer },
|
// Display prefix: make the frontend show something, like a dialog
|
||||||
SetActiveTool { tool_name: String, tool_options: Option<ToolOptions> },
|
// Update prefix: give the frontend a new value or state for it to use
|
||||||
SetActiveDocument { document_id: u64 },
|
// Trigger prefix: cause a browser API to do something
|
||||||
|
DisplayDocumentLayerTreeStructure { data_buffer: RawBuffer },
|
||||||
|
UpdateActiveTool { tool_name: String, tool_options: Option<ToolOptions> },
|
||||||
|
UpdateActiveDocument { document_id: u64 },
|
||||||
UpdateOpenDocumentsList { open_documents: Vec<FrontendDocumentDetails> },
|
UpdateOpenDocumentsList { open_documents: Vec<FrontendDocumentDetails> },
|
||||||
UpdateInputHints { hint_data: HintData },
|
UpdateInputHints { hint_data: HintData },
|
||||||
DisplayError { title: String, description: String },
|
DisplayDialogError { title: String, description: String },
|
||||||
DisplayPanic { panic_info: String, title: String, description: String },
|
DisplayDialogPanic { panic_info: String, title: String, description: String },
|
||||||
DisplayConfirmationToCloseDocument { document_id: u64 },
|
DisplayConfirmationToCloseDocument { document_id: u64 },
|
||||||
DisplayConfirmationToCloseAllDocuments,
|
DisplayConfirmationToCloseAllDocuments,
|
||||||
DisplayAboutGraphiteDialog,
|
DisplayDialogAboutGraphite,
|
||||||
UpdateLayer { data: LayerPanelEntry },
|
UpdateDocumentLayer { data: LayerPanelEntry },
|
||||||
UpdateArtwork { svg: String },
|
UpdateDocumentArtwork { svg: String },
|
||||||
UpdateOverlays { svg: String },
|
UpdateDocumentOverlays { svg: String },
|
||||||
UpdateArtboards { svg: String },
|
UpdateDocumentArtboards { svg: String },
|
||||||
UpdateScrollbars { position: (f64, f64), size: (f64, f64), multiplier: (f64, f64) },
|
UpdateDocumentScrollbars { position: (f64, f64), size: (f64, f64), multiplier: (f64, f64) },
|
||||||
UpdateRulers { origin: (f64, f64), spacing: f64, interval: f64 },
|
UpdateDocumentRulers { origin: (f64, f64), spacing: f64, interval: f64 },
|
||||||
ExportDocument { document: String, name: String },
|
TriggerFileUpload,
|
||||||
SaveDocument { document: String, name: String },
|
TriggerFileDownload { document: String, name: String },
|
||||||
AutoSaveDocument { document: String, details: FrontendDocumentDetails, version: String },
|
TriggerIndexedDbWriteDocument { document: String, details: FrontendDocumentDetails, version: String },
|
||||||
RemoveAutoSaveDocument { document_id: u64 },
|
TriggerIndexedDbRemoveDocument { document_id: u64 },
|
||||||
OpenDocumentBrowse,
|
|
||||||
UpdateWorkingColors { primary: Color, secondary: Color },
|
UpdateWorkingColors { primary: Color, secondary: Color },
|
||||||
SetCanvasZoom { new_zoom: f64 },
|
UpdateCanvasZoom { factor: f64 },
|
||||||
SetCanvasRotation { new_radians: f64 },
|
UpdateCanvasRotation { angle_radians: f64 },
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -219,7 +219,7 @@ impl Default for Mapping {
|
|||||||
entry! {action=ToolMessage::ResetColors, key_down=KeyX, modifiers=[KeyShift, KeyControl]},
|
entry! {action=ToolMessage::ResetColors, key_down=KeyX, modifiers=[KeyShift, KeyControl]},
|
||||||
entry! {action=ToolMessage::SwapColors, key_down=KeyX, modifiers=[KeyShift]},
|
entry! {action=ToolMessage::SwapColors, key_down=KeyX, modifiers=[KeyShift]},
|
||||||
// Editor Actions
|
// Editor Actions
|
||||||
entry! {action=FrontendMessage::OpenDocumentBrowse, key_down=KeyO, modifiers=[KeyControl]},
|
entry! {action=FrontendMessage::TriggerFileUpload, key_down=KeyO, modifiers=[KeyControl]},
|
||||||
// Document Actions
|
// Document Actions
|
||||||
entry! {action=PortfolioMessage::Paste(User), key_down=KeyV, modifiers=[KeyControl]},
|
entry! {action=PortfolioMessage::Paste(User), key_down=KeyV, modifiers=[KeyControl]},
|
||||||
entry! {action=DocumentMessage::Redo, key_down=KeyZ, modifiers=[KeyControl, KeyShift]},
|
entry! {action=DocumentMessage::Redo, key_down=KeyZ, modifiers=[KeyControl, KeyShift]},
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ impl MessageHandler<ToolMessage, (&DocumentMessageHandler, &InputPreprocessor)>
|
|||||||
// Notify the frontend about the new active tool to be displayed
|
// Notify the frontend about the new active tool to be displayed
|
||||||
let tool_name = new_tool.to_string();
|
let tool_name = new_tool.to_string();
|
||||||
let tool_options = self.tool_state.document_tool_data.tool_options.get(&new_tool).copied();
|
let tool_options = self.tool_state.document_tool_data.tool_options.get(&new_tool).copied();
|
||||||
responses.push_back(FrontendMessage::SetActiveTool { tool_name, tool_options }.into());
|
responses.push_back(FrontendMessage::UpdateActiveTool { tool_name, tool_options }.into());
|
||||||
}
|
}
|
||||||
DocumentIsDirty => {
|
DocumentIsDirty => {
|
||||||
// Send the DocumentIsDirty message to the active tool's sub-tool message handler
|
// Send the DocumentIsDirty message to the active tool's sub-tool message handler
|
||||||
|
|||||||
@@ -251,7 +251,17 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from "vue";
|
import { defineComponent } from "vue";
|
||||||
|
|
||||||
import { UpdateArtwork, UpdateOverlays, UpdateScrollbars, UpdateRulers, SetActiveTool, SetCanvasZoom, SetCanvasRotation, ToolName, UpdateArtboards } from "@/dispatcher/js-messages";
|
import {
|
||||||
|
UpdateDocumentArtwork,
|
||||||
|
UpdateDocumentOverlays,
|
||||||
|
UpdateDocumentScrollbars,
|
||||||
|
UpdateDocumentRulers,
|
||||||
|
UpdateActiveTool,
|
||||||
|
UpdateCanvasZoom,
|
||||||
|
UpdateCanvasRotation,
|
||||||
|
ToolName,
|
||||||
|
UpdateDocumentArtboards,
|
||||||
|
} from "@/dispatcher/js-messages";
|
||||||
|
|
||||||
import LayoutCol from "@/components/layout/LayoutCol.vue";
|
import LayoutCol from "@/components/layout/LayoutCol.vue";
|
||||||
import LayoutRow from "@/components/layout/LayoutRow.vue";
|
import LayoutRow from "@/components/layout/LayoutRow.vue";
|
||||||
@@ -330,41 +340,41 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.editor.dispatcher.subscribeJsMessage(UpdateArtwork, (UpdateArtwork) => {
|
this.editor.dispatcher.subscribeJsMessage(UpdateDocumentArtwork, (UpdateDocumentArtwork) => {
|
||||||
this.artworkSvg = UpdateArtwork.svg;
|
this.artworkSvg = UpdateDocumentArtwork.svg;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.editor.dispatcher.subscribeJsMessage(UpdateOverlays, (updateOverlays) => {
|
this.editor.dispatcher.subscribeJsMessage(UpdateDocumentOverlays, (updateDocumentOverlays) => {
|
||||||
this.overlaysSvg = updateOverlays.svg;
|
this.overlaysSvg = updateDocumentOverlays.svg;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.editor.dispatcher.subscribeJsMessage(UpdateArtboards, (updateArtboards) => {
|
this.editor.dispatcher.subscribeJsMessage(UpdateDocumentArtboards, (updateDocumentArtboards) => {
|
||||||
this.artboardSvg = updateArtboards.svg;
|
this.artboardSvg = updateDocumentArtboards.svg;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.editor.dispatcher.subscribeJsMessage(UpdateScrollbars, (updateScrollbars) => {
|
this.editor.dispatcher.subscribeJsMessage(UpdateDocumentScrollbars, (updateDocumentScrollbars) => {
|
||||||
this.scrollbarPos = updateScrollbars.position;
|
this.scrollbarPos = updateDocumentScrollbars.position;
|
||||||
this.scrollbarSize = updateScrollbars.size;
|
this.scrollbarSize = updateDocumentScrollbars.size;
|
||||||
this.scrollbarMultiplier = updateScrollbars.multiplier;
|
this.scrollbarMultiplier = updateDocumentScrollbars.multiplier;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.editor.dispatcher.subscribeJsMessage(UpdateRulers, (updateRulers) => {
|
this.editor.dispatcher.subscribeJsMessage(UpdateDocumentRulers, (updateDocumentRulers) => {
|
||||||
this.rulerOrigin = updateRulers.origin;
|
this.rulerOrigin = updateDocumentRulers.origin;
|
||||||
this.rulerSpacing = updateRulers.spacing;
|
this.rulerSpacing = updateDocumentRulers.spacing;
|
||||||
this.rulerInterval = updateRulers.interval;
|
this.rulerInterval = updateDocumentRulers.interval;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.editor.dispatcher.subscribeJsMessage(SetActiveTool, (setActiveTool) => {
|
this.editor.dispatcher.subscribeJsMessage(UpdateActiveTool, (updateActiveTool) => {
|
||||||
this.activeTool = setActiveTool.tool_name;
|
this.activeTool = updateActiveTool.tool_name;
|
||||||
this.activeToolOptions = setActiveTool.tool_options;
|
this.activeToolOptions = updateActiveTool.tool_options;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.editor.dispatcher.subscribeJsMessage(SetCanvasZoom, (setCanvasZoom) => {
|
this.editor.dispatcher.subscribeJsMessage(UpdateCanvasZoom, (updateCanvasZoom) => {
|
||||||
this.documentZoom = setCanvasZoom.new_zoom * 100;
|
this.documentZoom = updateCanvasZoom.factor * 100;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.editor.dispatcher.subscribeJsMessage(SetCanvasRotation, (setCanvasRotation) => {
|
this.editor.dispatcher.subscribeJsMessage(UpdateCanvasRotation, (updateCanvasRotation) => {
|
||||||
const newRotation = setCanvasRotation.new_radians * (180 / Math.PI);
|
const newRotation = updateCanvasRotation.angle_radians * (180 / Math.PI);
|
||||||
this.documentRotation = (360 + (newRotation % 360)) % 360;
|
this.documentRotation = (360 + (newRotation % 360)) % 360;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -242,7 +242,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from "vue";
|
import { defineComponent } from "vue";
|
||||||
|
|
||||||
import { BlendMode, DisplayFolderTreeStructure, UpdateLayer, LayerPanelEntry } from "@/dispatcher/js-messages";
|
import { BlendMode, DisplayDocumentLayerTreeStructure, UpdateDocumentLayer, LayerPanelEntry } from "@/dispatcher/js-messages";
|
||||||
|
|
||||||
import LayoutCol from "@/components/layout/LayoutCol.vue";
|
import LayoutCol from "@/components/layout/LayoutCol.vue";
|
||||||
import LayoutRow from "@/components/layout/LayoutRow.vue";
|
import LayoutRow from "@/components/layout/LayoutRow.vue";
|
||||||
@@ -498,11 +498,11 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.editor.dispatcher.subscribeJsMessage(DisplayFolderTreeStructure, (displayFolderTreeStructure) => {
|
this.editor.dispatcher.subscribeJsMessage(DisplayDocumentLayerTreeStructure, (displayDocumentLayerTreeStructure) => {
|
||||||
const path = [] as bigint[];
|
const path = [] as bigint[];
|
||||||
this.layers = [] as { folderIndex: number; entry: LayerPanelEntry }[];
|
this.layers = [] as { folderIndex: number; entry: LayerPanelEntry }[];
|
||||||
|
|
||||||
const recurse = (folder: DisplayFolderTreeStructure, layers: { folderIndex: number; entry: LayerPanelEntry }[], cache: Map<string, LayerPanelEntry>): void => {
|
const recurse = (folder: DisplayDocumentLayerTreeStructure, layers: { folderIndex: number; entry: LayerPanelEntry }[], cache: Map<string, LayerPanelEntry>): void => {
|
||||||
folder.children.forEach((item, index) => {
|
folder.children.forEach((item, index) => {
|
||||||
// TODO: fix toString
|
// TODO: fix toString
|
||||||
path.push(BigInt(item.layerId.toString()));
|
path.push(BigInt(item.layerId.toString()));
|
||||||
@@ -513,12 +513,12 @@ export default defineComponent({
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
recurse(displayFolderTreeStructure, this.layers, this.layerCache);
|
recurse(displayDocumentLayerTreeStructure, this.layers, this.layerCache);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.editor.dispatcher.subscribeJsMessage(UpdateLayer, (updateLayer) => {
|
this.editor.dispatcher.subscribeJsMessage(UpdateDocumentLayer, (updateDocumentLayer) => {
|
||||||
const targetPath = updateLayer.data.path;
|
const targetPath = updateDocumentLayer.data.path;
|
||||||
const targetLayer = updateLayer.data;
|
const targetLayer = updateDocumentLayer.data;
|
||||||
|
|
||||||
const layer = this.layerCache.get(targetPath.toString());
|
const layer = this.layerCache.get(targetPath.toString());
|
||||||
if (layer) {
|
if (layer) {
|
||||||
|
|||||||
@@ -135,23 +135,23 @@ export type ToolName =
|
|||||||
| "Ellipse"
|
| "Ellipse"
|
||||||
| "Shape";
|
| "Shape";
|
||||||
|
|
||||||
export class SetActiveTool extends JsMessage {
|
export class UpdateActiveTool extends JsMessage {
|
||||||
readonly tool_name!: ToolName;
|
readonly tool_name!: ToolName;
|
||||||
|
|
||||||
readonly tool_options!: object;
|
readonly tool_options!: object;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class SetActiveDocument extends JsMessage {
|
export class UpdateActiveDocument extends JsMessage {
|
||||||
readonly document_id!: BigInt;
|
readonly document_id!: BigInt;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class DisplayError extends JsMessage {
|
export class DisplayDialogError extends JsMessage {
|
||||||
readonly title!: string;
|
readonly title!: string;
|
||||||
|
|
||||||
readonly description!: string;
|
readonly description!: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class DisplayPanic extends JsMessage {
|
export class DisplayDialogPanic extends JsMessage {
|
||||||
readonly panic_info!: string;
|
readonly panic_info!: string;
|
||||||
|
|
||||||
readonly title!: string;
|
readonly title!: string;
|
||||||
@@ -165,23 +165,23 @@ export class DisplayConfirmationToCloseDocument extends JsMessage {
|
|||||||
|
|
||||||
export class DisplayConfirmationToCloseAllDocuments extends JsMessage {}
|
export class DisplayConfirmationToCloseAllDocuments extends JsMessage {}
|
||||||
|
|
||||||
export class DisplayAboutGraphiteDialog extends JsMessage {}
|
export class DisplayDialogAboutGraphite extends JsMessage {}
|
||||||
|
|
||||||
export class UpdateArtwork extends JsMessage {
|
export class UpdateDocumentArtwork extends JsMessage {
|
||||||
readonly svg!: string;
|
readonly svg!: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class UpdateOverlays extends JsMessage {
|
export class UpdateDocumentOverlays extends JsMessage {
|
||||||
readonly svg!: string;
|
readonly svg!: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class UpdateArtboards extends JsMessage {
|
export class UpdateDocumentArtboards extends JsMessage {
|
||||||
readonly svg!: string;
|
readonly svg!: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const TupleToVec2 = Transform(({ value }) => ({ x: value[0], y: value[1] }));
|
const TupleToVec2 = Transform(({ value }) => ({ x: value[0], y: value[1] }));
|
||||||
|
|
||||||
export class UpdateScrollbars extends JsMessage {
|
export class UpdateDocumentScrollbars extends JsMessage {
|
||||||
@TupleToVec2
|
@TupleToVec2
|
||||||
readonly position!: { x: number; y: number };
|
readonly position!: { x: number; y: number };
|
||||||
|
|
||||||
@@ -192,7 +192,7 @@ export class UpdateScrollbars extends JsMessage {
|
|||||||
readonly multiplier!: { x: number; y: number };
|
readonly multiplier!: { x: number; y: number };
|
||||||
}
|
}
|
||||||
|
|
||||||
export class UpdateRulers extends JsMessage {
|
export class UpdateDocumentRulers extends JsMessage {
|
||||||
@TupleToVec2
|
@TupleToVec2
|
||||||
readonly origin!: { x: number; y: number };
|
readonly origin!: { x: number; y: number };
|
||||||
|
|
||||||
@@ -201,24 +201,18 @@ export class UpdateRulers extends JsMessage {
|
|||||||
readonly interval!: number;
|
readonly interval!: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ExportDocument extends JsMessage {
|
export class TriggerFileDownload extends JsMessage {
|
||||||
readonly document!: string;
|
readonly document!: string;
|
||||||
|
|
||||||
readonly name!: string;
|
readonly name!: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class SaveDocument extends JsMessage {
|
export class TriggerFileUpload extends JsMessage {}
|
||||||
readonly document!: string;
|
|
||||||
|
|
||||||
readonly name!: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class OpenDocumentBrowse extends JsMessage {}
|
|
||||||
|
|
||||||
export class DocumentChanged extends JsMessage {}
|
export class DocumentChanged extends JsMessage {}
|
||||||
|
|
||||||
export class DisplayFolderTreeStructure extends JsMessage {
|
export class DisplayDocumentLayerTreeStructure extends JsMessage {
|
||||||
constructor(readonly layerId: BigInt, readonly children: DisplayFolderTreeStructure[]) {
|
constructor(readonly layerId: BigInt, readonly children: DisplayDocumentLayerTreeStructure[]) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -228,7 +222,7 @@ interface DataBuffer {
|
|||||||
length: BigInt;
|
length: BigInt;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function newDisplayFolderTreeStructure(input: { data_buffer: DataBuffer }, wasm: WasmInstance): DisplayFolderTreeStructure {
|
export function newDisplayDocumentLayerTreeStructure(input: { data_buffer: DataBuffer }, wasm: WasmInstance): DisplayDocumentLayerTreeStructure {
|
||||||
const { pointer, length } = input.data_buffer;
|
const { pointer, length } = input.data_buffer;
|
||||||
const pointerNum = Number(pointer);
|
const pointerNum = Number(pointer);
|
||||||
const lengthNum = Number(length);
|
const lengthNum = Number(length);
|
||||||
@@ -245,7 +239,7 @@ export function newDisplayFolderTreeStructure(input: { data_buffer: DataBuffer }
|
|||||||
const layerIdsSection = new DataView(wasmMemoryBuffer, pointerNum + 8 + structureSectionLength * 8);
|
const layerIdsSection = new DataView(wasmMemoryBuffer, pointerNum + 8 + structureSectionLength * 8);
|
||||||
|
|
||||||
let layersEncountered = 0;
|
let layersEncountered = 0;
|
||||||
let currentFolder = new DisplayFolderTreeStructure(BigInt(-1), []);
|
let currentFolder = new DisplayDocumentLayerTreeStructure(BigInt(-1), []);
|
||||||
const currentFolderStack = [currentFolder];
|
const currentFolderStack = [currentFolder];
|
||||||
|
|
||||||
for (let i = 0; i < structureSectionLength; i += 1) {
|
for (let i = 0; i < structureSectionLength; i += 1) {
|
||||||
@@ -260,7 +254,7 @@ export function newDisplayFolderTreeStructure(input: { data_buffer: DataBuffer }
|
|||||||
const layerId = layerIdsSection.getBigUint64(layersEncountered * 8, true);
|
const layerId = layerIdsSection.getBigUint64(layersEncountered * 8, true);
|
||||||
layersEncountered += 1;
|
layersEncountered += 1;
|
||||||
|
|
||||||
const childLayer = new DisplayFolderTreeStructure(layerId, []);
|
const childLayer = new DisplayDocumentLayerTreeStructure(layerId, []);
|
||||||
currentFolder.children.push(childLayer);
|
currentFolder.children.push(childLayer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -282,17 +276,17 @@ export function newDisplayFolderTreeStructure(input: { data_buffer: DataBuffer }
|
|||||||
return currentFolder;
|
return currentFolder;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class UpdateLayer extends JsMessage {
|
export class UpdateDocumentLayer extends JsMessage {
|
||||||
@Type(() => LayerPanelEntry)
|
@Type(() => LayerPanelEntry)
|
||||||
readonly data!: LayerPanelEntry;
|
readonly data!: LayerPanelEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class SetCanvasZoom extends JsMessage {
|
export class UpdateCanvasZoom extends JsMessage {
|
||||||
readonly new_zoom!: number;
|
readonly factor!: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class SetCanvasRotation extends JsMessage {
|
export class UpdateCanvasRotation extends JsMessage {
|
||||||
readonly new_radians!: number;
|
readonly angle_radians!: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type BlendMode =
|
export type BlendMode =
|
||||||
@@ -348,7 +342,7 @@ export class IndexedDbDocumentDetails extends DocumentDetails {
|
|||||||
id!: string;
|
id!: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class AutoSaveDocument extends JsMessage {
|
export class TriggerIndexedDbWriteDocument extends JsMessage {
|
||||||
document!: string;
|
document!: string;
|
||||||
|
|
||||||
@Type(() => IndexedDbDocumentDetails)
|
@Type(() => IndexedDbDocumentDetails)
|
||||||
@@ -357,7 +351,7 @@ export class AutoSaveDocument extends JsMessage {
|
|||||||
version!: string;
|
version!: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class RemoveAutoSaveDocument extends JsMessage {
|
export class TriggerIndexedDbRemoveDocument extends JsMessage {
|
||||||
// Use a string since IndexedDB can not use BigInts for keys
|
// Use a string since IndexedDB can not use BigInts for keys
|
||||||
@Transform(({ value }: { value: BigInt }) => value.toString())
|
@Transform(({ value }: { value: BigInt }) => value.toString())
|
||||||
document_id!: string;
|
document_id!: string;
|
||||||
@@ -369,29 +363,28 @@ type JSMessageFactory = (data: any, wasm: WasmInstance, instance: RustEditorInst
|
|||||||
type MessageMaker = typeof JsMessage | JSMessageFactory;
|
type MessageMaker = typeof JsMessage | JSMessageFactory;
|
||||||
|
|
||||||
export const messageConstructors: Record<string, MessageMaker> = {
|
export const messageConstructors: Record<string, MessageMaker> = {
|
||||||
UpdateArtwork,
|
UpdateDocumentArtwork,
|
||||||
UpdateOverlays,
|
UpdateDocumentOverlays,
|
||||||
UpdateScrollbars,
|
UpdateDocumentScrollbars,
|
||||||
UpdateRulers,
|
UpdateDocumentRulers,
|
||||||
ExportDocument,
|
TriggerFileDownload,
|
||||||
SaveDocument,
|
TriggerFileUpload,
|
||||||
OpenDocumentBrowse,
|
DisplayDocumentLayerTreeStructure: newDisplayDocumentLayerTreeStructure,
|
||||||
DisplayFolderTreeStructure: newDisplayFolderTreeStructure,
|
UpdateDocumentLayer,
|
||||||
UpdateLayer,
|
UpdateActiveTool,
|
||||||
SetActiveTool,
|
UpdateActiveDocument,
|
||||||
SetActiveDocument,
|
|
||||||
UpdateOpenDocumentsList,
|
UpdateOpenDocumentsList,
|
||||||
UpdateInputHints,
|
UpdateInputHints,
|
||||||
UpdateWorkingColors,
|
UpdateWorkingColors,
|
||||||
SetCanvasZoom,
|
UpdateCanvasZoom,
|
||||||
SetCanvasRotation,
|
UpdateCanvasRotation,
|
||||||
DisplayError,
|
DisplayDialogError,
|
||||||
DisplayPanic,
|
DisplayDialogPanic,
|
||||||
DisplayConfirmationToCloseDocument,
|
DisplayConfirmationToCloseDocument,
|
||||||
DisplayConfirmationToCloseAllDocuments,
|
DisplayConfirmationToCloseAllDocuments,
|
||||||
DisplayAboutGraphiteDialog,
|
DisplayDialogAboutGraphite,
|
||||||
AutoSaveDocument,
|
TriggerIndexedDbWriteDocument,
|
||||||
RemoveAutoSaveDocument,
|
TriggerIndexedDbRemoveDocument,
|
||||||
UpdateArtboards,
|
UpdateDocumentArtboards,
|
||||||
} as const;
|
} as const;
|
||||||
export type JsMessageType = keyof typeof messageConstructors;
|
export type JsMessageType = keyof typeof messageConstructors;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { AutoSaveDocument, RemoveAutoSaveDocument } from "@/dispatcher/js-messages";
|
import { TriggerIndexedDbWriteDocument, TriggerIndexedDbRemoveDocument } from "@/dispatcher/js-messages";
|
||||||
import { DocumentsState } from "@/state/documents";
|
import { DocumentsState } from "@/state/documents";
|
||||||
import { EditorState, getWasmInstance } from "@/state/wasm-loader";
|
import { EditorState, getWasmInstance } from "@/state/wasm-loader";
|
||||||
|
|
||||||
@@ -39,13 +39,15 @@ export function createAutoSaveManager(editor: EditorState, documents: DocumentsS
|
|||||||
|
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
request.onsuccess = (): void => {
|
request.onsuccess = (): void => {
|
||||||
const previouslySavedDocuments: AutoSaveDocument[] = request.result;
|
const previouslySavedDocuments: TriggerIndexedDbWriteDocument[] = request.result;
|
||||||
|
|
||||||
const documentOrder: string[] = JSON.parse(window.localStorage.getItem(GRAPHITE_AUTO_SAVE_ORDER_KEY) || "[]");
|
const documentOrder: string[] = JSON.parse(window.localStorage.getItem(GRAPHITE_AUTO_SAVE_ORDER_KEY) || "[]");
|
||||||
const orderedSavedDocuments = documentOrder.map((id) => previouslySavedDocuments.find((autoSave) => autoSave.details.id === id)).filter((x) => x !== undefined) as AutoSaveDocument[];
|
const orderedSavedDocuments = documentOrder
|
||||||
|
.map((id) => previouslySavedDocuments.find((autoSave) => autoSave.details.id === id))
|
||||||
|
.filter((x) => x !== undefined) as TriggerIndexedDbWriteDocument[];
|
||||||
|
|
||||||
const currentDocumentVersion = getWasmInstance().graphite_version();
|
const currentDocumentVersion = getWasmInstance().graphite_version();
|
||||||
orderedSavedDocuments.forEach((doc: AutoSaveDocument) => {
|
orderedSavedDocuments.forEach((doc: TriggerIndexedDbWriteDocument) => {
|
||||||
if (doc.version === currentDocumentVersion) {
|
if (doc.version === currentDocumentVersion) {
|
||||||
editor.instance.open_auto_saved_document(BigInt(doc.details.id), doc.details.name, doc.details.is_saved, doc.document);
|
editor.instance.open_auto_saved_document(BigInt(doc.details.id), doc.details.name, doc.details.is_saved, doc.document);
|
||||||
} else {
|
} else {
|
||||||
@@ -70,14 +72,14 @@ export function createAutoSaveManager(editor: EditorState, documents: DocumentsS
|
|||||||
storeDocumentOrder();
|
storeDocumentOrder();
|
||||||
};
|
};
|
||||||
|
|
||||||
editor.dispatcher.subscribeJsMessage(AutoSaveDocument, async (autoSaveDocument) => {
|
editor.dispatcher.subscribeJsMessage(TriggerIndexedDbWriteDocument, async (autoSaveDocument) => {
|
||||||
const db = await databaseConnection;
|
const db = await databaseConnection;
|
||||||
const transaction = db.transaction(GRAPHITE_AUTO_SAVE_STORE, "readwrite");
|
const transaction = db.transaction(GRAPHITE_AUTO_SAVE_STORE, "readwrite");
|
||||||
transaction.objectStore(GRAPHITE_AUTO_SAVE_STORE).put(autoSaveDocument);
|
transaction.objectStore(GRAPHITE_AUTO_SAVE_STORE).put(autoSaveDocument);
|
||||||
storeDocumentOrder();
|
storeDocumentOrder();
|
||||||
});
|
});
|
||||||
|
|
||||||
editor.dispatcher.subscribeJsMessage(RemoveAutoSaveDocument, async (removeAutoSaveDocument) => {
|
editor.dispatcher.subscribeJsMessage(TriggerIndexedDbRemoveDocument, async (removeAutoSaveDocument) => {
|
||||||
removeDocument(removeAutoSaveDocument.document_id);
|
removeDocument(removeAutoSaveDocument.document_id);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { DisplayError, DisplayPanic } from "@/dispatcher/js-messages";
|
import { DisplayDialogError, DisplayDialogPanic } from "@/dispatcher/js-messages";
|
||||||
import { DialogState } from "@/state/dialog";
|
import { DialogState } from "@/state/dialog";
|
||||||
import { EditorState } from "@/state/wasm-loader";
|
import { EditorState } from "@/state/wasm-loader";
|
||||||
import { stripIndents } from "@/utilities/strip-indents";
|
import { stripIndents } from "@/utilities/strip-indents";
|
||||||
@@ -6,7 +6,7 @@ import { TextButtonWidget } from "@/utilities/widgets";
|
|||||||
|
|
||||||
export function initErrorHandling(editor: EditorState, dialogState: DialogState): void {
|
export function initErrorHandling(editor: EditorState, dialogState: DialogState): void {
|
||||||
// Graphite error dialog
|
// Graphite error dialog
|
||||||
editor.dispatcher.subscribeJsMessage(DisplayError, (displayError) => {
|
editor.dispatcher.subscribeJsMessage(DisplayDialogError, (displayDialogError) => {
|
||||||
const okButton: TextButtonWidget = {
|
const okButton: TextButtonWidget = {
|
||||||
kind: "TextButton",
|
kind: "TextButton",
|
||||||
callback: async () => dialogState.dismissDialog(),
|
callback: async () => dialogState.dismissDialog(),
|
||||||
@@ -14,16 +14,16 @@ export function initErrorHandling(editor: EditorState, dialogState: DialogState)
|
|||||||
};
|
};
|
||||||
const buttons = [okButton];
|
const buttons = [okButton];
|
||||||
|
|
||||||
dialogState.createDialog("Warning", displayError.title, displayError.description, buttons);
|
dialogState.createDialog("Warning", displayDialogError.title, displayDialogError.description, buttons);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Code panic dialog and console error
|
// Code panic dialog and console error
|
||||||
editor.dispatcher.subscribeJsMessage(DisplayPanic, (displayPanic) => {
|
editor.dispatcher.subscribeJsMessage(DisplayDialogPanic, (displayDialogPanic) => {
|
||||||
// `Error.stackTraceLimit` is only available in V8/Chromium
|
// `Error.stackTraceLimit` is only available in V8/Chromium
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
(Error as any).stackTraceLimit = Infinity;
|
(Error as any).stackTraceLimit = Infinity;
|
||||||
const stackTrace = new Error().stack || "";
|
const stackTrace = new Error().stack || "";
|
||||||
const panicDetails = `${displayPanic.panic_info}\n\n${stackTrace}`;
|
const panicDetails = `${displayDialogPanic.panic_info}\n\n${stackTrace}`;
|
||||||
|
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.error(panicDetails);
|
console.error(panicDetails);
|
||||||
@@ -45,7 +45,7 @@ export function initErrorHandling(editor: EditorState, dialogState: DialogState)
|
|||||||
};
|
};
|
||||||
const buttons = [reloadButton, copyErrorLogButton, reportOnGithubButton];
|
const buttons = [reloadButton, copyErrorLogButton, reportOnGithubButton];
|
||||||
|
|
||||||
dialogState.createDialog("Warning", displayPanic.title, displayPanic.description, buttons);
|
dialogState.createDialog("Warning", displayDialogPanic.title, displayDialogPanic.description, buttons);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { reactive, readonly } from "vue";
|
import { reactive, readonly } from "vue";
|
||||||
|
|
||||||
import { DisplayAboutGraphiteDialog } from "@/dispatcher/js-messages";
|
import { DisplayDialogAboutGraphite } from "@/dispatcher/js-messages";
|
||||||
import { EditorState } from "@/state/wasm-loader";
|
import { EditorState } from "@/state/wasm-loader";
|
||||||
import { IconName } from "@/utilities/icons";
|
import { IconName } from "@/utilities/icons";
|
||||||
import { stripIndents } from "@/utilities/strip-indents";
|
import { stripIndents } from "@/utilities/strip-indents";
|
||||||
@@ -106,7 +106,7 @@ export function createDialogState(editor: EditorState) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Run on creation
|
// Run on creation
|
||||||
editor.dispatcher.subscribeJsMessage(DisplayAboutGraphiteDialog, () => onAboutHandler());
|
editor.dispatcher.subscribeJsMessage(DisplayDialogAboutGraphite, () => onAboutHandler());
|
||||||
|
|
||||||
return {
|
return {
|
||||||
state: readonly(state),
|
state: readonly(state),
|
||||||
|
|||||||
@@ -4,11 +4,10 @@ import { reactive, readonly } from "vue";
|
|||||||
import {
|
import {
|
||||||
DisplayConfirmationToCloseAllDocuments,
|
DisplayConfirmationToCloseAllDocuments,
|
||||||
DisplayConfirmationToCloseDocument,
|
DisplayConfirmationToCloseDocument,
|
||||||
ExportDocument,
|
TriggerFileDownload,
|
||||||
FrontendDocumentDetails,
|
FrontendDocumentDetails,
|
||||||
OpenDocumentBrowse,
|
TriggerFileUpload,
|
||||||
SaveDocument,
|
UpdateActiveDocument,
|
||||||
SetActiveDocument,
|
|
||||||
UpdateOpenDocumentsList,
|
UpdateOpenDocumentsList,
|
||||||
} from "@/dispatcher/js-messages";
|
} from "@/dispatcher/js-messages";
|
||||||
import { DialogState } from "@/state/dialog";
|
import { DialogState } from "@/state/dialog";
|
||||||
@@ -81,9 +80,9 @@ export function createDocumentsState(editor: EditorState, dialogState: DialogSta
|
|||||||
state.documents = updateOpenDocumentList.open_documents;
|
state.documents = updateOpenDocumentList.open_documents;
|
||||||
});
|
});
|
||||||
|
|
||||||
editor.dispatcher.subscribeJsMessage(SetActiveDocument, (setActiveDocument) => {
|
editor.dispatcher.subscribeJsMessage(UpdateActiveDocument, (updateActiveDocument) => {
|
||||||
// Assume we receive a correct document id
|
// Assume we receive a correct document id
|
||||||
const activeId = state.documents.findIndex((doc) => doc.id === setActiveDocument.document_id);
|
const activeId = state.documents.findIndex((doc) => doc.id === updateActiveDocument.document_id);
|
||||||
state.activeDocumentIndex = activeId;
|
state.activeDocumentIndex = activeId;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -95,18 +94,14 @@ export function createDocumentsState(editor: EditorState, dialogState: DialogSta
|
|||||||
closeAllDocumentsWithConfirmation();
|
closeAllDocumentsWithConfirmation();
|
||||||
});
|
});
|
||||||
|
|
||||||
editor.dispatcher.subscribeJsMessage(OpenDocumentBrowse, async () => {
|
editor.dispatcher.subscribeJsMessage(TriggerFileUpload, async () => {
|
||||||
const extension = editor.rawWasm.file_save_suffix();
|
const extension = editor.rawWasm.file_save_suffix();
|
||||||
const data = await upload(extension);
|
const data = await upload(extension);
|
||||||
editor.instance.open_document_file(data.filename, data.content);
|
editor.instance.open_document_file(data.filename, data.content);
|
||||||
});
|
});
|
||||||
|
|
||||||
editor.dispatcher.subscribeJsMessage(ExportDocument, (exportDocument) => {
|
editor.dispatcher.subscribeJsMessage(TriggerFileDownload, (triggerFileDownload) => {
|
||||||
download(exportDocument.name, exportDocument.document);
|
download(triggerFileDownload.name, triggerFileDownload.document);
|
||||||
});
|
|
||||||
|
|
||||||
editor.dispatcher.subscribeJsMessage(SaveDocument, (saveDocument) => {
|
|
||||||
download(saveDocument.name, saveDocument.document);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Get the initial documents
|
// Get the initial documents
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ fn panic_hook(info: &panic::PanicInfo) {
|
|||||||
log::error!("{}", info);
|
log::error!("{}", info);
|
||||||
EDITOR_INSTANCES.with(|instances| {
|
EDITOR_INSTANCES.with(|instances| {
|
||||||
instances.borrow_mut().values_mut().for_each(|instance| {
|
instances.borrow_mut().values_mut().for_each(|instance| {
|
||||||
instance.1.handle_response_rust_proxy(FrontendMessage::DisplayPanic {
|
instance.1.handle_response_rust_proxy(FrontendMessage::DisplayDialogPanic {
|
||||||
panic_info: panic_info.clone(),
|
panic_info: panic_info.clone(),
|
||||||
title: title.clone(),
|
title: title.clone(),
|
||||||
description: description.clone(),
|
description: description.clone(),
|
||||||
|
|||||||
Reference in New Issue
Block a user