mirror of
https://github.com/zero-peak/ZeroOmega.git
synced 2025-03-14 00:48:13 -04:00
Refactor Options constructor into loadOptions and init methods.
This commit is contained in:
parent
a145d4f6a5
commit
29bebd458c
@ -136,5 +136,7 @@ angular.module('omegaTarget', []).factory 'omegaTarget', ($q) ->
|
|||||||
return d.promise
|
return d.promise
|
||||||
openManage: ->
|
openManage: ->
|
||||||
chrome.tabs.create url: 'chrome://extensions/?id=' + chrome.runtime.id
|
chrome.tabs.create url: 'chrome://extensions/?id=' + chrome.runtime.id
|
||||||
|
setOptionsSync: (enabled, args) ->
|
||||||
|
callBackground('setOptionsSync', enabled, args)
|
||||||
|
|
||||||
return omegaTarget
|
return omegaTarget
|
||||||
|
@ -237,13 +237,13 @@ class ChromeOptions extends OmegaTarget.Options
|
|||||||
else
|
else
|
||||||
Promise.reject()
|
Promise.reject()
|
||||||
|
|
||||||
getOldOptions = getOldOptions.catch =>
|
getOldOptions = getOldOptions.catch ->
|
||||||
if options?['config']
|
if options?['config']
|
||||||
Promise.resolve options
|
Promise.resolve options
|
||||||
else if localStorage['config']
|
else if localStorage['config']
|
||||||
Promise.resolve localStorage
|
Promise.resolve localStorage
|
||||||
else
|
else
|
||||||
Promise.reject new @NoOptionsError()
|
Promise.reject new OmegaTarget.Options.NoOptionsError()
|
||||||
|
|
||||||
getOldOptions.then (oldOptions) =>
|
getOldOptions.then (oldOptions) =>
|
||||||
i18n = {
|
i18n = {
|
||||||
|
@ -55,48 +55,99 @@ class Options
|
|||||||
value = profile
|
value = profile
|
||||||
return value
|
return value
|
||||||
|
|
||||||
constructor: (@_options, @_storage, @_state, @log, @sync) ->
|
constructor: (options, @_storage, @_state, @log, @sync) ->
|
||||||
@_storage ?= Storage()
|
@_storage ?= Storage()
|
||||||
@_state ?= Storage()
|
@_state ?= Storage()
|
||||||
@log ?= Log
|
@log ?= Log
|
||||||
if @_options?
|
if not options?
|
||||||
@ready = Promise.resolve(@_options)
|
@init()
|
||||||
else
|
else
|
||||||
@ready = if @sync?.enabled then Promise.resolve() else @_storage.get(null)
|
@ready = @_storage.remove().then(=>
|
||||||
@ready = @ready.then (options) =>
|
@_storage.set(options)
|
||||||
return options if not @sync?
|
).then =>
|
||||||
if options?['schemaVersion']
|
@init()
|
||||||
@_state.get({'syncOptions': ''}).then ({syncOptions}) =>
|
|
||||||
return if syncOptions
|
###*
|
||||||
@_state.set({'syncOptions': 'conflict'})
|
# Attempt to load options from local and remote storage.
|
||||||
@sync.storage.get('schemaVersion').then({schemaVersion}) =>
|
# @param {?{}} args Extra arguments
|
||||||
@_state.set({'syncOptions': 'pristine'}) if not schemaVersion
|
# @param {number=3} args.retry Number of retries before giving up.
|
||||||
return options
|
# @returns {Promise<OmegaOptions>} The loaded options
|
||||||
|
###
|
||||||
|
loadOptions: ({retry} = {}) ->
|
||||||
|
retry ?= 3
|
||||||
|
@_syncWatchStop?()
|
||||||
|
@_syncWatchStop = null
|
||||||
|
@_watchStop?()
|
||||||
|
@_watchStop = null
|
||||||
|
|
||||||
|
loadRaw = if options? then Promise.resolve(options) else
|
||||||
|
if not @sync?.enabled
|
||||||
|
if not @sync?
|
||||||
|
@_state.set({'syncOptions': 'unsupported'})
|
||||||
|
@_storage.get(null)
|
||||||
|
else
|
||||||
@_state.set({'syncOptions': 'sync'})
|
@_state.set({'syncOptions': 'sync'})
|
||||||
@sync.watchAndPull(@_storage)
|
@_syncWatchStop = @sync.watchAndPull(@_storage)
|
||||||
@sync.copyTo(@_storage).then =>
|
@sync.copyTo(@_storage).then =>
|
||||||
@_storage.get(null)
|
@_storage.get(null)
|
||||||
@ready = @ready.then((options) =>
|
|
||||||
@upgrade(options).then(([options, changes]) =>
|
@optionsLoaded = loadRaw.then((options) =>
|
||||||
modified = {}
|
@upgrade(options)
|
||||||
removed = []
|
).then(([options, changes]) =>
|
||||||
for own key, value of changes
|
@_storage.apply(changes: changes).return(options)
|
||||||
if typeof value == 'undefined'
|
).tap((options) =>
|
||||||
removed.push(value)
|
|
||||||
else
|
|
||||||
modified[key] = value
|
|
||||||
@_storage.set(modified).then(=>
|
|
||||||
@_storage.remove(removed)
|
|
||||||
).return(options)
|
|
||||||
).catch (ex) =>
|
|
||||||
if not ex instanceof NoOptionsError
|
|
||||||
@log.error(ex.stack)
|
|
||||||
@reset().tap =>
|
|
||||||
@_state.set({'firstRun': 'new', 'web.switchGuide': 'showOnFirstUse'})
|
|
||||||
).then((options) =>
|
|
||||||
@_options = options
|
@_options = options
|
||||||
@_watch()
|
@_watchStop = @_watch()
|
||||||
).then(=>
|
# Try to set syncOptions to some value if not initialized.
|
||||||
|
@_state.get({'syncOptions': ''}).then ({syncOptions}) =>
|
||||||
|
return if syncOptions
|
||||||
|
@_state.set({'syncOptions': 'conflict'})
|
||||||
|
@sync.storage.get('schemaVersion').then ({schemaVersion}) =>
|
||||||
|
@_state.set({'syncOptions': 'pristine'}) if not schemaVersion
|
||||||
|
).catch (e) =>
|
||||||
|
return Promise.reject(e) unless retry > 0
|
||||||
|
|
||||||
|
getFallbackOptions = Promise.resolve().then =>
|
||||||
|
if e instanceof NoOptionsError
|
||||||
|
@_state.get({
|
||||||
|
'firstRun': 'new'
|
||||||
|
'web.switchGuide': 'showOnFirstUse'
|
||||||
|
}).then (items) => @_state.set(items)
|
||||||
|
return null unless @sync?
|
||||||
|
# Try to fetch options from sync storage.
|
||||||
|
return @sync.storage.get(null).then (options) =>
|
||||||
|
if not options['schemaVersion']
|
||||||
|
@_state.set({'syncOptions': 'pristine'})
|
||||||
|
return null
|
||||||
|
else
|
||||||
|
@_state.set({'syncOptions': 'sync'})
|
||||||
|
@sync.enabled = true
|
||||||
|
@log.log('Options#loadOptions::fromSync', options)
|
||||||
|
options
|
||||||
|
else
|
||||||
|
@log.error(e.stack)
|
||||||
|
# Some serious error happened when loading options. Disable syncing
|
||||||
|
# and use fallback options.
|
||||||
|
@_state.remove(['syncOptions'])
|
||||||
|
return null
|
||||||
|
|
||||||
|
getFallbackOptions.then (options) =>
|
||||||
|
options ?= @parseOptions(@getDefaultOptions())
|
||||||
|
if @sync?
|
||||||
|
prevEnabled = @sync.enabled
|
||||||
|
@sync.enabled = false
|
||||||
|
@_storage.remove().then(=>
|
||||||
|
@_storage.set(options)
|
||||||
|
).then =>
|
||||||
|
@sync.enabled = prevEnabled if @sync?
|
||||||
|
@loadOptions({retry: retry - 1})
|
||||||
|
|
||||||
|
###*
|
||||||
|
# Attempt to initialize (or reinitialize) options.
|
||||||
|
# @returns {Promise<OmegaOptions>} A promise that is fulfilled on ready.
|
||||||
|
###
|
||||||
|
init: ->
|
||||||
|
@ready = @loadOptions().then(=>
|
||||||
if @_options['-startupProfileName']
|
if @_options['-startupProfileName']
|
||||||
@applyProfile(@_options['-startupProfileName'])
|
@applyProfile(@_options['-startupProfileName'])
|
||||||
else
|
else
|
||||||
@ -125,6 +176,8 @@ class Options
|
|||||||
if @_options['-downloadInterval'] > 0
|
if @_options['-downloadInterval'] > 0
|
||||||
@updateProfile()
|
@updateProfile()
|
||||||
|
|
||||||
|
return @ready
|
||||||
|
|
||||||
toString: -> "<Options>"
|
toString: -> "<Options>"
|
||||||
|
|
||||||
###*
|
###*
|
||||||
@ -173,14 +226,11 @@ class Options
|
|||||||
Promise.reject new Error("Invalid schemaVerion #{version}!")
|
Promise.reject new Error("Invalid schemaVerion #{version}!")
|
||||||
|
|
||||||
###*
|
###*
|
||||||
# Reset the options to the given options or initial options.
|
# Parse options in various formats (including JSON & base64).
|
||||||
# @param {?OmegaOptions} options The options to set. Defaults to initial.
|
# @param {OmegaOptions|string} options The options to parse
|
||||||
# @returns {Promise<OmegaOptions>} The options just applied
|
# @returns {Promise<OmegaOptions>} The parsed options.
|
||||||
###
|
###
|
||||||
reset: (options) ->
|
parseOptions: (options) ->
|
||||||
@log.method('Options#reset', this, arguments)
|
|
||||||
if not options
|
|
||||||
options = @getDefaultOptions()
|
|
||||||
if typeof options == 'string'
|
if typeof options == 'string'
|
||||||
if options[0] != '{'
|
if options[0] != '{'
|
||||||
try
|
try
|
||||||
@ -190,11 +240,26 @@ class Options
|
|||||||
options = null
|
options = null
|
||||||
options = try JSON.parse(options)
|
options = try JSON.parse(options)
|
||||||
if not options
|
if not options
|
||||||
return Promise.reject new Error('Invalid options!')
|
return throw new Error('Invalid options!')
|
||||||
@upgrade(options).then ([opt]) =>
|
|
||||||
|
return options
|
||||||
|
|
||||||
|
###*
|
||||||
|
# Reset the options to the given options or initial options.
|
||||||
|
# @param {?OmegaOptions} options The options to set. Defaults to initial.
|
||||||
|
# @returns {Promise<OmegaOptions>} The options just applied
|
||||||
|
###
|
||||||
|
reset: (options) ->
|
||||||
|
@log.method('Options#reset', this, arguments)
|
||||||
|
options ?= getDefaultOptions()
|
||||||
|
@upgrade(@parseOptions(options)).then ([opt]) =>
|
||||||
|
# Disable syncing when resetting to avoid affecting sync storage.
|
||||||
|
@sync.enabled = false if @sync?
|
||||||
|
@_state.remove(['syncOptions'])
|
||||||
@_storage.remove().then(=>
|
@_storage.remove().then(=>
|
||||||
@_storage.set(opt)
|
@_storage.set(opt)
|
||||||
).then -> opt
|
).then =>
|
||||||
|
@init()
|
||||||
|
|
||||||
###*
|
###*
|
||||||
# Called on the first initialization of options.
|
# Called on the first initialization of options.
|
||||||
@ -856,4 +921,44 @@ class Options
|
|||||||
@currentProfileChanged('external')
|
@currentProfileChanged('external')
|
||||||
return
|
return
|
||||||
|
|
||||||
|
###*
|
||||||
|
# Switch options syncing on and off.
|
||||||
|
# @param {boolean} enabled Whether to enable syncing
|
||||||
|
# @param {?{}} args Extra arguments
|
||||||
|
# @param {boolean=false} args.force If true, overwrite options when conflict
|
||||||
|
# @returns {Promise} A promise which is fulfilled when the syncing is switched
|
||||||
|
###
|
||||||
|
setOptionsSync: (enabled, args) ->
|
||||||
|
@log.method('Options#setOptionsSync', this, arguments)
|
||||||
|
if not @sync?
|
||||||
|
return Promise.reject(new Error('Options syncing is unsupported.'))
|
||||||
|
@_state.get({'syncOptions': ''}).then ({syncOptions}) =>
|
||||||
|
if not enabled
|
||||||
|
if syncOptions == 'sync'
|
||||||
|
@_state.set({'syncOptions': 'conflict'})
|
||||||
|
@sync.enabled = false
|
||||||
|
@_syncWatchStop?()
|
||||||
|
@_syncWatchStop = null
|
||||||
|
return
|
||||||
|
|
||||||
|
if syncOptions == 'conflict'
|
||||||
|
if not args?.force
|
||||||
|
return Promise.reject(new Error(
|
||||||
|
'Syncing not enabled due to conflict. Retry with force to overwrite
|
||||||
|
local options and enable syncing.'))
|
||||||
|
return if syncOptions == 'sync'
|
||||||
|
@_state.set({'syncOptions': 'sync'}).then =>
|
||||||
|
if syncOptions == 'conflict'
|
||||||
|
# Try to re-init options from sync.
|
||||||
|
@sync.enabled = false
|
||||||
|
@_storage.remove().then =>
|
||||||
|
@sync.enabled = true
|
||||||
|
@init()
|
||||||
|
else
|
||||||
|
@sync.enabled = true
|
||||||
|
@_syncWatchStop?()
|
||||||
|
@sync.requestPush(@_options)
|
||||||
|
@_syncWatchStop = @sync.watchAndPull(@_storage)
|
||||||
|
return
|
||||||
|
|
||||||
module.exports = Options
|
module.exports = Options
|
||||||
|
Loading…
Reference in New Issue
Block a user