Make edit sessions compatible with tabs
This commit is contained in:
parent
8652b513d3
commit
1e35ca9428
@ -429,7 +429,7 @@
|
|||||||
#tab_bar .project_tab {
|
#tab_bar .project_tab {
|
||||||
background-color: var(--color-back);
|
background-color: var(--color-back);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
width: 200px;
|
width: 240px;
|
||||||
min-width: 120px;
|
min-width: 120px;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
padding: 2px 6px;
|
padding: 2px 6px;
|
||||||
@ -511,6 +511,19 @@
|
|||||||
#new_tab_button:hover {
|
#new_tab_button:hover {
|
||||||
color: var(--color-light);
|
color: var(--color-light);
|
||||||
}
|
}
|
||||||
|
#tab_bar .project_tab > label.project_tab_session_badge {
|
||||||
|
display: flex;
|
||||||
|
flex-grow: 0;
|
||||||
|
width: auto;
|
||||||
|
color: var(--color-accent);
|
||||||
|
}
|
||||||
|
#tab_bar .project_tab > label.project_tab_session_badge i {
|
||||||
|
margin-right: 2px;
|
||||||
|
margin-left: -4px;
|
||||||
|
}
|
||||||
|
#tab_bar.invisible {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*Start Screen*/
|
/*Start Screen*/
|
||||||
|
84
index.html
84
index.html
@ -143,34 +143,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<dialog class="dialog draggable paddinged" id="edit_sessions">
|
|
||||||
<div class="dialog_handle tl">dialog.edit_session.title</div>
|
|
||||||
|
|
||||||
<div class="dialog_bar">
|
|
||||||
<label class="name_space_left tl">edit_session.username</label>
|
|
||||||
<input type="text" class="dark_bordered half" id="edit_session_username">
|
|
||||||
</div>
|
|
||||||
<div class="dialog_bar">
|
|
||||||
<label class="name_space_left tl">edit_session.token</label>
|
|
||||||
<input type="text" class="dark_bordered half f_left" id="edit_session_token">
|
|
||||||
<div id="edit_session_copy_button" class="tool" onclick="EditSession.copyToken()"><div class="tooltip tl">action.paste</div><i class="fa fa_big fa-clipboard"></i></div>
|
|
||||||
</div>
|
|
||||||
<div class="edit_session_inactive">
|
|
||||||
<p class="tl">edit_session.about</p>
|
|
||||||
</div>
|
|
||||||
<div class="edit_session_active hidden">
|
|
||||||
<p><b class="tl">edit_session.status</b>: <span class="tl" id="edit_session_status">edit_session.connected</span></p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="dialog_bar button_bar">
|
|
||||||
<button type="button" class="edit_session_inactive confirm_btn tl" onclick="EditSession.join();">edit_session.join</button>
|
|
||||||
<button type="button" class="edit_session_inactive tl" onclick="EditSession.start();">edit_session.create</button>
|
|
||||||
<button type="button" class="edit_session_active tl" onclick="EditSession.quit();">edit_session.quit</button>
|
|
||||||
<button type="button" class="cancel_btn tl" onclick="hideDialog();">dialog.cancel</button>
|
|
||||||
</div>
|
|
||||||
<div class="dialog_close_button" onclick="hideDialog();"><i class="material-icons">clear</i></div>
|
|
||||||
</dialog>
|
|
||||||
|
|
||||||
<dialog class="dialog draggable paddinged" id="toolbar_edit">
|
<dialog class="dialog draggable paddinged" id="toolbar_edit">
|
||||||
<div class="dialog_handle tl">dialog.toolbar_edit.title</div>
|
<div class="dialog_handle tl">dialog.toolbar_edit.title</div>
|
||||||
|
|
||||||
@ -592,38 +564,40 @@
|
|||||||
<button id="web_download_button" hidden><a class="tl" href="https://blockbench.net/downloads">web.download_app</a></button>
|
<button id="web_download_button" hidden><a class="tl" href="https://blockbench.net/downloads">web.download_app</a></button>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<div id="tab_bar" :class="{drag_mode: drag_target_index !== null}">
|
|
||||||
<div
|
|
||||||
class="project_tab"
|
|
||||||
v-for="(project, index) in tabs" :key="project.uuid"
|
|
||||||
:class="{
|
|
||||||
selected: project.selected,
|
|
||||||
new_tab: project.is_new_tab,
|
|
||||||
dragging: index == drag_target_index,
|
|
||||||
move_back: (drag_position_index !== null && index > drag_target_index && drag_position_index >= index),
|
|
||||||
move_forth: (drag_position_index !== null && index < drag_target_index && drag_position_index <= index)
|
|
||||||
}"
|
|
||||||
:title="project.name || project.geometry_name"
|
|
||||||
@dblclick="project.openSettings()"
|
|
||||||
@mousedown="mouseDown(project, $event)"
|
|
||||||
@mouseup="mouseUp(project, $event)"
|
|
||||||
>
|
|
||||||
<label>{{ project.name || project.geometry_name || project.format.name }}</label>
|
|
||||||
<div class="project_tab_close_button" :class="{unsaved: !project.saved}" :title="close_tab_label" @click="project.close()">
|
|
||||||
<i class="material-icons">{{ project.saved ? 'clear' : 'fiber_manual_record' }}</i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="new_tab_button" @click="openNewTab()" :title="new_tab.name">
|
|
||||||
<i class="material-icons">add</i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="page_wrapper" class="invisible start_screen">
|
<div id="page_wrapper" class="invisible start_screen">
|
||||||
|
|
||||||
<dialog id="action_selector"></dialog>
|
|
||||||
|
|
||||||
<div id="blackout"></div>
|
<div id="blackout"></div>
|
||||||
|
|
||||||
|
<div id="tab_bar" :class="{drag_mode: drag_target_index !== null}">
|
||||||
|
<div
|
||||||
|
class="project_tab"
|
||||||
|
v-for="(project, index) in tabs" :key="project.uuid"
|
||||||
|
:class="{
|
||||||
|
selected: project.selected,
|
||||||
|
new_tab: project.is_new_tab,
|
||||||
|
dragging: index == drag_target_index,
|
||||||
|
move_back: (drag_position_index !== null && index > drag_target_index && drag_position_index >= index),
|
||||||
|
move_forth: (drag_position_index !== null && index < drag_target_index && drag_position_index <= index)
|
||||||
|
}"
|
||||||
|
:title="project.name || project.geometry_name"
|
||||||
|
@dblclick="project.openSettings()"
|
||||||
|
@mousedown="mouseDown(project, $event)"
|
||||||
|
@mouseup="mouseUp(project, $event)"
|
||||||
|
>
|
||||||
|
<label class="project_tab_session_badge" v-if="project.EditSession"><i class="material-icons">group</i>{{ project.EditSession.client_count }}</label>
|
||||||
|
<label>{{ project.name || project.geometry_name || project.format.name }}</label>
|
||||||
|
<div class="project_tab_close_button" :class="{unsaved: !project.saved}" :title="close_tab_label" @click="project.close()">
|
||||||
|
<i class="material-icons">{{ project.saved ? 'clear' : 'fiber_manual_record' }}</i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="new_tab_button" @click="openNewTab()" :title="new_tab.name">
|
||||||
|
<i class="material-icons">add</i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<dialog id="action_selector"></dialog>
|
||||||
|
|
||||||
<div id="start_screen">
|
<div id="start_screen">
|
||||||
<content>
|
<content>
|
||||||
<section id="start-files">
|
<section id="start-files">
|
||||||
|
@ -433,7 +433,7 @@ function closeBlockbenchWindow() {
|
|||||||
Blockbench.addFlag('allow_closing');
|
Blockbench.addFlag('allow_closing');
|
||||||
Blockbench.dispatchEvent('before_closing')
|
Blockbench.dispatchEvent('before_closing')
|
||||||
localStorage.removeItem('backup_model')
|
localStorage.removeItem('backup_model')
|
||||||
EditSession.quit()
|
if (Project.EditSession) Project.EditSession.quit()
|
||||||
return currentwindow.close();
|
return currentwindow.close();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,60 +1,70 @@
|
|||||||
const EditSession = {
|
class EditSession {
|
||||||
active: false,
|
constructor() {
|
||||||
hosting: false,
|
this.active = false;
|
||||||
BBKey: '1h3sq3hoj6vfkh',
|
this.hosting = false;
|
||||||
ip: 'blckbn.ch',
|
this.clients = {};
|
||||||
clients: {},
|
this.client_count = 1;
|
||||||
placeholder_names: ['R2D2', 'Tin Man', 'C3PO', 'WALL-E', 'EVE', 'BB-8', 'B1 Battle Droid', 'ASIMO', 'Atlas'],
|
|
||||||
start() {
|
|
||||||
if (EditSession.active) return;
|
|
||||||
|
|
||||||
var peer = EditSession.peer = new Peer({
|
this.data_queue = [];
|
||||||
|
|
||||||
|
this.chat_history = [];
|
||||||
|
|
||||||
|
this.Project = Project || null;
|
||||||
|
Interface.Panels.chat.inside_vue.chat_history = this.chat_history;
|
||||||
|
if (Project) Project.EditSession = this;
|
||||||
|
}
|
||||||
|
updateClientCount() {
|
||||||
|
this.client_count = Math.clamp(Object.keys(this.clients).length, 1, 999);
|
||||||
|
}
|
||||||
|
start(username) {
|
||||||
|
if (this.active) return;
|
||||||
|
|
||||||
|
var peer = this.peer = new Peer({
|
||||||
key: 'edit_session',
|
key: 'edit_session',
|
||||||
host: EditSession.ip,
|
host: EditSession.defaults.ip,
|
||||||
port: 9000,
|
port: 9000,
|
||||||
path: '/sessions',
|
path: '/sessions',
|
||||||
secure: true
|
secure: true
|
||||||
});
|
});
|
||||||
EditSession.username = $('#edit_session_username').val() || EditSession.placeholder_names.random();
|
this.username = username || EditSession.defaults.placeholder_names.random();
|
||||||
settings.username.value = EditSession.username;
|
settings.username.value = this.username;
|
||||||
|
|
||||||
peer.on('open', (token) => {
|
peer.on('open', (token) => {
|
||||||
EditSession.hosting = true;
|
this.hosting = true;
|
||||||
Prop.session = true;
|
this.setState(true);
|
||||||
EditSession.setState(true);
|
|
||||||
|
|
||||||
EditSession.self = new EditSession.Client({
|
this.self = new EditSession.Client(this, {
|
||||||
id: EditSession.peer.id,
|
id: this.peer.id,
|
||||||
name: EditSession.username,
|
name: this.username,
|
||||||
hosting: true
|
hosting: true
|
||||||
})
|
})
|
||||||
|
|
||||||
$('#edit_session_token').val(token)
|
$('#edit_session_token').val(token)
|
||||||
EditSession.token = token;
|
this.token = token;
|
||||||
Clipbench.setText(token)
|
Clipbench.setText(token)
|
||||||
Blockbench.dispatchEvent('create_session', {peer, token})
|
Blockbench.dispatchEvent('create_session', {peer, token})
|
||||||
})
|
})
|
||||||
peer.on('connection', (conn) => {
|
peer.on('connection', (conn) => {
|
||||||
conn.on('open', function() {
|
conn.on('open', () => {
|
||||||
|
|
||||||
var client = new EditSession.Client({
|
var client = new EditSession.Client(this, {
|
||||||
id: conn.peer,
|
id: conn.peer,
|
||||||
conn: conn,
|
conn: conn,
|
||||||
name: conn.metadata.username,
|
name: conn.metadata.username,
|
||||||
hosting: false
|
hosting: false
|
||||||
})
|
})
|
||||||
Chat.processMessage({text: tl('edit_session.joined', [client.name]), color: 'green'})
|
this.processChatMessage({text: tl('edit_session.joined', [client.name]), color: 'green'})
|
||||||
Blockbench.showQuickMessage(tl('edit_session.joined', [client.name]))
|
Blockbench.showQuickMessage(tl('edit_session.joined', [client.name]))
|
||||||
//New Login
|
//New Login
|
||||||
client.send({
|
client.send({
|
||||||
type: 'chat_message',
|
type: 'chat_message',
|
||||||
data: {text: tl('edit_session.welcome', [EditSession.username]), color: 'yellow'}
|
data: {text: tl('edit_session.welcome', [this.username]), color: 'yellow'}
|
||||||
})
|
})
|
||||||
var model = Codecs.project.compile({uuids: true, bitmaps: true, backup: true, history: true})
|
var model = Codecs.project.compile({uuids: true, bitmaps: true, backup: true, history: true})
|
||||||
client.send({
|
client.send({
|
||||||
type: 'init_model',
|
type: 'init_model',
|
||||||
fromHost: EditSession.hosting,
|
fromHost: this.hosting,
|
||||||
sender: EditSession.peer.id,
|
sender: this.peer.id,
|
||||||
data: model
|
data: model
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -62,25 +72,23 @@ const EditSession = {
|
|||||||
peer.on('error', error => {
|
peer.on('error', error => {
|
||||||
console.error('Error in edit session:', error)
|
console.error('Error in edit session:', error)
|
||||||
})
|
})
|
||||||
},
|
}
|
||||||
join() {
|
join(username, token) {
|
||||||
if (EditSession.active) return;
|
if (this.active) return;
|
||||||
|
|
||||||
var token = $('#edit_session_token').val()
|
this.hosting = false;
|
||||||
|
this.peer = new Peer({
|
||||||
EditSession.hosting = false;
|
|
||||||
EditSession.peer = new Peer({
|
|
||||||
key: 'edit_session',
|
key: 'edit_session',
|
||||||
host: EditSession.ip,
|
host: EditSession.defaults.ip,
|
||||||
port: 9000,
|
port: 9000,
|
||||||
path: '/sessions',
|
path: '/sessions',
|
||||||
secure: true
|
secure: true
|
||||||
});
|
});
|
||||||
EditSession.peer.on('open', function() {
|
this.peer.on('open', () => {
|
||||||
|
|
||||||
EditSession.username = $('#edit_session_username').val() || EditSession.placeholder_names.random();
|
this.username = username || EditSession.defaults.placeholder_names.random();
|
||||||
settings.username.value = EditSession.username;
|
settings.username.value = this.username;
|
||||||
if (!token || !EditSession._matchToken(token)) {
|
if (!token || !EditSession.matchToken(token)) {
|
||||||
Blockbench.showMessageBox({
|
Blockbench.showMessageBox({
|
||||||
translateKey: 'invalid_session',
|
translateKey: 'invalid_session',
|
||||||
icon: 'cloud_off',
|
icon: 'cloud_off',
|
||||||
@ -89,8 +97,8 @@ const EditSession = {
|
|||||||
})
|
})
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
EditSession.token = token;
|
this.token = token;
|
||||||
var conn = EditSession.peer.connect(token, {metadata: {username: EditSession.username}});
|
var conn = this.peer.connect(token, {metadata: {username: this.username}});
|
||||||
|
|
||||||
conn.on('error', (err) => {
|
conn.on('error', (err) => {
|
||||||
console.error('peer join error', err)
|
console.error('peer join error', err)
|
||||||
@ -98,117 +106,91 @@ const EditSession = {
|
|||||||
translateKey: 'invalid_session',
|
translateKey: 'invalid_session',
|
||||||
icon: 'cloud_off',
|
icon: 'cloud_off',
|
||||||
})
|
})
|
||||||
EditSession.quit()
|
this.quit()
|
||||||
})
|
})
|
||||||
conn.on('open', () => {
|
conn.on('open', () => {
|
||||||
hideDialog()
|
hideDialog()
|
||||||
EditSession.host = conn;
|
this.host = conn;
|
||||||
EditSession.setState(true);
|
this.setState(true);
|
||||||
EditSession.initConnection(conn)
|
this.initConnection(conn)
|
||||||
Blockbench.dispatchEvent('join_session', {conn})
|
Blockbench.dispatchEvent('join_session', {conn})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
EditSession.peer.on('error', error => {
|
this.peer.on('error', error => {
|
||||||
console.error('Error in edit session:', error)
|
console.error('Error in edit session:', error)
|
||||||
})
|
})
|
||||||
},
|
}
|
||||||
quit() {
|
quit() {
|
||||||
if (!EditSession.active) return;
|
if (!this.active) return;
|
||||||
|
|
||||||
Blockbench.dispatchEvent('quit_session', {})
|
Blockbench.dispatchEvent('quit_session', {})
|
||||||
if (EditSession.hosting) {
|
if (this.hosting) {
|
||||||
EditSession.sendAll('command', 'quit_session')
|
this.sendAll('command', 'quit_session')
|
||||||
} else {
|
} else {
|
||||||
EditSession.host.close()
|
this.host.close()
|
||||||
}
|
}
|
||||||
setTimeout(function() {
|
ModelProject.all.forEach(project => {
|
||||||
EditSession.setState(false)
|
if (project.EditSession == this) {
|
||||||
Chat.history.purge()
|
delete project.EditSession;
|
||||||
EditSession.peer.destroy()
|
}
|
||||||
Prop.session = false;
|
})
|
||||||
Prop.connections = 0;
|
setTimeout(() => {
|
||||||
|
this.setState(false)
|
||||||
|
this.chat_history.purge()
|
||||||
|
this.peer.destroy()
|
||||||
Blockbench.showQuickMessage('edit_session.quit_session', 1500)
|
Blockbench.showQuickMessage('edit_session.quit_session', 1500)
|
||||||
}, 400)
|
}, 400)
|
||||||
},
|
}
|
||||||
setState(active) {
|
setState(active) {
|
||||||
EditSession.active = active;
|
this.active = active;
|
||||||
$('#edit_session_username, #edit_session_token').attr('readonly', active)
|
if (!active) {
|
||||||
if (active) {
|
this.hosting = false;
|
||||||
$('.edit_session_inactive').hide()
|
|
||||||
$('.edit_session_active').show()
|
|
||||||
$('#edit_session_status').text(EditSession.hosting ? tl('edit_session.hosting') : tl('edit_session.connected'))
|
|
||||||
$('#edit_session_copy_button .tooltip').text(tl('action.copy'))
|
|
||||||
} else {
|
|
||||||
EditSession.hosting = false;
|
|
||||||
$('.edit_session_active').hide()
|
|
||||||
$('.edit_session_inactive').show()
|
|
||||||
$('#edit_session_copy_button .tooltip').text(tl('action.paste'))
|
|
||||||
$('#edit_session_token').val('')
|
|
||||||
}
|
}
|
||||||
updateInterface()
|
updateInterface()
|
||||||
},
|
}
|
||||||
dialog() {
|
|
||||||
showDialog('edit_sessions');
|
|
||||||
if (!EditSession.active) {
|
|
||||||
var username = settings.username.value;
|
|
||||||
if (isApp) {
|
|
||||||
var token = clipboard.readText()
|
|
||||||
if (EditSession._matchToken(token) && !$('#edit_session_token').val()) {
|
|
||||||
$('#edit_session_token').val(token)
|
|
||||||
}
|
|
||||||
if (!username) {
|
|
||||||
username = process.env.USERNAME
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!username) username = EditSession.placeholder_names.random()
|
|
||||||
if (username) {
|
|
||||||
$('#edit_session_username').val(username)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
copyToken() {
|
copyToken() {
|
||||||
var input = $('#edit_session_token')
|
var input = $('#edit_session_token')
|
||||||
if (EditSession.active) {
|
if (this.active) {
|
||||||
input.focus()
|
input.focus()
|
||||||
document.execCommand('selectAll')
|
document.execCommand('selectAll')
|
||||||
document.execCommand('copy')
|
document.execCommand('copy')
|
||||||
} else {
|
} else {
|
||||||
if (isApp) {
|
if (isApp) {
|
||||||
var token = clipboard.readText()
|
var token = clipboard.readText()
|
||||||
if (EditSession._matchToken(token)) {
|
if (EditSession.matchToken(token)) {
|
||||||
$('#edit_session_token').val(token)
|
$('#edit_session_token').val(token)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
navigator.clipboard.readText().then((token) => {
|
navigator.clipboard.readText().then((token) => {
|
||||||
if (EditSession._matchToken(token)) {
|
if (EditSession.matchToken(token)) {
|
||||||
$('#edit_session_token').val(token)
|
$('#edit_session_token').val(token)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
initNewModel(force) {
|
initNewModel(force) {
|
||||||
if (EditSession.active && EditSession.hosting) {
|
if (this.active && this.hosting) {
|
||||||
var model = Codecs.project.compile({uuids: true, bitmaps: true, backup: true, flag: force ? 'force' : null})
|
var model = Codecs.project.compile({uuids: true, bitmaps: true, backup: true, flag: force ? 'force' : null})
|
||||||
if (force) {
|
if (force) {
|
||||||
model.flag = 'force'
|
model.flag = 'force'
|
||||||
}
|
}
|
||||||
EditSession.sendAll('init_model', model)
|
this.sendAll('init_model', model)
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
initConnection(conn) {
|
initConnection(conn) {
|
||||||
conn.on('data', EditSession.receiveData)
|
conn.on('data', (...args) => this.receiveData(...args))
|
||||||
},
|
}
|
||||||
sendAll(type, data) {
|
sendAll(type, data) {
|
||||||
var tag = {type, data}
|
var tag = {type, data}
|
||||||
Blockbench.dispatchEvent('send_session_data', tag)
|
Blockbench.dispatchEvent('send_session_data', tag)
|
||||||
for (var key in EditSession.peer.connections) {
|
for (var key in this.peer.connections) {
|
||||||
var conns = EditSession.peer.connections[key];
|
var conns = this.peer.connections[key];
|
||||||
conns.forEach(conn => {
|
conns.forEach(conn => {
|
||||||
conn.send({
|
conn.send({
|
||||||
type: tag.type,
|
type: tag.type,
|
||||||
fromHost: EditSession.hosting,
|
fromHost: this.hosting,
|
||||||
sender: EditSession.peer.id,
|
sender: this.peer.id,
|
||||||
data: tag.data
|
data: tag.data
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
@ -216,7 +198,7 @@ const EditSession = {
|
|||||||
if (Blockbench.hasFlag('log_session')) {
|
if (Blockbench.hasFlag('log_session')) {
|
||||||
console.log('Sent Data:', type, data)
|
console.log('Sent Data:', type, data)
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
sendEdit(entry) {
|
sendEdit(entry) {
|
||||||
var new_entry = {
|
var new_entry = {
|
||||||
before: omitKeys(entry.before, ['aspects']),
|
before: omitKeys(entry.before, ['aspects']),
|
||||||
@ -224,17 +206,17 @@ const EditSession = {
|
|||||||
save_history: entry.save_history,
|
save_history: entry.save_history,
|
||||||
action: entry.action
|
action: entry.action
|
||||||
}
|
}
|
||||||
EditSession.sendAll('edit', JSON.stringify(new_entry))
|
this.sendAll('edit', JSON.stringify(new_entry))
|
||||||
},
|
}
|
||||||
receiveData(tag) {
|
receiveData(tag) {
|
||||||
if (Blockbench.hasFlag('log_session')) {
|
if (Blockbench.hasFlag('log_session')) {
|
||||||
console.log('Received Data:', tag)
|
console.log('Received Data:', tag)
|
||||||
}
|
}
|
||||||
if (EditSession.hosting && !tag.hostOnly && Object.keys(EditSession.peer.connections).length > 1) {
|
if (this.hosting && !tag.hostOnly && Object.keys(this.peer.connections).length > 1) {
|
||||||
//Redistribute
|
//Redistribute
|
||||||
for (var id in EditSession.peer.connections) {
|
for (var id in this.peer.connections) {
|
||||||
if (id !== tag.sender) {
|
if (id !== tag.sender) {
|
||||||
EditSession.peer.connections[id][0].send(tag);
|
this.peer.connections[id][0].send(tag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -247,21 +229,41 @@ const EditSession = {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Blockbench.dispatchEvent('receive_session_data', tag)
|
Blockbench.dispatchEvent('receive_session_data', tag);
|
||||||
|
|
||||||
|
if (tag.type === 'chat_input' && this.hosting) {
|
||||||
|
this.processChatMessage(tag.data);
|
||||||
|
|
||||||
|
} else if (tag.type === 'chat_message') {
|
||||||
|
this.addChatMessage(tag.data);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (Project.EditSession == this || (!this.Project)) {
|
||||||
|
this.processData(tag);
|
||||||
|
} else {
|
||||||
|
this.data_queue.push(tag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
processData(tag) {
|
||||||
|
let {data} = tag;
|
||||||
if (tag.type === 'edit') {
|
if (tag.type === 'edit') {
|
||||||
Undo.remoteEdit(data)
|
Undo.remoteEdit(data);
|
||||||
|
|
||||||
} else if (tag.type === 'init_model') {
|
} else if (tag.type === 'init_model') {
|
||||||
|
|
||||||
newProject(data.meta.type||'free', data.flag === 'force');
|
newProject(data.meta.type||'free', data.flag === 'force');
|
||||||
Codecs.project.parse(data);
|
Codecs.project.parse(data);
|
||||||
|
this.Project = Project;
|
||||||
|
this.Project.EditSession = this;
|
||||||
|
|
||||||
} else if (tag.type === 'command') {
|
} else if (tag.type === 'command') {
|
||||||
switch (data) {
|
switch (data) {
|
||||||
case 'undo': Undo.undo(true); break;
|
case 'undo': Undo.undo(true); break;
|
||||||
case 'redo': Undo.redo(true); break;
|
case 'redo': Undo.redo(true); break;
|
||||||
case 'quit_session': EditSession.quit(); break;
|
case 'quit_session': this.quit(); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (tag.type === 'change_project_meta') {
|
} else if (tag.type === 'change_project_meta') {
|
||||||
@ -269,33 +271,87 @@ const EditSession = {
|
|||||||
Project[key] = data[key];
|
Project[key] = data[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (tag.type === 'chat_input' && EditSession.hosting) {
|
|
||||||
Chat.processMessage(tag.data)
|
|
||||||
|
|
||||||
} else if (tag.type === 'chat_message') {
|
|
||||||
Chat.addMessage(tag.data)
|
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
updateClientCount() {
|
catchUp() {
|
||||||
Prop.connections = Object.keys(EditSession.clients).length-1
|
while (this.data_queue.length) {
|
||||||
},
|
let tag = this.data_queue.shift();
|
||||||
_matchToken(token) {
|
try {
|
||||||
return !!(token.length === 16 && token.match(/[a-z0-9]{16}/))
|
this.processData(tag);
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sendChat(text) {
|
||||||
|
if (typeof text !== 'string') {
|
||||||
|
text = $('input#chat_input').val()
|
||||||
|
$('input#chat_input').val('')
|
||||||
|
}
|
||||||
|
if (!text) return;
|
||||||
|
this.processChatMessage({
|
||||||
|
author: this.username,
|
||||||
|
text: text,
|
||||||
|
sender: this.peer.id
|
||||||
|
})
|
||||||
|
}
|
||||||
|
addChatMessage(message) {
|
||||||
|
if (!(message instanceof EditSession.ChatMessage)) {
|
||||||
|
message = new EditSession.ChatMessage(this, message)
|
||||||
|
}
|
||||||
|
if (!message.text) return;
|
||||||
|
|
||||||
|
this.chat_history.push(message)
|
||||||
|
Vue.nextTick(() => {
|
||||||
|
$('#chat_history').scrollTop(10000)
|
||||||
|
})
|
||||||
|
if (!document.hasFocus() && !message.self) {
|
||||||
|
Blockbench.notification(message.author ? message.author+':' : 'Chat', message.text)
|
||||||
|
}
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
processChatMessage(data) {
|
||||||
|
if (!this.hosting) {
|
||||||
|
this.host.send({
|
||||||
|
type: 'chat_input',
|
||||||
|
data,
|
||||||
|
sender: this.peer.id
|
||||||
|
})
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//Host Only
|
||||||
|
Blockbench.dispatchEvent('process_chat_message', data)
|
||||||
|
|
||||||
|
this.sendAll('chat_message', data)
|
||||||
|
this.addChatMessage(data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EditSession.matchToken = function(token) {
|
||||||
|
return !!(token.length === 16 && token.match(/[a-z0-9]{16}/))
|
||||||
|
}
|
||||||
|
|
||||||
|
EditSession.defaults = {
|
||||||
|
max_chat_length: 512,
|
||||||
|
ip: 'blckbn.ch',
|
||||||
|
placeholder_names: ['R2D2', 'Tin Man', 'C3PO', 'WALL-E', 'EVE', 'BB-8', 'B1 Battle Droid', 'ASIMO', 'Atlas'],
|
||||||
|
}
|
||||||
|
|
||||||
EditSession.Client = class {
|
EditSession.Client = class {
|
||||||
constructor(data) {
|
constructor(session, data) {
|
||||||
var scope = this;
|
var scope = this;
|
||||||
this.id = data.id;
|
this.id = data.id;
|
||||||
this.hosting = data.hosting;
|
this.hosting = data.hosting;
|
||||||
this.conn = data.conn;
|
this.conn = data.conn;
|
||||||
this.name = data.name;
|
this.name = data.name;
|
||||||
|
this.session = session;
|
||||||
|
|
||||||
EditSession.clients[this.id] = this;
|
this.session.clients[this.id] = this;
|
||||||
EditSession.updateClientCount()
|
this.session.updateClientCount()
|
||||||
|
|
||||||
if (this.conn) {
|
if (this.conn) {
|
||||||
EditSession.initConnection(this.conn)
|
this.session.initConnection(this.conn)
|
||||||
this.conn.on('close', () => {
|
this.conn.on('close', () => {
|
||||||
scope.disconnect()
|
scope.disconnect()
|
||||||
})
|
})
|
||||||
@ -311,70 +367,25 @@ EditSession.Client = class {
|
|||||||
this.conn.send(tag)
|
this.conn.send(tag)
|
||||||
}
|
}
|
||||||
disconnect(e) {
|
disconnect(e) {
|
||||||
if (!EditSession.clients[this.id]) return;
|
if (!this.session.clients[this.id]) return;
|
||||||
Blockbench.dispatchEvent('user_leaves_session', this)
|
Blockbench.dispatchEvent('user_leaves_session', this)
|
||||||
delete EditSession.peer.connections[this.conn.peer];
|
delete this.session.peer.connections[this.conn.peer];
|
||||||
delete EditSession.clients[this.id];
|
delete this.session.clients[this.id];
|
||||||
EditSession.updateClientCount();
|
this.session.updateClientCount();
|
||||||
|
|
||||||
Chat.processMessage({text: tl('edit_session.left', [this.name]), color: 'red'})
|
this.processChatMessage({text: tl('edit_session.left', [this.name]), color: 'red'})
|
||||||
Blockbench.showQuickMessage(tl('edit_session.left', [this.name]))
|
Blockbench.showQuickMessage(tl('edit_session.left', [this.name]))
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
const Chat = {
|
|
||||||
history: [],
|
|
||||||
maxlength: 512,
|
|
||||||
send(text) {
|
|
||||||
if (typeof text !== 'string') {
|
|
||||||
text = $('input#chat_input').val()
|
|
||||||
$('input#chat_input').val('')
|
|
||||||
}
|
|
||||||
if (!text) return;
|
|
||||||
Chat.processMessage({
|
|
||||||
author: EditSession.username,
|
|
||||||
text: text,
|
|
||||||
sender: EditSession.peer.id
|
|
||||||
})
|
|
||||||
},
|
|
||||||
addMessage(message) {
|
|
||||||
if (!(message instanceof Chat.Message)) {
|
|
||||||
message = new Chat.Message(message)
|
|
||||||
}
|
|
||||||
if (!message.text) return;
|
|
||||||
|
|
||||||
Chat.history.push(message)
|
|
||||||
Vue.nextTick(() => {
|
|
||||||
$('#chat_history').scrollTop(10000)
|
|
||||||
})
|
|
||||||
if (!document.hasFocus() && !message.self) {
|
|
||||||
Blockbench.notification(message.author ? message.author+':' : 'Chat', message.text)
|
|
||||||
}
|
|
||||||
return message;
|
|
||||||
},
|
|
||||||
processMessage(data) {
|
|
||||||
if (!EditSession.hosting) {
|
|
||||||
EditSession.host.send({
|
|
||||||
type: 'chat_input',
|
|
||||||
data,
|
|
||||||
sender: EditSession.peer.id
|
|
||||||
})
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
//Host Only
|
|
||||||
Blockbench.dispatchEvent('process_chat_message', data)
|
|
||||||
|
|
||||||
EditSession.sendAll('chat_message', data)
|
|
||||||
Chat.addMessage(data)
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
Chat.Message = class {
|
|
||||||
constructor(data) {
|
EditSession.ChatMessage = class {
|
||||||
|
constructor(session, data) {
|
||||||
|
this.session = session;
|
||||||
this.author = data.author||'';
|
this.author = data.author||'';
|
||||||
this.author = this.author.substr(0, 64)
|
this.author = this.author.substr(0, 64)
|
||||||
this.sender = data.sender
|
this.sender = data.sender
|
||||||
this.self = data.sender == EditSession.peer.id;
|
this.self = data.sender == this.session.peer.id;
|
||||||
this.text = data.text.substr(0, Chat.maxlength)||'';
|
this.text = data.text.substr(0, EditSession.defaults.max_chat_length)||'';
|
||||||
|
|
||||||
this.html = this.text.replace(/</g, '<').replace(/>/g, '>');
|
this.html = this.text.replace(/</g, '<').replace(/>/g, '>');
|
||||||
this.html = this.html.replace(/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)/g, (text, i) => {
|
this.html = this.html.replace(/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)/g, (text, i) => {
|
||||||
@ -402,8 +413,8 @@ Chat.Message = class {
|
|||||||
}
|
}
|
||||||
showAuthor() {
|
showAuthor() {
|
||||||
if (!this.author) return false;
|
if (!this.author) return false;
|
||||||
var this_i = Chat.history.indexOf(this);
|
var this_i = this.session.chat_history.indexOf(this);
|
||||||
var prev = Chat.history[this_i-1];
|
var prev = this.session.chat_history[this_i-1];
|
||||||
return (!prev) || (prev.author !== this.author);
|
return (!prev) || (prev.author !== this.author);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -412,33 +423,100 @@ BARS.defineActions(function() {
|
|||||||
new Action('edit_session', {
|
new Action('edit_session', {
|
||||||
icon: 'people',
|
icon: 'people',
|
||||||
category: 'blockbench',
|
category: 'blockbench',
|
||||||
click: EditSession.dialog
|
click: () => {
|
||||||
|
|
||||||
|
let session = Project && Project.EditSession;
|
||||||
|
var username, token;
|
||||||
|
|
||||||
|
if (session) {
|
||||||
|
username = session.username;
|
||||||
|
token = session.token;
|
||||||
|
} else {
|
||||||
|
username = settings.username.value;
|
||||||
|
if (!username && isApp) {
|
||||||
|
username = process.env.USERNAME
|
||||||
|
}
|
||||||
|
token = EditSession.token;
|
||||||
|
if (!token && isApp) {
|
||||||
|
let clipboard_token = clipboard.readText()
|
||||||
|
if (EditSession.matchToken(clipboard_token) && !$('#edit_session_token').val()) {
|
||||||
|
token = clipboard_token;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
new Dialog({
|
||||||
|
id: 'edit_session',
|
||||||
|
title: 'dialog.edit_session.title',
|
||||||
|
form: {
|
||||||
|
username: {type: 'text', label: 'edit_session.username', value: username},
|
||||||
|
token: {type: 'text', label: 'edit_session.token', value: token, readonly: !!session},
|
||||||
|
about: {type: 'info', text: 'edit_session.about', condition: !session},
|
||||||
|
status: {type: 'info', text: `**${tl('edit_session.status')}**: ${(session && session.hosting) ? tl('edit_session.hosting') : tl('edit_session.connected')}`, condition: !!session},
|
||||||
|
},
|
||||||
|
buttons: session
|
||||||
|
? ['edit_session.quit', 'dialog.close']
|
||||||
|
: ['edit_session.join', 'edit_session.create', 'dialog.close'],
|
||||||
|
onButton(button) {
|
||||||
|
let result = this.getFormResult();
|
||||||
|
if (session && button == 0) {
|
||||||
|
session.quit();
|
||||||
|
|
||||||
|
} else if (!session && button != 2) {
|
||||||
|
if (button == 0) {
|
||||||
|
// Join
|
||||||
|
session = new EditSession();
|
||||||
|
session.join(result.username, result.token);
|
||||||
|
} else {
|
||||||
|
// Create
|
||||||
|
if (!Project) {
|
||||||
|
Formats.free.new();
|
||||||
|
}
|
||||||
|
session = new EditSession();
|
||||||
|
session.start(result.username);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).show();
|
||||||
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
EditSession.initNewModel = function() {}
|
||||||
|
|
||||||
Interface.definePanels(function() {
|
Interface.definePanels(function() {
|
||||||
|
|
||||||
Interface.Panels.chat = new Panel({
|
Interface.Panels.chat = new Panel({
|
||||||
id: 'chat',
|
id: 'chat',
|
||||||
icon: 'chat',
|
icon: 'chat',
|
||||||
condition: {method() {return EditSession.active}},
|
condition: {method() {return Project.EditSession && Project.EditSession.active}},
|
||||||
toolbars: {},
|
toolbars: {},
|
||||||
onResize: t => {
|
onResize: t => {
|
||||||
},
|
},
|
||||||
component: {
|
component: {
|
||||||
data() {return Chat},
|
data() {return {
|
||||||
|
chat_history: [],
|
||||||
|
chat_input: ''
|
||||||
|
}},
|
||||||
|
methods: {
|
||||||
|
sendMessage() {
|
||||||
|
if (Project && Project.EditSession) {
|
||||||
|
Project.EditSession.sendChat(this.chat_input);
|
||||||
|
this.chat_input = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
template: `
|
template: `
|
||||||
<div>
|
<div>
|
||||||
<ul id="chat_history">
|
<ul id="chat_history">
|
||||||
<li v-for="msg in history">
|
<li v-for="msg in chat_history">
|
||||||
<b v-if="msg.showAuthor()" v-bind:class="{self: msg.self}">{{ msg.author }}:</b>
|
<b v-if="msg.showAuthor()" v-bind:class="{self: msg.self}">{{ msg.author }}:</b>
|
||||||
<span class="text" v-bind:style="{color: msg.hex || 'inherit'}" v-html="msg.html"></span>
|
<span class="text" v-bind:style="{color: msg.hex || 'inherit'}" v-html="msg.html"></span>
|
||||||
<span class="timestamp">{{ msg.timestamp }}</span>
|
<span class="timestamp">{{ msg.timestamp }}</span>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<div id="chat_bar">
|
<div id="chat_bar">
|
||||||
<input type="text" id="chat_input" class="dark_bordered f_left" maxlength="512">
|
<input type="text" id="chat_input" class="dark_bordered f_left" maxlength="512" v-model="chat_input">
|
||||||
<i class="material-icons" onclick="Chat.send()">send</i>
|
<i class="material-icons" @click="sendMessage()">send</i>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
|
@ -15,7 +15,7 @@ class ResizeLine {
|
|||||||
this.node = jq.get(0)
|
this.node = jq.get(0)
|
||||||
jq.draggable({
|
jq.draggable({
|
||||||
axis: this.horizontal ? 'y' : 'x',
|
axis: this.horizontal ? 'y' : 'x',
|
||||||
containment: '#page_wrapper',
|
containment: '#work_screen',
|
||||||
revert: true,
|
revert: true,
|
||||||
revertDuration: 0,
|
revertDuration: 0,
|
||||||
start: function(e, u) {
|
start: function(e, u) {
|
||||||
@ -108,7 +108,7 @@ const Interface = {
|
|||||||
},
|
},
|
||||||
position: function(line) {
|
position: function(line) {
|
||||||
line.setPosition({
|
line.setPosition({
|
||||||
top: document.getElementById('page_wrapper').offsetTop,
|
top: document.getElementById('work_screen').offsetTop,
|
||||||
bottom: 0,
|
bottom: 0,
|
||||||
left: Interface.data.left_bar_width+2
|
left: Interface.data.left_bar_width+2
|
||||||
})
|
})
|
||||||
@ -139,7 +139,7 @@ const Interface = {
|
|||||||
},
|
},
|
||||||
position: function(line) {
|
position: function(line) {
|
||||||
line.setPosition({
|
line.setPosition({
|
||||||
top: document.getElementById('page_wrapper').offsetTop+30,
|
top: document.getElementById('work_screen').offsetTop+30,
|
||||||
bottom: 0,
|
bottom: 0,
|
||||||
right: Interface.data.right_bar_width-2
|
right: Interface.data.right_bar_width-2
|
||||||
})
|
})
|
||||||
@ -238,7 +238,7 @@ function setupInterface() {
|
|||||||
|
|
||||||
for (var key in Interface.Resizers) {
|
for (var key in Interface.Resizers) {
|
||||||
var resizer = Interface.Resizers[key]
|
var resizer = Interface.Resizers[key]
|
||||||
$('#page_wrapper').append(resizer.node)
|
$('#work_screen').append(resizer.node)
|
||||||
}
|
}
|
||||||
//$(document).contextmenu()
|
//$(document).contextmenu()
|
||||||
|
|
||||||
@ -826,9 +826,6 @@ onVueSetup(function() {
|
|||||||
<div class="f_right">
|
<div class="f_right">
|
||||||
{{ Prop.fps }} FPS
|
{{ Prop.fps }} FPS
|
||||||
</div>
|
</div>
|
||||||
<div class="f_right" v-if="Prop.session">
|
|
||||||
{{ Prop.connections }} Clients
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="sidebar_toggle_button" v-if="!isMobile" @click="toggleSidebar('right')" :title="tl('status_bar.toggle_sidebar')">
|
<div class="sidebar_toggle_button" v-if="!isMobile" @click="toggleSidebar('right')" :title="tl('status_bar.toggle_sidebar')">
|
||||||
<i class="material-icons">{{Prop.show_right_bar ? 'chevron_right' : 'chevron_left'}}</i>
|
<i class="material-icons">{{Prop.show_right_bar ? 'chevron_right' : 'chevron_left'}}</i>
|
||||||
|
@ -567,9 +567,9 @@ addEventListeners(document, 'keydown mousedown', function(e) {
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ($('input#chat_input:focus').length && EditSession.active) {
|
if ($('input#chat_input:focus').length && Project.EditSession) {
|
||||||
if (Keybinds.extra.confirm.keybind.isTriggered(e)) {
|
if (Keybinds.extra.confirm.keybind.isTriggered(e)) {
|
||||||
Chat.send();
|
Interface.Panels.chat.inside_vue.sendMessage();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -478,7 +478,6 @@ const MenuBar = {
|
|||||||
'project_window',
|
'project_window',
|
||||||
'_',
|
'_',
|
||||||
{name: 'menu.file.new', id: 'new', icon: 'insert_drive_file',
|
{name: 'menu.file.new', id: 'new', icon: 'insert_drive_file',
|
||||||
condition: () => (!EditSession.active || EditSession.hosting),
|
|
||||||
children: function() {
|
children: function() {
|
||||||
var arr = [];
|
var arr = [];
|
||||||
for (var key in Formats) {
|
for (var key in Formats) {
|
||||||
@ -499,7 +498,7 @@ const MenuBar = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{name: 'menu.file.recent', id: 'recent', icon: 'history',
|
{name: 'menu.file.recent', id: 'recent', icon: 'history',
|
||||||
condition: function() {return isApp && recent_projects.length && (!EditSession.active || EditSession.hosting)},
|
condition: function() {return isApp && recent_projects.length},
|
||||||
children: function() {
|
children: function() {
|
||||||
var arr = []
|
var arr = []
|
||||||
let redact = settings.streamer_mode.value;
|
let redact = settings.streamer_mode.value;
|
||||||
|
@ -211,6 +211,4 @@ function loadModelFile(file) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EditSession.initNewModel()
|
|
||||||
}
|
}
|
||||||
|
@ -195,7 +195,6 @@ class ModelFormat {
|
|||||||
Canvas.updateAllBones()
|
Canvas.updateAllBones()
|
||||||
Canvas.updateAllFaces()
|
Canvas.updateAllFaces()
|
||||||
updateSelection()
|
updateSelection()
|
||||||
EditSession.initNewModel()
|
|
||||||
}
|
}
|
||||||
delete() {
|
delete() {
|
||||||
delete Formats[this.id];
|
delete Formats[this.id];
|
||||||
|
@ -511,7 +511,6 @@ function calculateVisibleBox() {
|
|||||||
Project.BedrockEntityManager.initEntity()
|
Project.BedrockEntityManager.initEntity()
|
||||||
}
|
}
|
||||||
updateSelection()
|
updateSelection()
|
||||||
EditSession.initNewModel()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compile
|
// Compile
|
||||||
|
@ -122,7 +122,6 @@ function parseGeometry(data) {
|
|||||||
Project.BedrockEntityManager.initEntity()
|
Project.BedrockEntityManager.initEntity()
|
||||||
}
|
}
|
||||||
updateSelection()
|
updateSelection()
|
||||||
EditSession.initNewModel()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -149,7 +149,6 @@ const codec = new Codec('skin_model', {
|
|||||||
Canvas.updateVisibility()
|
Canvas.updateVisibility()
|
||||||
setProjectTitle()
|
setProjectTitle()
|
||||||
updateSelection()
|
updateSelection()
|
||||||
EditSession.initNewModel()
|
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
codec.export = null;
|
codec.export = null;
|
||||||
|
@ -447,7 +447,7 @@ BARS.defineActions(function() {
|
|||||||
icon: 'assessment',
|
icon: 'assessment',
|
||||||
category: 'file',
|
category: 'file',
|
||||||
keybind: new Keybind({key: 'o', ctrl: true}),
|
keybind: new Keybind({key: 'o', ctrl: true}),
|
||||||
condition: () => (!EditSession.active || EditSession.hosting),
|
condition: () => (!Project.EditSession || Project.EditSession.hosting),
|
||||||
click: function () {
|
click: function () {
|
||||||
var startpath;
|
var startpath;
|
||||||
if (isApp && recent_projects && recent_projects.length) {
|
if (isApp && recent_projects && recent_projects.length) {
|
||||||
|
@ -19,6 +19,7 @@ class ModelProject {
|
|||||||
if (isApp) this.BedrockEntityManager = new BedrockEntityManager();
|
if (isApp) this.BedrockEntityManager = new BedrockEntityManager();
|
||||||
this.format = options.format instanceof ModelFormat ? options.format : Formats.free;
|
this.format = options.format instanceof ModelFormat ? options.format : Formats.free;
|
||||||
this.mode = 'edit';
|
this.mode = 'edit';
|
||||||
|
this.EditSession = null;
|
||||||
|
|
||||||
// Data
|
// Data
|
||||||
this.elements = [];
|
this.elements = [];
|
||||||
@ -185,6 +186,11 @@ class ModelProject {
|
|||||||
BarItems.lock_motion_trail.value = !!Project.motion_trail_lock;
|
BarItems.lock_motion_trail.value = !!Project.motion_trail_lock;
|
||||||
BarItems.lock_motion_trail.updateEnabledState();
|
BarItems.lock_motion_trail.updateEnabledState();
|
||||||
|
|
||||||
|
if (this.EditSession) {
|
||||||
|
Interface.Panels.chat.inside_vue.chat_history = this.EditSession.chat_history;
|
||||||
|
this.EditSession.catchUp();
|
||||||
|
}
|
||||||
|
|
||||||
Blockbench.dispatchEvent('select_project', {project: this});
|
Blockbench.dispatchEvent('select_project', {project: this});
|
||||||
|
|
||||||
setProjectTitle(this.name);
|
setProjectTitle(this.name);
|
||||||
@ -589,8 +595,8 @@ BARS.defineActions(function() {
|
|||||||
Blockbench.dispatchEvent('update_project_settings', formResult);
|
Blockbench.dispatchEvent('update_project_settings', formResult);
|
||||||
|
|
||||||
BARS.updateConditions()
|
BARS.updateConditions()
|
||||||
if (EditSession.active) {
|
if (Project.EditSession) {
|
||||||
EditSession.sendAll('change_project_meta', JSON.stringify(Project));
|
Project.EditSession.sendAll('change_project_meta', JSON.stringify(Project));
|
||||||
}
|
}
|
||||||
|
|
||||||
dialog.hide()
|
dialog.hide()
|
||||||
@ -599,24 +605,19 @@ BARS.defineActions(function() {
|
|||||||
dialog.show()
|
dialog.show()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
/*
|
|
||||||
new Action('close_project', {
|
new Action('close_project', {
|
||||||
icon: 'cancel_presentation',
|
icon: 'cancel_presentation',
|
||||||
category: 'file',
|
category: 'file',
|
||||||
condition: () => (!EditSession.active || EditSession.hosting) && Format,
|
keybind: new Keybind({key: 'w', ctrl: true}),
|
||||||
|
condition: () => Project,
|
||||||
click: function () {
|
click: function () {
|
||||||
if (showSaveDialog()) {
|
Project.close();
|
||||||
resetProject()
|
|
||||||
Modes.options.start.select()
|
|
||||||
Modes.vue.$forceUpdate()
|
|
||||||
Blockbench.dispatchEvent('close_project');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})*/
|
})
|
||||||
new Action('convert_project', {
|
new Action('convert_project', {
|
||||||
icon: 'fas.fa-file-import',
|
icon: 'fas.fa-file-import',
|
||||||
category: 'file',
|
category: 'file',
|
||||||
condition: () => (!EditSession.active || EditSession.hosting),
|
condition: () => Project && (!Project.EditSession || Project.EditSession.hosting),
|
||||||
click: function () {
|
click: function () {
|
||||||
|
|
||||||
var options = {};
|
var options = {};
|
||||||
|
@ -844,8 +844,6 @@ class Cube extends OutlinerElement {
|
|||||||
Outliner.buttons.locked,
|
Outliner.buttons.locked,
|
||||||
Outliner.buttons.visibility,
|
Outliner.buttons.visibility,
|
||||||
];
|
];
|
||||||
Cube.selected = [];
|
|
||||||
Cube.all = [];
|
|
||||||
|
|
||||||
new Property(Cube, 'string', 'name', {default: 'cube'})
|
new Property(Cube, 'string', 'name', {default: 'cube'})
|
||||||
new Property(Cube, 'boolean', 'rescale')
|
new Property(Cube, 'boolean', 'rescale')
|
||||||
|
@ -108,8 +108,6 @@ class Locator extends OutlinerElement {
|
|||||||
'rename',
|
'rename',
|
||||||
'delete'
|
'delete'
|
||||||
])
|
])
|
||||||
Locator.selected = [];
|
|
||||||
Locator.all = [];
|
|
||||||
|
|
||||||
new Property(Locator, 'string', 'name', {default: 'locator'})
|
new Property(Locator, 'string', 'name', {default: 'locator'})
|
||||||
new Property(Locator, 'vector', 'from')
|
new Property(Locator, 'vector', 'from')
|
||||||
|
@ -95,8 +95,6 @@ class NullObject extends OutlinerElement {
|
|||||||
'rename',
|
'rename',
|
||||||
'delete'
|
'delete'
|
||||||
])
|
])
|
||||||
NullObject.selected = [];
|
|
||||||
NullObject.all = [];
|
|
||||||
|
|
||||||
new Property(NullObject, 'string', 'name', {default: 'null_object'})
|
new Property(NullObject, 'string', 'name', {default: 'null_object'})
|
||||||
new Property(NullObject, 'vector', 'from')
|
new Property(NullObject, 'vector', 'from')
|
||||||
|
@ -703,10 +703,10 @@ function dropOutlinerObjects(item, target, event, order) {
|
|||||||
function renameOutliner(element) {
|
function renameOutliner(element) {
|
||||||
stopRenameOutliner()
|
stopRenameOutliner()
|
||||||
|
|
||||||
if (Group.selected && !element && !EditSession.active) {
|
if (Group.selected && !element && !Project.EditSession) {
|
||||||
Group.selected.rename()
|
Group.selected.rename()
|
||||||
|
|
||||||
} else if (selected.length === 1 && !EditSession.active) {
|
} else if (selected.length === 1 && !Project.EditSession) {
|
||||||
selected[0].rename()
|
selected[0].rename()
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -367,13 +367,13 @@ class Texture {
|
|||||||
this.startWatcher()
|
this.startWatcher()
|
||||||
Painter.current = {}
|
Painter.current = {}
|
||||||
|
|
||||||
if (EditSession.active) {
|
if (Project.EditSession) {
|
||||||
this.load(() => {
|
this.load(() => {
|
||||||
var before = {textures: {}}
|
var before = {textures: {}}
|
||||||
before.textures[scope.uuid] = true;
|
before.textures[scope.uuid] = true;
|
||||||
this.edit()
|
this.edit()
|
||||||
var post = new Undo.save({textures: [this]})
|
var post = new Undo.save({textures: [this]})
|
||||||
EditSession.sendEdit({
|
Project.EditSession.sendEdit({
|
||||||
before: before,
|
before: before,
|
||||||
post: post,
|
post: post,
|
||||||
action: 'loaded_texture',
|
action: 'loaded_texture',
|
||||||
|
12
js/undo.js
12
js/undo.js
@ -53,8 +53,8 @@ class UndoSystem {
|
|||||||
Project.saved = false;
|
Project.saved = false;
|
||||||
}
|
}
|
||||||
Blockbench.dispatchEvent('finished_edit', {aspects})
|
Blockbench.dispatchEvent('finished_edit', {aspects})
|
||||||
if (EditSession.active) {
|
if (Project.EditSession && Project.EditSession.active) {
|
||||||
EditSession.sendEdit(entry)
|
Project.EditSession.sendEdit(entry)
|
||||||
}
|
}
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
@ -84,8 +84,8 @@ class UndoSystem {
|
|||||||
|
|
||||||
var entry = this.history[this.index]
|
var entry = this.history[this.index]
|
||||||
this.loadSave(entry.before, entry.post)
|
this.loadSave(entry.before, entry.post)
|
||||||
if (EditSession.active && remote !== true) {
|
if (Project.EditSession && remote !== true) {
|
||||||
EditSession.sendAll('command', 'undo')
|
Project.EditSession.sendAll('command', 'undo')
|
||||||
}
|
}
|
||||||
Blockbench.dispatchEvent('undo', {entry})
|
Blockbench.dispatchEvent('undo', {entry})
|
||||||
}
|
}
|
||||||
@ -99,8 +99,8 @@ class UndoSystem {
|
|||||||
var entry = this.history[this.index]
|
var entry = this.history[this.index]
|
||||||
this.index++;
|
this.index++;
|
||||||
this.loadSave(entry.post, entry.before)
|
this.loadSave(entry.post, entry.before)
|
||||||
if (EditSession.active && remote !== true) {
|
if (Project.EditSession && remote !== true) {
|
||||||
EditSession.sendAll('command', 'redo')
|
Project.EditSession.sendAll('command', 'redo')
|
||||||
}
|
}
|
||||||
Blockbench.dispatchEvent('redo', {entry})
|
Blockbench.dispatchEvent('redo', {entry})
|
||||||
}
|
}
|
||||||
|
@ -22,8 +22,8 @@ try {
|
|||||||
|
|
||||||
function loadInfoFromURL() {
|
function loadInfoFromURL() {
|
||||||
if (location.hash.substr(1, 8) == 'session=') {
|
if (location.hash.substr(1, 8) == 'session=') {
|
||||||
EditSession.dialog()
|
EditSession.token = location.hash.substr(9);
|
||||||
$('#edit_session_token').val(location.hash.substr(9))
|
BarItems.edit_session.click();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (location.hash.substr(1, 2) == 'm=') {
|
if (location.hash.substr(1, 2) == 'm=') {
|
||||||
@ -39,7 +39,7 @@ window.onbeforeunload = function() {
|
|||||||
return 'Unsaved Changes';
|
return 'Unsaved Changes';
|
||||||
} else {
|
} else {
|
||||||
Blockbench.dispatchEvent('before_closing')
|
Blockbench.dispatchEvent('before_closing')
|
||||||
EditSession.quit()
|
if (Project.EditSession) Project.EditSession.quit()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function showSaveDialog(close) {
|
function showSaveDialog(close) {
|
||||||
|
@ -1379,7 +1379,7 @@
|
|||||||
"dialog.edit_session.title": "Edit Session",
|
"dialog.edit_session.title": "Edit Session",
|
||||||
"edit_session.username": "Username",
|
"edit_session.username": "Username",
|
||||||
"edit_session.token": "Token",
|
"edit_session.token": "Token",
|
||||||
"edit_session.about": "Edit Sessions can be used to collaborate on models across the internet. Create a session and copy the token and send it to friends, who can then use it to join.",
|
"edit_session.about": "Edit Sessions can be used to collaborate on models across the internet. Create a session, copy the token, and send it to friends, who can then use it to join.",
|
||||||
"edit_session.join": "Join Session",
|
"edit_session.join": "Join Session",
|
||||||
"edit_session.create": "Create Session",
|
"edit_session.create": "Create Session",
|
||||||
"edit_session.quit": "Quit Session",
|
"edit_session.quit": "Quit Session",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user