Feat: bank / pattern import / export feature + documentation

This commit is contained in:
2026-02-26 00:20:46 +01:00
parent 6dd265067f
commit 71bd09d5ea
15 changed files with 412 additions and 3 deletions

View File

@@ -168,6 +168,111 @@ impl App {
}
}
pub fn share_pattern(&mut self, bank: usize, pattern: usize) {
let pattern_data = &self.project_state.project.banks[bank].patterns[pattern];
match model::share::export(pattern_data) {
Ok(encoded) => {
let len = encoded.len();
if let Some(clip) = &mut self.clipboard {
let _ = clip.set_text(encoded);
}
if len > 2000 {
self.ui.flash(
&format!("Shared ({len} chars — too long for Discord)"),
200,
FlashKind::Error,
);
} else {
self.ui
.flash(&format!("Shared ({len} chars)"), 150, FlashKind::Success);
}
}
Err(e) => {
self.ui
.flash(&format!("Share failed: {e}"), 200, FlashKind::Error);
}
}
}
pub fn share_bank(&mut self, bank: usize) {
let bank_data = &self.project_state.project.banks[bank];
match model::share::export_bank(bank_data) {
Ok(encoded) => {
let len = encoded.len();
if let Some(clip) = &mut self.clipboard {
let _ = clip.set_text(encoded);
}
if len > 2000 {
self.ui.flash(
&format!("Bank shared ({len} chars — too long for Discord)"),
200,
FlashKind::Error,
);
} else {
self.ui
.flash(&format!("Bank shared ({len} chars)"), 150, FlashKind::Success);
}
}
Err(e) => {
self.ui
.flash(&format!("Share failed: {e}"), 200, FlashKind::Error);
}
}
}
pub fn import_bank(&mut self, bank: usize) {
let text = match self.clipboard.as_mut().and_then(|c| c.get_text().ok()) {
Some(t) => t,
None => {
self.ui.flash("Clipboard empty", 150, FlashKind::Error);
return;
}
};
match model::share::import_bank(&text) {
Ok(imported) => {
self.project_state.project.banks[bank] = imported;
for pattern in 0..model::MAX_PATTERNS {
self.project_state.mark_dirty(bank, pattern);
}
if self.editor_ctx.bank == bank {
self.load_step_to_editor();
}
self.ui
.flash("Bank imported", 150, FlashKind::Success);
}
Err(e) => {
self.ui
.flash(&format!("Import failed: {e}"), 200, FlashKind::Error);
}
}
}
pub fn import_pattern(&mut self, bank: usize, pattern: usize) {
let text = match self.clipboard.as_mut().and_then(|c| c.get_text().ok()) {
Some(t) => t,
None => {
self.ui
.flash("Clipboard empty", 150, FlashKind::Error);
return;
}
};
match model::share::import(&text) {
Ok(imported) => {
self.project_state.project.banks[bank].patterns[pattern] = imported;
self.project_state.mark_dirty(bank, pattern);
if self.editor_ctx.bank == bank && self.editor_ctx.pattern == pattern {
self.load_step_to_editor();
}
self.ui
.flash("Pattern imported", 150, FlashKind::Success);
}
Err(e) => {
self.ui
.flash(&format!("Import failed: {e}"), 200, FlashKind::Error);
}
}
}
pub fn harden_steps(&mut self) {
let (bank, pattern) = self.current_bank_pattern();
let indices = self.selected_steps();