@@ -215,32 +215,33 @@ export class Plugin {
215215 contributors : string [ ]
216216 version : string
217217 variant : PluginVariant
218- min_version : string
219- max_version : string
220- deprecation_note : string
218+ min_version : string = '' ;
219+ max_version : string = '' ;
220+ deprecation_note : string = '' ;
221221 path : string
222- website : string
222+ website : string = '' ;
223223 repository : string
224224 bug_tracker : string
225- source : PluginSource
226- creation_date : string | number
225+ source : PluginSource = 'store' ;
226+ creation_date : number = 0
227227 /**
228228 * Can be used to specify which features a plugin adds. This allows Blockbench to be aware of and suggest even plugins that are not installed.
229229 */
230230 contributes ?: {
231231 formats ?: string [ ]
232232 open_extensions ?: string [ ]
233- }
234- await_loading : boolean
235- has_changelog : boolean
236- changelog : null | PluginChangelog
237- about_fetched : boolean
238- changelog_fetched : boolean
239- disabled : boolean
240- new_repository_format : boolean
241- cache_version : number
233+ } = { } ;
234+ await_loading : boolean = false ;
235+ has_changelog : boolean = false ;
236+ changelog : null | PluginChangelog = null ;
237+ about_fetched : boolean = false ;
238+ changelog_fetched : boolean = false ;
239+ update_available : false | string = false ;
240+ disabled : boolean = false ;
241+ new_repository_format : boolean = false ;
242+ cache_version : number = 0 ;
242243 menu : Menu
243- details : null | PluginDetails
244+ details : null | PluginDetails = null ;
244245 uuid : UUID
245246
246247 onload ?: ( ) => void
@@ -263,22 +264,6 @@ export class Plugin {
263264 this . contributors = [ ] ;
264265 this . version = '0.0.1' ;
265266 this . variant = 'both' ;
266- this . min_version = '' ;
267- this . max_version = '' ;
268- this . deprecation_note = '' ;
269- this . website = '' ;
270- this . source = 'store' ;
271- this . creation_date = 0 ;
272- this . contributes = { } ;
273- this . await_loading = false ;
274- this . has_changelog = false ;
275- this . changelog = null ;
276- this . details = null ;
277- this . about_fetched = false ;
278- this . changelog_fetched = false ;
279- this . disabled = false ;
280- this . new_repository_format = false ;
281- this . cache_version = 0 ;
282267
283268 this . extend ( data )
284269
@@ -445,6 +430,8 @@ export class Plugin {
445430 let response = await this . installDependencies ( first ) ;
446431 if ( response == false ) return ;
447432
433+ this . update_available = false ;
434+
448435 var scope = this ;
449436 function register ( ) {
450437 if ( ! Plugins . json [ scope . id ] ) return ;
@@ -662,6 +649,25 @@ export class Plugin {
662649
663650 return this ;
664651 }
652+ installUpdate ( ) {
653+ this . cache_version ++ ;
654+ this . unload ( )
655+ this . tags . empty ( ) ;
656+ this . contributors . empty ( ) ;
657+ this . dependencies . empty ( ) ;
658+ this . details = null ;
659+ let had_changelog = this . changelog_fetched ;
660+ this . changelog_fetched = false ;
661+
662+ this . download ( ) ;
663+
664+ this . fetchAbout ( true ) ;
665+ if ( had_changelog && this . has_changelog ) {
666+ this . fetchChangelog ( true ) ;
667+ }
668+
669+ return this ;
670+ }
665671 async #runPluginFile( path : string ) {
666672 let file_content : any ;
667673 if ( path . startsWith ( 'http' ) ) {
@@ -1055,6 +1061,7 @@ export async function loadInstalledPlugins() {
10551061 }
10561062 const install_promises = [ ] ;
10571063 const online_access = Plugins . json instanceof Object && navigator . onLine ;
1064+ const allow_updates = settings . automatic_plugin_updates . value ;
10581065
10591066 // Setup offers from store
10601067 if ( online_access ) {
@@ -1129,15 +1136,27 @@ export async function loadInstalledPlugins() {
11291136 plugin . installed = true ;
11301137 if ( installation . disabled ) plugin . disabled = true ;
11311138
1132- if ( isApp && (
1133- ( installation . version && plugin . version && VersionUtil . compare ( plugin . version , '<=' , installation . version ) ) ||
1134- ( plugin . min_version && Blockbench . isOlderThan ( plugin . min_version ) )
1135- ) ) {
1136- // Get from file
1137- let promise = plugin . load ( false ) ;
1138- install_promises . push ( promise ) ;
1139+ if ( isApp ) {
1140+ let up_to_date = installation . version && plugin . version && VersionUtil . compare ( plugin . version , '<=' , installation . version ) ;
1141+ let update_unsupported = plugin . min_version && Blockbench . isOlderThan ( plugin . min_version ) ;
1142+ let update_available = ! up_to_date && ! update_unsupported ;
1143+
1144+ if ( update_available && allow_updates ) {
1145+ // Update
1146+ let promise = plugin . download ( ) ;
1147+ if ( plugin . await_loading ) {
1148+ install_promises . push ( promise ) ;
1149+ }
1150+ } else {
1151+ if ( update_available && ! allow_updates ) {
1152+ plugin . update_available = plugin . version ;
1153+ }
1154+ // Get from local file
1155+ let promise = plugin . load ( false ) ;
1156+ install_promises . push ( promise ) ;
1157+ }
11391158 } else {
1140- // Update
1159+ // Web app always loads from web
11411160 let promise = plugin . download ( ) ;
11421161 if ( plugin . await_loading ) {
11431162 install_promises . push ( promise ) ;
@@ -1227,43 +1246,46 @@ BARS.defineActions(function() {
12271246 computed : {
12281247 plugin_search ( ) {
12291248 let search_name = this . search_term . toUpperCase ( ) ;
1249+ let plugins : Plugin [ ] = this . items ;
12301250 if ( search_name ) {
1231- let filtered = this . items . filter ( item => {
1251+ let filtered = plugins . filter ( item => {
12321252 return (
12331253 item . id . toUpperCase ( ) . includes ( search_name ) ||
12341254 item . title . toUpperCase ( ) . includes ( search_name ) ||
12351255 item . description . toUpperCase ( ) . includes ( search_name ) ||
12361256 item . author . toUpperCase ( ) . includes ( search_name ) ||
1237- item . tags . find ( tag => tag . toUpperCase ( ) . includes ( search_name ) )
1257+ item . tags . find ( tag => tag . toUpperCase ( ) . includes ( search_name ) ) ||
1258+ item . update_available && search_name . includes ( 'UPDATE_AVAILABLE' )
12381259 )
12391260 } ) ;
12401261 let installed = filtered . filter ( p => p . installed ) ;
12411262 let not_installed = filtered . filter ( p => ! p . installed ) ;
12421263 return installed . concat ( not_installed ) ;
12431264 } else {
1244- return this . items . filter ( item => {
1265+ return plugins . filter ( item => {
12451266 return ( this . tab == 'installed' ) == item . installed ;
12461267 } )
12471268 }
12481269 } ,
12491270 suggested_rows ( ) {
12501271 let tags = [ "Animation" ] ;
1251- this . items . forEach ( plugin => {
1272+ let plugins : Plugin [ ] = this . items ;
1273+ plugins . forEach ( plugin => {
12521274 if ( ! plugin . installed ) return ;
12531275 tags . safePush ( ...plugin . tags )
12541276 } )
12551277 let rows = tags . map ( tag => {
1256- let plugins = this . items . filter ( plugin => ! plugin . installed && plugin . tags . includes ( tag ) && ! plugin . tags . includes ( 'Deprecated' ) ) . slice ( 0 , 12 ) ;
1278+ let filtered = plugins . filter ( plugin => ! plugin . installed && plugin . tags . includes ( tag ) && ! plugin . tags . includes ( 'Deprecated' ) ) . slice ( 0 , 12 ) ;
12571279 return {
12581280 title : tag ,
1259- plugins,
1281+ plugins : filtered ,
12601282 }
12611283 } ) . filter ( row => row . plugins . length > 2 ) ;
12621284 //rows.sort((a, b) => a.plugins.length - b.plugins.length);
12631285 rows . sort ( ( ) => Math . random ( ) - 0.5 ) ;
12641286
12651287 let cutoff = Date . now ( ) - ( 3_600_000 * 24 * 28 ) ;
1266- let new_plugins = this . items . filter ( plugin => ! plugin . installed && plugin . creation_date > cutoff && ! plugin . tags . includes ( 'Deprecated' ) ) ;
1288+ let new_plugins = plugins . filter ( plugin => ! plugin . installed && plugin . creation_date > cutoff && ! plugin . tags . includes ( 'Deprecated' ) ) ;
12671289 if ( new_plugins . length ) {
12681290 new_plugins . sort ( ( a , b ) => a . creation_date - b . creation_date ) ;
12691291 let new_row = {
@@ -1624,6 +1646,7 @@ BARS.defineActions(function() {
16241646 <div class="description">{{ plugin.description }}</div>
16251647 <ul class="plugin_tag_list">
16261648 <li v-for="tag in plugin.tags" :class="getTagClass(tag)" :key="tag" @click="search_term = tag;">{{tag}}</li>
1649+ <li v-if="plugin.update_available" class="plugin_tag_update" :key="'update_available'" @click="search_term = 'update_available';">${ tl ( 'dialog.plugins.update_available' ) } </li>
16271650 </ul>
16281651 </li>
16291652 <div class="no_plugin_message tl" v-if="plugin_search.length < 1 && tab === 'installed'">${ tl ( 'dialog.plugins.none_installed' ) } </div>
@@ -1662,6 +1685,14 @@ BARS.defineActions(function() {
16621685 </div>
16631686
16641687 <div class="button_bar" v-if="selected_plugin.installed || selected_plugin.isInstallable() == true">
1688+ <button type="button" @click="selected_plugin.installUpdate()"
1689+ v-if="selected_plugin.installed && selected_plugin.update_available"
1690+ style="color: var(--color-update);"
1691+ :title="tl('dialog.plugins.update_available') + ': ' + selected_plugin.update_available"
1692+ >
1693+ <i class="material-icons icon">update</i>
1694+ <span>${ tl ( 'dialog.plugins.update' ) } </span>
1695+ </button>
16651696 <button type="button" v-if="selected_plugin.installed" @click="selected_plugin.toggleDisabled()">
16661697 <i class="material-icons icon">bedtime</i>
16671698 <span>{{ selected_plugin.disabled ? '${ tl ( 'dialog.plugins.enable' ) } ' : '${ tl ( 'dialog.plugins.disable' ) } ' }}</span>
@@ -1682,6 +1713,7 @@ BARS.defineActions(function() {
16821713
16831714 <ul class="plugin_tag_list">
16841715 <li v-for="tag in selected_plugin.tags" :class="getTagClass(tag)" :key="tag" @click="search_term = tag;">{{tag}}</li>
1716+ <li v-if="selected_plugin.update_available" class="plugin_tag_update" :key="'update_available'" @click="search_term = 'update_available';">${ tl ( 'dialog.plugins.update_available' ) } </li>
16851717 </ul>
16861718
16871719 <div class="description" :class="{disabled_plugin: selected_plugin.disabled}">{{ selected_plugin.description }}</div>
0 commit comments