Merge pull request #1045 from h3poteto/iss-948

refs #948 Add a preference to auto launch at login
This commit is contained in:
AkiraFukushima 2019-09-25 23:40:32 +09:00 committed by GitHub
commit 590bb604c1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 219 additions and 77 deletions

33
package-lock.json generated
View File

@ -1912,6 +1912,12 @@
"resolved": "https://registry.npmjs.org/@trodi/electron-splashscreen/-/electron-splashscreen-0.3.4.tgz",
"integrity": "sha512-nYF+sfNIEUhZPyzYUOpcqyCZoDYmMfZq8jLhEolvQFSVwrJ7gAlPhhMxpuw/qpCzPErUkFLEtdGGvK1tGtLuvQ=="
},
"@types/auto-launch": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/@types/auto-launch/-/auto-launch-5.0.1.tgz",
"integrity": "sha512-+KQ+/koZ7sJXnf5cnCANofY6yXAdYJNEoVZEuWcwJfuWbUp9u6l09I7KhwD+ivU+cdz7JId4V5ukxscWtHdSuw==",
"dev": true
},
"@types/babel__core": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.0.tgz",
@ -2971,6 +2977,11 @@
"default-require-extensions": "^2.0.0"
}
},
"applescript": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/applescript/-/applescript-1.0.0.tgz",
"integrity": "sha1-u4evVoytA0pOSMS9r2Bno6JwExc="
},
"aproba": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
@ -3242,6 +3253,18 @@
"integrity": "sha1-0IiFvmubv5Q5/gh8dihyRfCoFFA=",
"dev": true
},
"auto-launch": {
"version": "5.0.5",
"resolved": "https://registry.npmjs.org/auto-launch/-/auto-launch-5.0.5.tgz",
"integrity": "sha512-ppdF4mihhYzMYLuCcx9H/c5TUOCev8uM7en53zWVQhyYAJrurd2bFZx3qQVeJKF2jrc7rsPRNN5cD+i23l6PdA==",
"requires": {
"applescript": "^1.0.0",
"mkdirp": "^0.5.1",
"path-is-absolute": "^1.0.0",
"untildify": "^3.0.2",
"winreg": "1.2.4"
}
},
"autoprefixer": {
"version": "9.6.1",
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.6.1.tgz",
@ -21060,6 +21083,11 @@
}
}
},
"untildify": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/untildify/-/untildify-3.0.3.tgz",
"integrity": "sha512-iSk/J8efr8uPT/Z4eSUywnqyrQU7DSdMfdqK4iWEaUVVmcP5JcnpRqmVMwcwcnmI1ATFNgC5V90u09tBynNFKA=="
},
"unused-filename": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unused-filename/-/unused-filename-1.0.0.tgz",
@ -22477,6 +22505,11 @@
}
}
},
"winreg": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/winreg/-/winreg-1.2.4.tgz",
"integrity": "sha1-ugZWKbepJRMOFXeRCM9UCZDpjRs="
},
"wordwrap": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",

View File

@ -163,6 +163,7 @@
"@trodi/electron-splashscreen": "^0.3.4",
"about-window": "^1.13.1",
"animate.css": "^3.7.0",
"auto-launch": "^5.0.5",
"axios": "^0.18.1",
"boom": "^7.3.0",
"deep-extend": "^0.6.0",
@ -208,6 +209,7 @@
"@babel/preset-env": "^7.4.3",
"@babel/runtime": "^7.4.3",
"@mapbox/stylelint-processor-arbitrary-tags": "^0.2.0",
"@types/auto-launch": "^5.0.1",
"@types/electron-json-storage": "^4.0.0",
"@types/i18next": "^12.1.0",
"@types/jest": "^24.0.15",

View File

@ -14,6 +14,9 @@ const state = (): GeneralState => {
cw: false,
nfsw: false,
hideAllAttachments: false
},
other: {
launch: false
}
},
loading: false
@ -31,7 +34,7 @@ const initStore = () => {
const app = {
namespaced: true,
actions: {
loadPreferences (_) {
loadPreferences(_) {
return true
}
}

View File

@ -13,6 +13,9 @@ describe('Preferences/General', () => {
cw: false,
nfsw: false,
hideAllAttachments: false
},
other: {
launch: false
}
},
loading: false

View File

@ -45,6 +45,10 @@
"general": {
"timeline": {
"description": "Customize view in your timelines."
},
"other": {
"title": "Other options",
"launch": "Launch app on login"
}
}
},

View File

@ -127,6 +127,10 @@
"cw": "Always ignore contents warnings",
"nfsw": "Always ignore NFSW of medias",
"hideAllAttachments": "Hide all medias"
},
"other": {
"title": "Other options",
"launch": "Launch app on login"
}
},
"appearance": {

View File

@ -3,5 +3,13 @@
"shortcut": {
"ctrl_r": "Reload current timeline"
}
},
"preferences": {
"general": {
"other": {
"title": "Other options",
"launch": "Launch app on login"
}
}
}
}

View File

@ -6,6 +6,12 @@
"follow_requests": "Follow Requests"
},
"preferences": {
"general": {
"other": {
"title": "Other options",
"launch": "Launch app on login"
}
},
"appearance": {
"toot_padding": "Padding around toot"
}

View File

@ -127,6 +127,10 @@
"cw": "常にCWを表示する",
"nfsw": "常にNFSWを表示する",
"hideAllAttachments": "すべてのメディアを非表示にする"
},
"other": {
"title": "その他",
"launch": "ログイン時にアプリを起動する"
}
},
"appearance": {

View File

@ -7,6 +7,10 @@
"cw": "Always ignore contents warnings",
"nfsw": "Always ignore NFSW of medias",
"hideAllAttachments": "Hide all medias"
},
"other": {
"title": "Other options",
"launch": "Launch app on login"
}
},
"appearance": {

View File

@ -67,6 +67,10 @@
"cw": "Always ignore contents warnings",
"nfsw": "Always ignore NFSW of medias",
"hideAllAttachments": "Hide all medias"
},
"other": {
"title": "Other options",
"launch": "Launch app on login"
}
},
"appearance": {

View File

@ -3,5 +3,13 @@
"shortcut": {
"ctrl_r": "Reload current timeline"
}
},
"preferences": {
"general": {
"other": {
"title": "Other options",
"launch": "Launch app on login"
}
}
}
}

View File

@ -24,6 +24,7 @@ import { initSplashScreen, Config } from '@trodi/electron-splashscreen'
import openAboutWindow from 'about-window'
import { Status, Notification as RemoteNotification, Account as RemoteAccount } from 'megalodon'
import sanitizeHtml from 'sanitize-html'
import AutoLaunch from 'auto-launch'
import pkg from '~/package.json'
import Authentication from './auth'
@ -107,6 +108,8 @@ const splashURL =
// https://github.com/louischatriot/nedb/issues/459
const userData = app.getPath('userData')
const appPath = app.getPath('exe')
const accountDBPath = process.env.NODE_ENV === 'production' ? userData + '/db/account.db' : 'account.db'
let accountDB = new Datastore({
filename: accountDBPath,
@ -139,6 +142,11 @@ const accountCache = new AccountCache(accountCachePath)
const soundBasePath =
process.env.NODE_ENV === 'development' ? path.join(__dirname, '../../build/sounds/') : path.join(process.resourcesPath!, 'build/sounds/')
const launcher = new AutoLaunch({
name: 'Whalebird',
path: appPath
})
async function listAccounts(): Promise<Array<LocalAccount>> {
try {
const accounts = await accountManager.listAccounts()
@ -206,7 +214,7 @@ async function createWindow() {
}
/**
* Windows10 don' notify, so we have to set appId
* Windows10 don't notify, so we have to set appId
* https://github.com/electron/electron/issues/10864
*/
app.setAppUserModelId(appId)
@ -458,6 +466,17 @@ ipcMain.on('remove-all-accounts', (event: Event) => {
})
})
ipcMain.on('change-auto-launch', (event: Event, enable: boolean) => {
launcher.isEnabled().then(enabled => {
if (!enabled && enable) {
launcher.enable()
} else if (enabled && !enable) {
launcher.disable()
}
event.sender.send('response-change-auto-launch', enable)
})
})
// badge
ipcMain.on('reset-badge', () => {
if (process.platform === 'darwin') {
@ -861,16 +880,20 @@ ipcMain.on('toot-action-sound', () => {
})
// preferences
ipcMain.on('get-preferences', (event: Event) => {
ipcMain.on('get-preferences', async (event: Event) => {
const preferences = new Preferences(preferencesDBPath)
preferences
.load()
.then(conf => {
event.sender.send('response-get-preferences', conf)
})
.catch(err => {
event.sender.send('error-get-preferences', err)
const enabled = await launcher.isEnabled()
await preferences
.update({
general: {
other: enabled
}
})
.catch(err => console.error(err))
const conf = await preferences.load().catch(err => {
event.sender.send('error-get-preferences', err)
})
event.sender.send('response-get-preferences', conf)
})
ipcMain.on('update-preferences', (event: Event, data: any) => {

View File

@ -11,7 +11,7 @@ import { Timeline } from '~/src/types/timeline'
import { Notify } from '~/src/types/notify'
import { Appearance } from '~/src/types/appearance'
import { Language as LanguageSet } from '~/src/types/language'
import { General, State, Notification, BaseConfig } from '~/src/types/preference'
import { General, State, Notification, BaseConfig, Other } from '~/src/types/preference'
const sound: Sound = {
fav_rb: true,
@ -24,9 +24,14 @@ const timeline: Timeline = {
hideAllAttachments: false
}
const other: Other = {
launch: false
}
const general: General = {
sound: sound,
timeline: timeline
timeline: timeline,
other: other
}
const state: State = {

View File

@ -1,50 +1,36 @@
<template>
<div id="general" v-loading="loading">
<h2>{{ $t('preferences.general.title') }}</h2>
<el-form class="sounds section" label-position="right" label-width="250px" size="small">
<h3>{{ $t('preferences.general.sounds.title') }}</h3>
<p class="description">{{ $t('preferences.general.sounds.description') }}</p>
<el-form-item for="fav_rb" :label="$t('preferences.general.sounds.fav_rb')">
<el-switch
id="fav_rb"
v-model="sound_fav_rb"
active-color="#13ce66">
</el-switch>
</el-form-item>
<el-form-item for="sound_toot" :label="$t('preferences.general.sounds.toot')">
<el-switch
id="sound_toot"
v-model="sound_toot"
active-color="#13ce66">
</el-switch>
</el-form-item>
</el-form>
<el-form class="timeline section" label-potision="right" label-width="250px" size="samll">
<h3>{{ $t('preferences.general.timeline.title') }}</h3>
<p class="description">{{ $t('preferences.general.timeline.description') }}</p>
<el-form-item for="cw" :label="$t('preferences.general.timeline.cw')">
<el-switch
id="cw"
v-model="timeline_cw"
active-color="#13ce66">
</el-switch>
</el-form-item>
<el-form-item for="nfsw" :label="$t('preferences.general.timeline.nfsw')">
<el-switch
id="nfsw"
v-model="timeline_nfsw"
active-color="#13ce66">
</el-switch>
</el-form-item>
<el-form-item for="hideAllAttachments" :label="$t('preferences.general.timeline.hideAllAttachments')">
<el-switch
id="hideAllAttachments"
v-model="timeline_hide_attachments"
active-color="#13ce66">
</el-switch>
</el-form-item>
</el-form>
</div>
<div id="general" v-loading="loading">
<h2>{{ $t('preferences.general.title') }}</h2>
<el-form class="sounds section" label-position="right" label-width="250px" size="small">
<h3>{{ $t('preferences.general.sounds.title') }}</h3>
<p class="description">{{ $t('preferences.general.sounds.description') }}</p>
<el-form-item for="fav_rb" :label="$t('preferences.general.sounds.fav_rb')">
<el-switch id="fav_rb" v-model="sound_fav_rb" active-color="#13ce66"> </el-switch>
</el-form-item>
<el-form-item for="sound_toot" :label="$t('preferences.general.sounds.toot')">
<el-switch id="sound_toot" v-model="sound_toot" active-color="#13ce66"> </el-switch>
</el-form-item>
</el-form>
<el-form class="timeline section" label-potision="right" label-width="250px" size="samll">
<h3>{{ $t('preferences.general.timeline.title') }}</h3>
<p class="description">{{ $t('preferences.general.timeline.description') }}</p>
<el-form-item for="cw" :label="$t('preferences.general.timeline.cw')">
<el-switch id="cw" v-model="timeline_cw" active-color="#13ce66"> </el-switch>
</el-form-item>
<el-form-item for="nfsw" :label="$t('preferences.general.timeline.nfsw')">
<el-switch id="nfsw" v-model="timeline_nfsw" active-color="#13ce66"> </el-switch>
</el-form-item>
<el-form-item for="hideAllAttachments" :label="$t('preferences.general.timeline.hideAllAttachments')">
<el-switch id="hideAllAttachments" v-model="timeline_hide_attachments" active-color="#13ce66"> </el-switch>
</el-form-item>
</el-form>
<el-form class="other section" label-position="right" label-width="250px" size="small">
<h3>{{ $t('preferences.general.other.title') }}</h3>
<el-form-item for="launch" :label="$t('preferences.general.other.launch')">
<el-switch id="launch" v-model="other_launch" active-color="#13ce66"> </el-switch>
</el-form-item>
</el-form>
</div>
</template>
<script>
@ -57,64 +43,73 @@ export default {
loading: state => state.Preferences.General.loading
}),
sound_fav_rb: {
get () {
get() {
return this.$store.state.Preferences.General.general.sound.fav_rb
},
set (value) {
set(value) {
this.$store.dispatch('Preferences/General/updateSound', {
fav_rb: value
})
}
},
sound_toot: {
get () {
get() {
return this.$store.state.Preferences.General.general.sound.toot
},
set (value) {
set(value) {
this.$store.dispatch('Preferences/General/updateSound', {
toot: value
})
}
},
timeline_cw: {
get () {
get() {
return this.$store.state.Preferences.General.general.timeline.cw
},
set (value) {
set(value) {
this.$store.dispatch('Preferences/General/updateTimeline', {
cw: value
})
}
},
timeline_nfsw: {
get () {
get() {
return this.$store.state.Preferences.General.general.timeline.nfsw
},
set (value) {
set(value) {
this.$store.dispatch('Preferences/General/updateTimeline', {
nfsw: value
})
}
},
timeline_hide_attachments: {
get () {
get() {
return this.$store.state.Preferences.General.general.timeline.hideAllAttachments
},
set (value) {
set(value) {
this.$store.dispatch('Preferences/General/updateTimeline', {
hideAllAttachments: value
})
}
},
other_launch: {
get() {
return this.$store.state.Preferences.General.general.other.launch
},
set(value) {
this.$store.dispatch('Preferences/General/updateOther', {
launch: value
})
}
}
},
created () {
this.$store.dispatch('Preferences/General/loadGeneral')
.catch(() => {
this.$message({
message: this.$t('message.preferences_load_error'),
type: 'error'
})
created() {
this.$store.dispatch('Preferences/General/loadGeneral').catch(() => {
this.$message({
message: this.$t('message.preferences_load_error'),
type: 'error'
})
})
}
}
</script>

View File

@ -3,7 +3,7 @@ import { Module, MutationTree, ActionTree } from 'vuex'
import { RootState } from '@/store'
import { Sound } from '~/src/types/sound'
import { Timeline } from '~/src/types/timeline'
import { BaseConfig, General } from '~/src/types/preference'
import { BaseConfig, General, Other } from '~/src/types/preference'
export type GeneralState = {
general: General
@ -20,6 +20,9 @@ const state = (): GeneralState => ({
cw: false,
nfsw: false,
hideAllAttachments: false
},
other: {
launch: false
}
},
loading: false
@ -93,7 +96,7 @@ const actions: ActionTree<GeneralState, RootState> = {
return new Promise((resolve, reject) => {
ipcRenderer.once('error-update-preferences', (_, err: Error) => {
ipcRenderer.removeAllListeners('response-update-preferences')
commit('changeLoading', false)
commit(MUTATION_TYPES.CHANGE_LOADING, false)
reject(err)
})
ipcRenderer.once('response-update-preferences', (_, conf: BaseConfig) => {
@ -105,6 +108,34 @@ const actions: ActionTree<GeneralState, RootState> = {
})
ipcRenderer.send('update-preferences', config)
})
},
updateOther: ({ commit, state, dispatch }, other: {}) => {
commit(MUTATION_TYPES.CHANGE_LOADING, true)
const newOther: Other = Object.assign({}, state.general.other, other)
const newGeneral: General = Object.assign({}, state.general, {
other: newOther
})
const config = {
general: newGeneral
}
return new Promise((resolve, reject) => {
ipcRenderer.once('response-change-auto-launch', () => {
ipcRenderer.once('error-update-preferences', (_, err: Error) => {
ipcRenderer.removeAllListeners('response-update-preferences')
commit(MUTATION_TYPES.CHANGE_LOADING, false)
reject(err)
})
ipcRenderer.once('response-update-preferences', (_, conf: BaseConfig) => {
ipcRenderer.removeAllListeners('error-update-preferences')
commit(MUTATION_TYPES.UPDATE_GENERAL, conf.general as General)
commit(MUTATION_TYPES.CHANGE_LOADING, false)
dispatch('App/loadPreferences', null, { root: true })
resolve(conf)
})
ipcRenderer.send('update-preferences', config)
})
ipcRenderer.send('change-auto-launch', newOther.launch)
})
}
}

View File

@ -4,9 +4,14 @@ import { Notify } from '~/src/types/notify'
import { Appearance } from '~/src/types/appearance'
import { Language } from '~/src/types/language'
export type Other = {
launch: boolean
}
export type General = {
sound: Sound
timeline: Timeline
other: Other
}
export type State = {