const StartScreen = { loaders: {} }; function addStartScreenSection(id, data) { if (typeof id == 'object') { data = id; id = ''; } var obj = $(Interface.createElement('section', {id})) if (typeof data.graphic === 'object') { var left = $('
') obj.append(left) if (data.graphic.type === 'icon') { var icon = Blockbench.getIconNode(data.graphic.icon) left.addClass('graphic_icon') left.append(icon) } else { left.css('background-image', `url('${data.graphic.source}')`) } if (data.graphic.width) { left.css('width', data.graphic.width+'px'); } if (data.graphic.width && data.text) { left.css('flex-shrink', '0'); } if (data.graphic.width && data.graphic.height && Blockbench.isMobile) { left.css('height', '0') .css('padding-top', '0') .css('padding-bottom', (data.graphic.height/data.graphic.width*100)+'%') } else { if (data.graphic.height) left.css('height', data.graphic.height+'px'); if (data.graphic.width && !data.graphic.height && !data.graphic.aspect_ratio) left.css('height', data.graphic.width+'px'); if (data.graphic.aspect_ratio) left.css('aspect-ratio', data.graphic.aspect_ratio); } if (data.graphic.description) { let content = $(marked(data.graphic.description)); content.css({ 'bottom': '15px', 'right': '15px', 'color': data.graphic.text_color || '#ffffff', }); left.append(content); } } if (data.text instanceof Array) { var right = $('
') obj.append(right) data.text.forEach(line => { var content = line.text ? marked(tl(line.text)) : ''; switch (line.type) { case 'h1': var tag = 'h2'; break; case 'h2': var tag = 'h3'; break; case 'list': var tag = 'ul class="list_style"'; line.list.forEach(string => { content += `
  • ${marked(tl(string))}
  • `; }) break; case 'button': var tag = 'button'; break; default: var tag = 'p'; break; } var l = $(`<${tag}>${content}`); if (typeof line.click == 'function') { l.on('click', line.click); } right.append(l); }) } if (data.layout == 'vertical') { obj.addClass('vertical'); } if (data.features instanceof Array) { let features_section = document.createElement('ul'); features_section.className = 'start_screen_features' data.features.forEach(feature => { let li = document.createElement('li'); let img = new Image(); img.src = feature.image; let title = document.createElement('h3'); title.textContent = feature.title; let text = document.createElement('p'); text.textContent = feature.text; li.append(img, title, text); features_section.append(li); }) obj.append(features_section); } if (data.closable !== false) { obj.append(`clear`); obj.find('i.start_screen_close_button').click((e) => { obj.detach() }); } if (typeof data.click == 'function') { obj.on('click', event => { if (event.target.classList.contains('start_screen_close_button')) return; data.click() }) } if (data.color) { obj.css('background-color', data.color); if (data.color == 'var(--color-bright_ui)') { obj.addClass('bright_ui') } } if (data.text_color) { obj.css('color', data.text_color); } if (data.last) { $('#start_screen > content').append(obj); } else if (data.insert_after) { $('#start_screen > content').find(`#${data.insert_after}`).after(obj); } else if (data.insert_before) { $('#start_screen > content').find(`#${data.insert_before}`).before(obj); } else { $('#start_screen > content').prepend(obj); } if (!obj[0].parentElement) { $('#start_screen > content').append(obj); } return { delete() { obj[0].remove(); } } } onVueSetup(function() { StateMemory.init('start_screen_list_type', 'string') StartScreen.vue = new Vue({ el: '#start_screen', components: {}, data: { formats: Formats, loaders: ModelLoader.loaders, selected_format_id: '', recent: isApp ? recent_projects : [], list_type: StateMemory.start_screen_list_type || 'grid', redact_names: settings.streamer_mode.value, redacted: tl('generic.redacted'), search_term: '', isApp, mobile_layout: Blockbench.isMobile, getIconNode: Blockbench.getIconNode }, methods: { getDate(p) { if (p.day) { var diff = (365e10 + Blockbench.openTime.dayOfYear() - p.day) % 365; if (diff <= 0) { return tl('dates.today'); } else if (diff == 1) { return tl('dates.yesterday'); } else if (diff <= 7) { return tl('dates.this_week'); } else { return tl('dates.weeks_ago', [Math.ceil(diff/7)]); } } else { return '-' } }, openProject: function(p, event) { Blockbench.read([p.path], {}, files => { loadModelFile(files[0]); }) }, getThumbnail(model_path) { let hash = model_path.hashCode().toString().replace(/^-/, '0'); let path = PathModule.join(app.getPath('userData'), 'thumbnails', `${hash}.png`); if (!fs.existsSync(path)) return; return path + '?' + Math.round(Math.random()*255); }, setListType(type) { this.list_type = type; StateMemory.start_screen_list_type = type; StateMemory.save('start_screen_list_type') }, recentProjectContextMenu(recent_project, event) { let menu = new Menu('recent_project', [ { id: 'favorite', name: 'mode.start.recent.favorite', icon: recent_project.favorite ? 'fas.fa-star' : 'far.fa-star', click: () => { this.toggleProjectFavorite(recent_project); } }, { id: 'remove', name: 'generic.remove', icon: 'clear', click: () => { recent_projects.remove(recent_project); updateRecentProjects(); } } ]) menu.show(event); }, toggleProjectFavorite(recent_project) { recent_project.favorite = !recent_project.favorite; if (recent_project.favorite) { recent_projects.remove(recent_project); recent_projects.splice(0, 0, recent_project); } updateRecentProjects(); }, getFormatCategories() { let categories = {}; function add(key, format) { if (!categories[format.category]) { categories[format.category] = { name: tl('format_category.' + format.category), entries: [] } } categories[format.category].entries.push(format); } for (let key in this.formats) { add(key, this.formats[key]) } for (let key in this.loaders) { add(key, this.loaders[key]) } return categories; }, loadFormat(format_entry) { this.selected_format_id = format_entry.id; if (format_entry.onFormatPage) format_entry.onFormatPage(); }, confirmSetupScreen(format_entry) { this.selected_format_id = ''; if (format_entry.onStart) format_entry.onStart(); if (typeof format_entry.new == 'function') format_entry.new(); }, openLink(link) { Blockbench.openLink(link); }, tl }, computed: { projects() { if (!this.search_term) return this.recent; let terms = this.search_term.toLowerCase().split(/\s/); return this.recent.filter(project => { return !terms.find(term => ( !project.path.toLowerCase().includes(term) )) }) } }, template: `

    ${tl('mode.start.new')}

      • help
      • menu_book
    clear

    {{ viewed_format.name }}

    ${tl('mode.start.recent')}

  • view_module
  • list
  • {{ '['+tl('generic.redacted')+']' }}
    • {{ redact_names ? redacted : project.name }} {{ getDate(project) }}
    • {{ tl('mode.start.no_recents') }}
    • {{ redact_names ? redacted : project.name }}
    ` }) }); class ModelLoader { constructor(id, options) { this.id = id; this.name = tl(options.name); this.description = options.description ? tl(options.description) : ''; this.icon = options.icon || 'arrow_forward'; this.category = options.category || 'loaders'; this.target = options.target || ''; this.show_on_start_screen = true; this.confidential = options.confidential || false; this.condition = options.condition; this.format_page = options.format_page; this.onFormatPage = options.onFormatPage; this.onStart = options.onStart; Vue.set(ModelLoader.loaders, id, this); if (this.format_page && this.format_page.component) { Vue.component(`format_page_${this.id}`, this.format_page.component) } } new() { this.onStart(); } delete() { delete ModelLoader.loaders[this.id]; } } ModelLoader.loaders = {}; (function() { /*$.getJSON('./content/news.json').then(data => { addStartScreenSection('new_version', data.new_version) })*/ var news_call = $.ajax({ cache: false, url: 'https://web.blockbench.net/content/news.json', dataType: 'json' }); documentReady.then(() => { Blockbench.startup_count = parseInt(localStorage.getItem('startups')||0) //Backup Model if (localStorage.getItem('backup_model') && (!isApp || !currentwindow.webContents.second_instance) && localStorage.getItem('backup_model').length > 40) { var backup_models = localStorage.getItem('backup_model') let section = addStartScreenSection({ color: 'var(--color-back)', graphic: {type: 'icon', icon: 'fa-archive'}, text: [ {type: 'h2', text: tl('message.recover_backup.title')}, {text: tl('message.recover_backup.message')}, {type: 'button', text: tl('message.recover_backup.recover'), click: (e) => { let parsed_backup_models = JSON.parse(backup_models); for (let uuid in parsed_backup_models) { Codecs.project.load(parsed_backup_models[uuid], {path: 'backup.bbmodel', no_file: true}) } section.delete(); }}, {type: 'button', text: tl('dialog.discard'), click: (e) => { localStorage.removeItem('backup_model'); section.delete(); }} ] }) } if (settings.streamer_mode.value) { updateStreamerModeNotification() } addStartScreenSection('splash_screen', { "text_color": '#000000', "graphic": { "type": "image", "source": "./assets/splash_art.png?43", "width": 1000, "aspect_ratio": "21/9", "description": "Splash Art by [MisterGriimm](https://twitter.com/MisterGriimm) and [MidnitePixel_](https://twitter.com/MidnitePixel_)", "text_color": '#cfcfcf' } }) if (!Blockbench.hasFlag('after_update')) { document.getElementById('start_screen').scrollTop = 100; } //Twitter let twitter_ad; if (Blockbench.startup_count < 20 && Blockbench.startup_count % 5 === 4) { twitter_ad = true; addStartScreenSection({ color: '#1da1f2', text_color: '#ffffff', graphic: {type: 'icon', icon: 'fab.fa-twitter'}, text: [ {type: 'h2', text: 'Blockbench on Twitter'}, {text: 'Follow Blockbench on Twitter for the latest news as well as cool models from the community! [twitter.com/blockbench](https://twitter.com/blockbench/)'} ], last: true }) } //Discord if (Blockbench.startup_count < 6 && !twitter_ad) { addStartScreenSection({ color: '#5865F2', text_color: '#ffffff', graphic: {type: 'icon', icon: 'fab.fa-discord'}, text: [ {type: 'h2', text: 'Discord Server'}, {text: 'You need help with modeling or you want to chat about Blockbench? Join the official [Blockbench Discord](https://discord.gg/WVHg5kH)!'} ], last: true }) } // Quick Setup if (Blockbench.startup_count <= 1) { let section = Interface.createElement('section', {id: 'quick_setup'}); $('#start_screen > content').prepend(section); new Vue({ data() {return { language: Language.code, language_original: Language.code, languages: Language.options, keymap: 'default', keymap_changed: false, theme: 'dark', keymap_options: { default: tl('action.load_keymap.default'), mouse: tl('action.load_keymap.mouse'), blender: 'Blender', cinema4d: 'Cinema 4D', maya: 'Maya', }, }}, methods: { tl, close() { obj.remove(); }, reload() { Blockbench.reload(); }, loadTheme(theme_id) { this.theme = theme_id; let theme = CustomTheme.themes.find(t => t.id == theme_id); if (theme) CustomTheme.loadTheme(theme); }, getThemeThumbnailStyle(theme_id) { let theme = CustomTheme.themes.find(t => t.id == theme_id); let style = {}; if (!theme) return style; for (let key in theme.colors) { style[`--color-${key}`] = theme.colors[key]; } return style; }, openThemes() { BarItems.theme_window.click(); } }, watch: { language(v) { settings.language.set(v); Settings.save(); }, keymap(keymap, old_keymap) { this.keymap_changed = true; let success = Keybinds.loadKeymap(keymap, true); if (!success) this.keymap = old_keymap; } }, template: `
    clear

    ${tl('mode.start.quick_setup')}

    {{ tl('action.load_keymap.' + keymap + '.desc') }}

    refresh

    {{ tl('message.restart_to_update') }}

    Dark
    Light
    Contrast
    more_horiz
    {{ tl('mode.start.quick_setup.more_themes') }}
    ` }).$mount(section); } }) Promise.all([news_call, documentReady]).then((data) => { if (!data || !data[0]) return; data = data[0]; //Update Screen if (Blockbench.hasFlag('after_update') && data.new_version) { data.new_version.insert_after = 'splash_screen' addStartScreenSection('new_version', data.new_version); jQuery.ajax({ url: 'https://blckbn.ch/api/event/successful_update', type: 'POST', data: { version: Blockbench.version } }) } if (data.psa) { (function() { if (typeof data.psa.version == 'string') { if (data.psa.version.includes('-')) { limits = data.psa.version.split('-'); if (limits[0] && compareVersions(limits[0], Blockbench.version)) return; if (limits[1] && compareVersions(Blockbench.version, limits[1])) return; } else { if (data.psa.version != Blockbench.version) return; } } addStartScreenSection(data.psa) })() } }) })()