Cutls's internal commit (merge kPherox's commits)

This commit is contained in:
Cutls 2019-04-27 15:13:30 +09:00
commit 63b8822c05
14 changed files with 439 additions and 1219 deletions

1437
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -20,7 +20,6 @@
}, },
"main": "background.js", "main": "background.js",
"dependencies": { "dependencies": {
"core-js": "^2.6.5",
"megalodon": "^0.6.3", "megalodon": "^0.6.3",
"nedb": "^1.8.0", "nedb": "^1.8.0",
"vue": "^2.6.6", "vue": "^2.6.6",
@ -29,21 +28,20 @@
"devDependencies": { "devDependencies": {
"@types/lodash": "^4.14.123", "@types/lodash": "^4.14.123",
"@types/nedb": "^1.8.7", "@types/nedb": "^1.8.7",
"@vue/cli-plugin-babel": "^3.5.0", "@vue/cli-plugin-eslint": "^3.6.0",
"@vue/cli-plugin-eslint": "^3.5.0",
"@vue/cli-service": "^3.6.0", "@vue/cli-service": "^3.6.0",
"@vue/eslint-config-typescript": "^4.0.0", "@vue/eslint-config-typescript": "^4.0.0",
"babel-eslint": "^10.0.1", "babel-eslint": "^10.0.1",
"csswring": "^7.0.0", "csswring": "^7.0.0",
"electron": "^4.0.0", "electron": "^4.1.5",
"electron-context-menu": "^0.11.0", "electron-context-menu": "^0.11.0",
"electron-icon-builder": "^1.0.0", "electron-icon-builder": "^1.0.0",
"electron-localshortcut": "^3.1.0", "electron-localshortcut": "^3.1.0",
"eslint": "^5.8.0", "eslint": "^5.8.0",
"eslint-plugin-vue": "^5.0.0", "eslint-plugin-vue": "^5.0.0",
"postcss-nested": "^4.1.2", "postcss-nested": "^4.1.2",
"typescript": "^3.2.1", "typescript": "^3.4.5",
"vue-cli-plugin-electron-builder": "^1.2.0", "vue-cli-plugin-electron-builder": "^1.3.0",
"vue-cli-plugin-typescript": "0.0.1", "vue-cli-plugin-typescript": "0.0.1",
"vue-template-compiler": "^2.5.21" "vue-template-compiler": "^2.5.21"
}, },

View File

@ -55,7 +55,7 @@ type UpdateListener = (e: Event, status: Status) => void
TimelineToot TimelineToot
} }
}) })
export default class AddColumn extends Vue { export default class PublicTimeline extends Vue {
public instance: Instance = "" public instance: Instance = ""
public showInput: boolean = true public showInput: boolean = true
public updateListeners: [string, UpdateListener][] = [] public updateListeners: [string, UpdateListener][] = []
@ -105,7 +105,6 @@ export default class AddColumn extends Vue {
ipcRenderer.send("no-auth-timeline", timeline.name) ipcRenderer.send("no-auth-timeline", timeline.name)
} }
public loadTL(timeline: Timeline, statuses: Status[]) { public loadTL(timeline: Timeline, statuses: Status[]) {
timeline.statuses = new Map( timeline.statuses = new Map(
statuses.map((status): [number, Status] => [status.id, status]) statuses.map((status): [number, Status] => [status.id, status])
@ -146,7 +145,7 @@ export default class AddColumn extends Vue {
console.log("Account dialog:" + id) console.log("Account dialog:" + id)
} }
} }
</script>= </script>
<style scoped lang="postcss"> <style scoped lang="postcss">
#timelines { #timelines {

View File

@ -0,0 +1,65 @@
<template>
<div>
<form @submit.prevent="addTL">
<label
v-for="(types,name) in userTimelineTypes"
:key="name"
:class="{selected: name === timelineType}"
>
<input type="radio" :value="name" v-model="timelineType">
{{ types }}
</label>
<BaseButton
type="submit"
class="primary fill"
style="--font-size:.8em;margin-top:1em;"
>Add Column</BaseButton>
</form>
</div>
</template>
<script lang="ts">
import { Component, Prop, Vue } from "vue-property-decorator"
@Component
export default class UserTimeline extends Vue {
@Prop() public username!: string
public timelineType: string = 'home'
public userTimelineTypes: {
[key: string]: string
} = {
home: 'Home Timeline',
notify: 'Notifications',
dm: 'Direct Messages',
local: 'Local Timeline',
fediverse: 'Fediverse Timeline',
integrated: 'Integrated Timeline (Home + Local)',
localPlus: 'Integrated Timeline (Local + Boost + Reply)',
}
public addTL() {
console.log(this.timelineType)
}
}
</script>
<style scoped lang="postcss">
label {
display: block;
line-height: 2em;
margin: 0em;
&:hover {
background-color: gray;
}
&.selected {
background-color: maroon;
}
& > input[type="radio"] {
display: none;
}
}
</style>

20
src/components/Main.vue Normal file
View File

@ -0,0 +1,20 @@
<template>
<div id="main">
<!-- 仮置き -->
<p>Main View</p>
</div>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator'
@Component({
components: {
}
})
export default class Main extends Vue {
}
</script>
<style lang="postcss">
</style>

View File

@ -18,12 +18,22 @@
>Login</BaseButton> >Login</BaseButton>
</form> </form>
</template> </template>
<script lang="ts"> <script lang="ts">
import { ipcRenderer } from "electron" import { ipcRenderer } from "electron"
import { Component, Vue } from "vue-property-decorator" import { Component, Vue } from "vue-property-decorator"
type Instance = string type Instance = string
interface Account {
domain: string
acct: string
avatar: string
avatarStatic: string
accessToken?: string
}
@Component @Component
export default class Auth extends Vue { export default class AccountAuth extends Vue {
public instance: Instance = "" public instance: Instance = ""
public code: string = "" public code: string = ""
public domain: string = "" public domain: string = ""
@ -38,15 +48,15 @@ export default class Auth extends Vue {
ipcRenderer.send(`new-account-setup`, this.instance) ipcRenderer.send(`new-account-setup`, this.instance)
} }
public authCode() { public authCode() {
let code = this.code ipcRenderer.send(`new-account-auth`, this.code, this.instance)
ipcRenderer.send(`new-account-auth`, code, this.instance)
this.code = "" this.code = ""
this.instance = ''
ipcRenderer.once( ipcRenderer.once(
`login-complete`, `login-complete`,
(e: Event) => { (e: Event, account: Account) => {
status="timeline" this.$emit('login-complete', account)
} }
); )
} }
} }
</script> </script>

View File

@ -155,7 +155,7 @@ export default class AddColumn extends Vue {
console.log("Account dialog:" + id); console.log("Account dialog:" + id);
} }
} }
</script>= </script>
<style scoped lang="postcss"> <style scoped lang="postcss">
#timelines { #timelines {

View File

@ -4,16 +4,21 @@
<h1>Welcome to TheDesk</h1> <h1>Welcome to TheDesk</h1>
<BaseButton @click.native="status = 'login'" class="primary fill">{{ loginButton }}</BaseButton> <BaseButton @click.native="status = 'login'" class="primary fill">{{ loginButton }}</BaseButton>
<BaseButton @click.native="status = 'public_timeline'" class="primary">{{ publicTLButton }}</BaseButton> <BaseButton @click.native="status = 'public_timeline'" class="primary">{{ publicTLButton }}</BaseButton>
<BaseButton @click.native="status = 'timeline'" class="primary">{{ TLButton }}</BaseButton>
<BaseOverlay <BaseOverlay
v-show="status !== 'welcome'" v-show="status !== 'welcome'"
@close="status = 'welcome'" @close="status = 'welcome'"
:title="status === 'login' ? loginButton : status === 'timeline' ? TLButton : publicTLButton" :disableClose="status === 'select_timeline'"
:title="status === 'login'
? loginButton
: status === 'public_timeline'
? publicTLButton
: status === 'select_timeline'
? selectTimeline : ''"
> >
<Login v-if="status === 'login'"/> <Login v-if="status === 'login'" @login-complete="loggedIn"/>
<PublicTimeline v-else-if="status === 'public_timeline'"/> <PublicTimeline v-else-if="status === 'public_timeline'"/>
<Timeline v-else-if="status === 'timeline'"/> <UserTimeline v-else-if="status === 'select_timeline'" :username="username"/>
</BaseOverlay> </BaseOverlay>
</div> </div>
</template> </template>
@ -21,26 +26,40 @@
<script lang="ts"> <script lang="ts">
import { Component, Vue } from 'vue-property-decorator' import { Component, Vue } from 'vue-property-decorator'
import Login from './Preference/AccountManager.vue' import Login from './Preferences/AccountAuth.vue'
import Timeline from './Timeline/Timeline.vue' import UserTimeline from './AddColumn/UserTimeline.vue'
import PublicTimeline from './AddColumn/PublicTimeline.vue' import PublicTimeline from './AddColumn/PublicTimeline.vue'
type Status = 'welcome' | 'login' | 'public_timeline' | 'timeline' type Status = 'welcome' | 'login' | 'public_timeline' | 'select_timeline'
interface Account {
domain: string
acct: string
avatar: string
avatarStatic: string
accessToken?: string
}
@Component({ @Component({
components: { components: {
Login, Login,
Timeline, UserTimeline,
PublicTimeline, PublicTimeline,
} }
}) })
export default class Welcome extends Vue { export default class Welcome extends Vue {
public status: Status = 'welcome'
public loginButton: string = 'Login' public loginButton: string = 'Login'
public publicTLButton: string = 'Streaming Public Timeline' public publicTLButton: string = 'Streaming Public Timeline'
public TLButton: string = 'Timeline' public selectTimeline: string = 'Select Timeline'
public username: string = ''
public status: Status = 'welcome'
public loggedIn(account: Account) {
this.username = `@${account.acct}@${account.domain}`
this.status = 'select_timeline'
} }
</script>= }
</script>
<style lang="postcss"> <style lang="postcss">
#welcome { #welcome {

View File

@ -11,7 +11,7 @@ import { Component, Prop, Vue } from 'vue-property-decorator'
inheritAttrs: false, inheritAttrs: false,
}) })
export default class BaseButton extends Vue { export default class BaseButton extends Vue {
@Prop() private type?: string @Prop() public type?: string
} }
</script> </script>

View File

@ -1,7 +1,7 @@
<template> <template>
<transition name="fade"> <transition name="fade">
<div class="overlay"> <div class="overlay">
<button type="button" class="close-button" @click="closeOverlay">X</button> <button type="button" class="close-button" @click="closeOverlay" v-show="!disableClose">X</button>
<h1>{{ title }}</h1> <h1>{{ title }}</h1>
<div class="overlay-inner"> <div class="overlay-inner">
<slot/> <slot/>
@ -19,6 +19,8 @@ import { Component, Prop, Vue } from 'vue-property-decorator'
export default class BaseOverlay extends Vue { export default class BaseOverlay extends Vue {
@Prop() @Prop()
public title?: string public title?: string
@Prop()
public disableClose?: boolean
public closeOverlay() { public closeOverlay() {
this.$emit('close') this.$emit('close')

View File

@ -68,7 +68,7 @@ export default class Auth {
autoload: true autoload: true
}) })
let docs = { let docs = {
domain: url, domain: instance,
acct: you.acct, acct: you.acct,
avatar: you.avatar, avatar: you.avatar,
avatarStatic: you.avatar_static, avatarStatic: you.avatar_static,
@ -82,7 +82,7 @@ export default class Auth {
message: "You cannot login already logined account." message: "You cannot login already logined account."
}) })
} else { } else {
event.sender.send(`login-complete`) event.sender.send(`login-complete`, newDocs)
} }
}) })
}) })

View File

@ -64,8 +64,8 @@ interface TheDeskInfo {
@Component @Component
export default class About extends Vue { export default class About extends Vue {
private thedeskInfo: TheDeskInfo = ipcRenderer.sendSync('thedesk-info') public thedeskInfo!: TheDeskInfo
private isDarkMode: boolean = ipcRenderer.sendSync('dark-theme') public isDarkMode!: boolean
public get ctrHtml(): string { public get ctrHtml(): string {
return this.contributors.map(contributer => { return this.contributors.map(contributer => {
@ -105,13 +105,19 @@ export default class About extends Vue {
} }
} }
beforeDestroy() { created() {
ipcRenderer.eventNames().forEach(name => ipcRenderer.removeAllListeners(name)) this.thedeskInfo = ipcRenderer.sendSync('thedesk-info')
this.isDarkMode = ipcRenderer.sendSync('dark-theme')
} }
mounted() { mounted() {
ipcRenderer.on('change-color-theme', () => this.isDarkMode = ipcRenderer.sendSync('dark-theme')) ipcRenderer.on('change-color-theme', () => this.isDarkMode = ipcRenderer.sendSync('dark-theme'))
} }
beforeDestroy() {
ipcRenderer.eventNames().forEach(name => ipcRenderer.removeAllListeners(name))
}
} }
</script> </script>

View File

@ -1,22 +1,27 @@
<template> <template>
<div id="app" :style="styles"> <div id="app" :style="styles">
<Welcome/> <Welcome v-if="isStartup"/>
<Main v-else/>
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
import { ipcRenderer } from 'electron' import { ipcRenderer } from 'electron'
import { Component, Vue } from 'vue-property-decorator' import { Component, Vue } from 'vue-property-decorator'
import Main from '@/components/Main.vue'
import Welcome from '@/components/Welcome.vue' import Welcome from '@/components/Welcome.vue'
@Component({ @Component({
components: { components: {
Main,
Welcome, Welcome,
}, },
}) })
export default class App extends Vue { export default class App extends Vue {
private isDarkMode: boolean = ipcRenderer.sendSync('dark-theme') public isDarkMode!: boolean
public fontSize: string = '16px' public isStartup!: boolean
public fontSize!: string
public get styles(): { [key: string]: string } { public get styles(): { [key: string]: string } {
return { return {
@ -26,12 +31,22 @@ export default class App extends Vue {
} }
} }
beforeDestroy() { created() {
ipcRenderer.eventNames().forEach(name => ipcRenderer.removeAllListeners(name)) this.isDarkMode = ipcRenderer.sendSync('dark-theme')
this.isStartup = true // TODO: ipcboolean
this.fontSize = '16px'
} }
mounted() { mounted() {
ipcRenderer.on('change-color-theme', () => this.isDarkMode = ipcRenderer.sendSync('dark-theme')) ipcRenderer.on('change-color-theme', () => this.isDarkMode = ipcRenderer.sendSync('dark-theme'))
// TODO: TL
if (this.isStartup) {
//ipcRenderer.once('add-timeline', () => this.isStartup = false)
}
}
beforeDestroy() {
ipcRenderer.eventNames().forEach(name => ipcRenderer.removeAllListeners(name))
} }
} }
</script> </script>

View File

@ -13,7 +13,8 @@
"sourceMap": true, "sourceMap": true,
"baseUrl": ".", "baseUrl": ".",
"types": [ "types": [
"webpack-env" "lodash",
"webpack-env",
], ],
"paths": { "paths": {
"*": [ "*": [
@ -36,7 +37,7 @@
"src/**/*.tsx", "src/**/*.tsx",
"src/**/*.vue", "src/**/*.vue",
"tests/**/*.ts", "tests/**/*.ts",
"tests/**/*.tsx" "tests/**/*.tsx",
], ],
"exclude": [ "exclude": [
"node_modules" "node_modules"