mirror of
https://github.com/JannisX11/blockbench.git
synced 2025-01-18 15:26:19 +08:00
Add backup browser
This commit is contained in:
parent
398529400a
commit
b754f66003
@ -1568,6 +1568,66 @@ dialog#edit_bedrock_binding > .dialog_wrapper > .dialog_content {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
/* View Backups */
|
||||
ul#view_backups_list {
|
||||
max-height: calc(95vh - 220px);
|
||||
margin-top: 8px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
ul#view_backups_list > li {
|
||||
padding: 2px 6px;
|
||||
cursor: pointer;
|
||||
border: 2px solid transparent;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
ul#view_backups_list > li.current {
|
||||
border-color: var(--color-accent);
|
||||
}
|
||||
ul#view_backups_list > li:hover {
|
||||
color: var(--color-light);
|
||||
}
|
||||
ul#view_backups_list > li.selected {
|
||||
background-color: var(--color-accent);
|
||||
color: var(--color-accent_text);
|
||||
position: relative;
|
||||
}
|
||||
#view_backups_list span {
|
||||
flex-grow: 1;
|
||||
}
|
||||
#view_backups_list .view_backups_info_field {
|
||||
color: var(--color-subtle_text);
|
||||
width: 90px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
cursor: inherit;
|
||||
text-align: right;
|
||||
}
|
||||
#view_backups_list .view_backups_info_field:last-child {
|
||||
width: 82px;
|
||||
}
|
||||
ul#view_backups_list > li.selected .view_backups_info_field {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
ol.pagination_numbers {
|
||||
display: flex;
|
||||
gap: 3px;
|
||||
justify-content: center;
|
||||
}
|
||||
ol.pagination_numbers > li {
|
||||
border-radius: 3px;
|
||||
cursor: pointer;
|
||||
padding: 0px 7px;
|
||||
min-width: 22px;
|
||||
}
|
||||
ol.pagination_numbers > li:hover, ol.pagination_numbers > li.selected {
|
||||
background-color: var(--color-accent);
|
||||
color: var(--color-accent_text);
|
||||
}
|
||||
|
||||
|
||||
/* Custom Brush Options */
|
||||
dialog#brush_options:not(.preset_selected) div.form_bar,
|
||||
dialog#brush_options:not(.preset_selected) hr {
|
||||
|
112
js/desktop.js
112
js/desktop.js
@ -450,6 +450,118 @@ function createBackup(init) {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
BARS.defineActions(() => {
|
||||
|
||||
let selected_id; // Remember selected one after re-opening
|
||||
new Action('view_backups', {
|
||||
icon: 'fa-archive',
|
||||
category: 'file',
|
||||
condition: () => isApp,
|
||||
click(e) {
|
||||
|
||||
let backup_directory = app.getPath('userData')+osfs+'backups';
|
||||
let files = fs.readdirSync(backup_directory);
|
||||
|
||||
let entries = files.map((file, i) => {
|
||||
let path = PathModule.join(backup_directory, file);
|
||||
let stats = fs.statSync(path);
|
||||
|
||||
let size = `${separateThousands(Math.round(stats.size / 1024))} KB`;
|
||||
let entry = {
|
||||
id: file,
|
||||
path,
|
||||
name: file.replace(/backup_\d+\.\d+\.\d+_\d+\.\d+_?/, '').replace(/\.bbmodel$/, '').replace(/_/g, ' ') || 'no name',
|
||||
date: stats.mtime.toLocaleDateString(),
|
||||
time: stats.mtime.toLocaleTimeString().replace(/:\d+ /, ' '),
|
||||
date_long: stats.mtime.toString(),
|
||||
timestamp: stats.mtime.getTime(),
|
||||
size,
|
||||
}
|
||||
return entry;
|
||||
})
|
||||
entries.sort((a, b) => b.timestamp - a.timestamp);
|
||||
|
||||
let selected;
|
||||
const dialog = new Dialog({
|
||||
id: 'view_backups',
|
||||
title: 'action.view_backups',
|
||||
width: 720,
|
||||
buttons: ['dialog.confirm', 'dialog.view_backups.open_folder', 'dialog.cancel'],
|
||||
component: {
|
||||
data() {return {
|
||||
backups: entries,
|
||||
page: 0,
|
||||
per_page: 80,
|
||||
search_term: '',
|
||||
selected: (selected_id ? entries.find(e => e.id == selected_id) : null)
|
||||
}},
|
||||
methods: {
|
||||
select(backup) {
|
||||
selected = this.selected = backup;
|
||||
selected_id = backup.id;
|
||||
},
|
||||
open() {
|
||||
dialog.confirm();
|
||||
},
|
||||
setPage(number) {
|
||||
this.page = number;
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
filtered_backups() {
|
||||
let term = this.search_term.toLowerCase();
|
||||
return this.backups.filter(backup => {
|
||||
return backup.name.includes(term);
|
||||
})
|
||||
},
|
||||
viewed_backups() {
|
||||
return this.filtered_backups.slice(this.page * this.per_page, (this.page+1) * this.per_page);
|
||||
},
|
||||
pages() {
|
||||
let pages = [];
|
||||
let length = this.filtered_backups.length;
|
||||
for (let i = 0; i * this.per_page < length; i++) {
|
||||
pages.push(i);
|
||||
}
|
||||
return pages;
|
||||
}
|
||||
},
|
||||
template: `
|
||||
<div>
|
||||
<div class="bar">
|
||||
<search-bar v-model="search_term" @input="setPage(0)"></search-bar>
|
||||
</div>
|
||||
<ul id="view_backups_list" class="list">
|
||||
<li v-for="backup in viewed_backups" :key="backup.id" :class="{selected: selected == backup}" @dblclick="open(backup)" @click="select(backup);">
|
||||
<span :title="backup.id">{{ backup.name }}</span>
|
||||
<div class="view_backups_info_field" :title="backup.date_long">{{ backup.date }}</div>
|
||||
<div class="view_backups_info_field" :title="backup.date_long">{{ backup.time }}</div>
|
||||
<div class="view_backups_info_field">{{ backup.size }}</div>
|
||||
</li>
|
||||
</ul>
|
||||
<ol class="pagination_numbers" v-if="pages.length > 1">
|
||||
<li v-for="number in pages" :class="{selected: page == number}" @click="setPage(number)">{{ number+1 }}</li>
|
||||
</ol>
|
||||
</div>
|
||||
`
|
||||
},
|
||||
onButton(button) {
|
||||
if (button == 1) {
|
||||
shell.openPath(backup_directory);
|
||||
}
|
||||
},
|
||||
onConfirm() {
|
||||
Blockbench.read([selected.path], {}, (files) => {
|
||||
loadModelFile(files[0]);
|
||||
})
|
||||
dialog.close();
|
||||
}
|
||||
}).show();
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
//Close
|
||||
window.onbeforeunload = function (event) {
|
||||
try {
|
||||
|
@ -1798,14 +1798,6 @@ const BARS = {
|
||||
shell.showItemInFolder(Project.export_path || Project.save_path);
|
||||
}
|
||||
})
|
||||
new Action('open_backup_folder', {
|
||||
icon: 'fa-archive',
|
||||
category: 'file',
|
||||
condition: () => isApp,
|
||||
click: function (e) {
|
||||
shell.openPath(app.getPath('userData')+osfs+'backups')
|
||||
}
|
||||
})
|
||||
new Action('reload', {
|
||||
icon: 'refresh',
|
||||
category: 'file',
|
||||
|
@ -422,7 +422,7 @@ function setupInterface() {
|
||||
Interface.status_bar.menu = new Menu([
|
||||
'project_window',
|
||||
'open_model_folder',
|
||||
'open_backup_folder',
|
||||
'view_backups',
|
||||
'save',
|
||||
'timelapse',
|
||||
'cancel_gif',
|
||||
|
@ -450,7 +450,7 @@ const MenuBar = {
|
||||
Blockbench.openLink('https://github.com/JannisX11/blockbench/issues');
|
||||
}},
|
||||
'_',
|
||||
'open_backup_folder',
|
||||
'view_backups',
|
||||
'_',
|
||||
{name: 'menu.help.developer', id: 'developer', icon: 'fas.fa-wrench', children: [
|
||||
'reload_plugins',
|
||||
|
@ -104,6 +104,22 @@ function trimFloatNumber(val, max_digits = 4) {
|
||||
if (string == -0) return 0;
|
||||
return string;
|
||||
}
|
||||
function separateThousands(number) {
|
||||
let str = number.toString();
|
||||
let length = str.indexOf('.');
|
||||
if (length == -1) length = str.length;
|
||||
if (length < 4) return str;
|
||||
|
||||
let modified;
|
||||
for (let i = length; i > 0; i -= 3) {
|
||||
if (i == length) {
|
||||
modified = str.substring(i-3);
|
||||
} else {
|
||||
modified = str.substring(Math.max(0, i-3), i) + ',' + modified;
|
||||
}
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
function getAxisLetter(number) {
|
||||
switch (number) {
|
||||
case 0: return 'x'; break;
|
||||
|
@ -603,6 +603,8 @@
|
||||
|
||||
"dialog.input.title": "Input",
|
||||
|
||||
"dialog.view_backups.open_folder": "Open Folder",
|
||||
|
||||
"dialog.sketchfab_uploader.title": "Upload Sketchfab Model",
|
||||
"dialog.sketchfab_uploader.token": "API Token",
|
||||
"dialog.sketchfab_uploader.about_token": "The token is used to connect Blockbench to your Sketchfab account. You can find it on %0",
|
||||
@ -1110,8 +1112,8 @@
|
||||
"action.new_window.desc": "Opens a new Blockbench window",
|
||||
"action.open_model_folder": "Open Model Folder",
|
||||
"action.open_model_folder.desc": "Opens the folder that the model is contained in",
|
||||
"action.open_backup_folder": "Open Backup Folder",
|
||||
"action.open_backup_folder.desc": "Opens the Blockbench backup folder",
|
||||
"action.view_backups": "View Backups",
|
||||
"action.view_backups.desc": "Browse the list of auto-saved project backups",
|
||||
"action.open_model": "Open Model",
|
||||
"action.open_model.desc": "Open a model file from your computer",
|
||||
"action.open_from_link": "Open Model from Link...",
|
||||
|
Loading…
Reference in New Issue
Block a user