diff --git a/src/components/base/settings/general/SettingsGeneral.tsx b/src/components/base/settings/general/SettingsGeneral.tsx
index e06512b..8cd631e 100644
--- a/src/components/base/settings/general/SettingsGeneral.tsx
+++ b/src/components/base/settings/general/SettingsGeneral.tsx
@@ -34,6 +34,10 @@ export default class SettingsGeneral extends Vue {
if (hasQyery) { this.$router.replace({}) }
}
+ changeTheme() {
+ throw Error('Change theme')
+ }
+
render() {
return
@@ -43,9 +47,12 @@ export default class SettingsGeneral extends Vue {
-
+
{ this.$t('settings.reset-settings') }
+
+ { this.$t('settings.change-theme') }
+
}
diff --git a/src/components/themes/agida/index.tsx b/src/components/themes/agida/index.tsx
index 0a90ffa..d0eedba 100644
--- a/src/components/themes/agida/index.tsx
+++ b/src/components/themes/agida/index.tsx
@@ -3,7 +3,8 @@ import { AppModule } from '@/store/app'
import { Wavery } from './lib/wave'
import { Debounce } from '@/utils/helper'
import { changeHsl, hexToRgb, rgbToHsl } from '@/utils/color'
-import { AppInputThemeGeneral } from '@/models/app'
+import { AppInputThemePalette } from '@/models/app'
+import { AgidaTypes } from '@/utils/constant'
export const OPACITY_ARR = [0.265, 0.4, 0.53, 1]
export const topColors = ['#03C79C', '#00A5B2', '#0080A5', '#005A8D']
@@ -20,11 +21,7 @@ export default class AgidaTheme extends Vue {
width: 1200,
segmentCount: 5,
layerCount: 4,
- variance: 1,
- animation: {
- steps: 2,
- time: 40000
- }
+ variance: 1
}
screen = {
@@ -33,7 +30,7 @@ export default class AgidaTheme extends Vue {
}
get palette(): string[] {
- const input = AppModule.getThemeInput('palette') as AppInputThemeGeneral
+ const input = AppModule.getThemeInput('palette') as AppInputThemePalette
const index = input?.value as number || 0
const values = input?.values || ['#00CC99', '#6600FF']
@@ -52,6 +49,10 @@ export default class AgidaTheme extends Vue {
return AppModule.getThemeInput('animation-speed')?.value as number || 40
}
+ get type(): AgidaTypes {
+ return AppModule.getThemeInput('type')?.value as AgidaTypes || 'agida'
+ }
+
get topColors(): string[] {
const initHSL = rgbToHsl(hexToRgb(this.topColor))
const second = changeHsl(initHSL, 10, -3, -5)
@@ -71,13 +72,13 @@ export default class AgidaTheme extends Vue {
}
get bottomActiveColor(): string {
- return this.bottomColor // this.bottomColors[3]
+ return this.bottomColor
}
get knifeSVG(): JSX.Element {
- return
-
-
+ return
+
+
}
@@ -157,14 +158,20 @@ export default class AgidaTheme extends Vue {
}
get yinYangSVG(): JSX.Element {
- return
+ return
}
get activeFragment() {
- return this.agidaSVG
+ const objectMap: Record = {
+ agida: this.agidaSVG,
+ knife: this.knifeSVG,
+ 'yin yang': this.yinYangSVG
+ }
+
+ return objectMap[this.type] || this.agidaSVG
}
get width(): number {
@@ -207,7 +214,6 @@ export default class AgidaTheme extends Vue {
generateWave(type: 'bottom' | 'top') {
const wavery = new Wavery(this.wave)
const waveSvg = wavery.generateSvg()
- console.log('GENERATE WAVE')
const { height, width, xmlns, paths } = waveSvg.svg
const isTop = type === 'top'
diff --git a/src/components/themes/infinity.tsx b/src/components/themes/infinity.tsx
index 14aaaac..ec4cb39 100644
--- a/src/components/themes/infinity.tsx
+++ b/src/components/themes/infinity.tsx
@@ -1,4 +1,4 @@
-import { AppInputThemeGeneral, AppTheme } from '@/models/app'
+import { AppInputThemePalette, AppTheme } from '@/models/app'
import { AppModule } from '@/store/app'
import { Component, Vue } from 'vue-property-decorator'
import { CreateElement } from 'vue/types/umd'
@@ -10,7 +10,7 @@ export default class InfinityTheme extends Vue {
}
get palette() {
- const input = AppModule.getThemeInput('palette') as AppInputThemeGeneral
+ const input = AppModule.getThemeInput('palette') as AppInputThemePalette
const index = input?.value as number || 0
const values = input?.values || []
diff --git a/src/locales/en.json b/src/locales/en.json
index cd50eb7..962dab7 100644
--- a/src/locales/en.json
+++ b/src/locales/en.json
@@ -75,6 +75,7 @@
"general": "General",
"choice-themes": "Choice themes",
"customize-theme": "Customize theme",
+ "change-theme": "Сhange theme",
"reset-settings": "Reset settings",
"login-position": {
"title": "Position",
diff --git a/src/locales/ru.json b/src/locales/ru.json
index d0f0ae9..145f32f 100644
--- a/src/locales/ru.json
+++ b/src/locales/ru.json
@@ -19,7 +19,8 @@
"invert": "Инвертировать",
"brightness": "Яркость",
"random": "Случайно",
- "symmetry": "Симметрия"
+ "symmetry": "Симметрия",
+ "thickness": "Толщина"
},
"text": {
"password": "пароль",
@@ -71,6 +72,7 @@
"choice-themes": "Выбор темы",
"customize-theme": "Настройка темы",
"reset-settings": "Сбросить настройки",
+ "change-theme": "Сменить тему",
"login-position": {
"title": "Положение",
"about": "Выбрать положение логина",
diff --git a/src/models/app.ts b/src/models/app.ts
index deffeb1..375ed8d 100644
--- a/src/models/app.ts
+++ b/src/models/app.ts
@@ -25,8 +25,8 @@ export interface AppThemeSnapshot {
values: Record;
}
-export type AppInputTheme = AppInputThemeGeneral | AppInputThemeSlider | AppInputButton
-export type AppInputThemeType = 'color' | 'slider' | 'checkbox' | 'palette' | 'button'
+export type AppInputTheme = AppInputThemeGeneral | AppInputThemeSlider | AppInputButton | AppInputThemePalette | AppInputThemeSelector
+export type AppInputThemeType = 'color' | 'slider' | 'checkbox' | 'palette' | 'button' | 'selector'
export type AppInputThemeValue = string | boolean | string[] | number
export interface AppInputThemeGeneral {
@@ -34,7 +34,6 @@ export interface AppInputThemeGeneral {
value: AppInputThemeValue;
label: string;
type: AppInputThemeType;
- values?: string[][];
options?: AppInputThemeOptions;
callback?: (value: AppInputThemeValue) => void;
}
@@ -45,6 +44,16 @@ export interface AppInputThemeSlider extends AppInputThemeGeneral {
options: AppInputThemeOptionsSlider;
}
+export interface AppInputThemeSelector extends AppInputThemeGeneral {
+ type: 'selector';
+ values: Readonly;
+}
+
+export interface AppInputThemePalette extends AppInputThemeGeneral {
+ type: 'palette';
+ values: string[][];
+}
+
export interface AppInputButton {
// TODO: "name" and "value" useless property, need to delete them
name: 'button';
diff --git a/src/models/lightdm.ts b/src/models/lightdm.ts
index 147c3ad..3373db7 100644
--- a/src/models/lightdm.ts
+++ b/src/models/lightdm.ts
@@ -1,55 +1,56 @@
-import { Greeter, Signal } from 'nody-greeter-types'
-
-export interface Lightdm {
- can_suspend: boolean;
- can_shutdown: boolean;
- can_restart: boolean;
- can_hibernate: boolean;
- is_authenticated: boolean;
- authentication_user?: string;
- default_session: string;
- sessions: LightdmSession[];
- users: LightdmUsers[];
- languages: LightdmLanguage[];
- language: string;
- has_guest_account: boolean;
- start_authentication(username: string): void;
- authenticate(username: string): void;
- cancel_authentication(): void;
- respond(password: string): void;
- login(user: string, session: string): void;
- shutdown(): void;
- hibernate(): void;
- suspend(): void;
- restart(): void;
-}
-
export interface LightdmUsers {
- display_name: string;
- username: string;
- image?: string;
+ display_name: string
+ username: string
+ image?: string
}
export interface LightdmLanguage {
- name: string;
- code: string;
+ name: string
+ code: string
}
export interface LightdmSession {
- name: string;
- key: string;
- comment?: string;
+ name: string
+ key: string
+ comment?: string
+}
+
+export interface Lightdm {
+ can_suspend: boolean
+ can_shutdown: boolean
+ can_restart: boolean
+ can_hibernate: boolean
+ is_authenticated: boolean
+ authentication_user?: string
+ default_session: string
+ sessions: LightdmSession[]
+ users: LightdmUsers[]
+ languages: LightdmLanguage[]
+ language: string
+ has_guest_account: boolean
+ start_authentication(username: string): void
+ authenticate(username: string): void
+ cancel_authentication(): void
+ respond(password: string): void
+ login(user: string, session: string): void
+ shutdown(): void
+ hibernate(): void
+ suspend(): void
+ restart(): void
}
declare global {
interface Window {
- authentication_complete(): void;
+ authentication_complete(): void
lightdmLogin(
username: string,
password: string,
callback: () => void,
): void;
- show_prompt(text: string, type?: string): void;
- show_message(text: string, type: any): void;
+ show_prompt(text: string, type?: string): void
+ show_message(text: string, type: any): void
+
+ lightdm_start(desktop: string): void;
+ lightdm_cancel_login(): void;
}
}
diff --git a/src/store/app.ts b/src/store/app.ts
index be70501..417eae7 100644
--- a/src/store/app.ts
+++ b/src/store/app.ts
@@ -22,14 +22,18 @@ import { isDifferentRoute, parseQueryValue, randomize, randomizeSettingsTheme }
import { AppThemes, defaultTheme } from '@/utils/constant'
import { version } from '@/../package.json'
import { LightdmHandler } from '@/utils/lightdm'
+import { LightDMBattery } from 'nody-greeter-types'
export interface AppState extends AppSettings {
themes: AppTheme[];
getMainSettings: AppSettings;
activeTheme: AppTheme;
+ battery?: LightDMBattery;
+ brightness?: number;
username: string;
desktops: LightdmSession[];
users: LightdmUsers[];
+ SET_STATE_APP: ({ key, value }: { key: K; value: S[K] }) => void
}
@Module({ dynamic: true, store, name: 'app' })
@@ -38,9 +42,11 @@ class App extends VuexModule implements AppState {
currentTheme = ''
currentOs = 'arch-linux'
desktop = LightdmHandler.defaultSession
- username = LightdmHandler?.username
+ username = LightdmHandler.username
password = ''
defaultColor = '#6BBBED'
+ battery?: LightDMBattery = undefined
+ brightness = 0
users = LightdmHandler?.users
desktops = LightdmHandler?.sessions
@@ -55,8 +61,16 @@ class App extends VuexModule implements AppState {
'only-ui': false
}
- get isAdvancedGreeted() {
- return LightdmHandler.isNode
+ get isCharging() {
+ return this.battery?.status === 'Charging'
+ }
+
+ get batteryLevel() {
+ return this.battery?.level || 0
+ }
+
+ get isSupportFullApi() {
+ return LightdmHandler.isSupportFullApi
}
// TODO: replace this on localStorageSettings
diff --git a/src/style/components/bar.styl b/src/style/components/bar.styl
new file mode 100644
index 0000000..7caf60a
--- /dev/null
+++ b/src/style/components/bar.styl
@@ -0,0 +1,64 @@
+.app-bar
+ --icon-size: 24px
+ position absolute
+ top 0
+ left 0
+ width 100%
+ font-size 0.875rem
+ background var(--background-block)
+ display flex
+ justify-content center
+ height var(--height-bar)
+ align-items center
+ padding 0 var(--gap)
+
+.app-bar__info
+ display flex
+ gap var(--gap)
+ position absolute
+ right var(--gap)
+
+.app-bar-battery
+ display flex
+ align-items center
+
+.app-bar-battery-icon
+ position relative
+ width var(--icon-size)
+ height calc(var(--icon-size) / 2)
+ border calc(var(--icon-size) / 40) white solid
+ border-radius calc(var(--icon-size) / 9)
+ margin-right calc(var(--gap) / 2)
+ &::before
+ content ''
+ display block
+ top 50%
+ right 0px
+ background white
+ position absolute
+ border-radius 0 calc(var(--icon-size) / 30) calc(var(--icon-size) / 30) 0
+ width calc(var(--icon-size) / 10)
+ height calc(var(--icon-size) / 5)
+ transform translate(100%, -50%)
+
+.app-bar-battery-icon__fill
+ max-width 100%
+ height 100%
+ background var(--color-unfocus)
+ &.charging
+ background var(--color-green)
+
+.app-bar-battery-icon__charge
+ width 80%
+ position absolute
+ top 50%
+ left 50%
+ transform translate(-50%, -50%)
+
+.app-bar__bright
+ gap calc(var(--gap) / 2)
+ display flex
+ align-items center
+
+.brightness-icon
+ width 1.1rem
\ No newline at end of file
diff --git a/src/style/components/index.styl b/src/style/components/index.styl
index 9048bec..e2646cc 100644
--- a/src/style/components/index.styl
+++ b/src/style/components/index.styl
@@ -1,3 +1,4 @@
+@import './bar.styl'
@import './menu.styl'
@import './login.styl'
@import './dialog.styl'
@@ -20,12 +21,12 @@
justify-content center
.frame-rate-block
- top 0
- right 0
+ top calc(var(--gap) + var(--height-bar))
+ right var(--gap)
color white
font-size 1.1rem
- padding 6px 12px
+ padding calc(var(--gap) / 2) var(--gap)
z-index 10
position absolute
background var(--background-block)
- border-radius 0 0 0 10px
\ No newline at end of file
+ border-radius var(--gap)
\ No newline at end of file
diff --git a/src/style/components/login.styl b/src/style/components/login.styl
index 2c65f8d..6bcd659 100644
--- a/src/style/components/login.styl
+++ b/src/style/components/login.styl
@@ -19,7 +19,7 @@
&.login-view--center
transform translate(calc(100vw / 2 - 50%), calc(100vh / 2 - 50%))
&.login-view--top
- transform translate(calc(100vw / 2 - 50%), 12px)
+ transform translate(calc(100vw / 2 - 50%), calc(var(--gap) + var(--height-bar)))
&.login-view--right
transform translate(calc(100vw - 100% - 12px), calc(100vh / 2 - 50%))
&.login-view--bottom
@@ -58,12 +58,10 @@
width 60px
height 60px
margin 0
- .time
- position absolute
- transform translate(74px, 32px)
.user-name
margin 8px 12px
-
+ display flex
+ align-items center
.user-choice
width 100%
@@ -72,6 +70,10 @@
height 50px
.time
+ position absolute
+ top 0
+ left 50%
+ transform translateX(-50%)
text-align center
color var(--color-unfocus)
font-size 0.95rem
@@ -82,7 +84,7 @@
height 100px
display block
transition .3s
- margin auto
+ margin 24px auto 0
background-repeat no-repeat
background-size cover
background-position center
diff --git a/src/style/components/selector.styl b/src/style/components/selector.styl
index 9b5b1de..6522a29 100644
--- a/src/style/components/selector.styl
+++ b/src/style/components/selector.styl
@@ -1,6 +1,7 @@
.selector
padding 4px 8px
border-radius 4px
+ max-height 36px
border 1px solid var(--color-unfocus)
color var(--color-unfocus)
display flex
diff --git a/src/style/components/slider.styl b/src/style/components/slider.styl
index 7f7fc46..a0c7d98 100644
--- a/src/style/components/slider.styl
+++ b/src/style/components/slider.styl
@@ -86,7 +86,7 @@
left auto
right 0
height 0
- width 10%
+ width 100%
.app-slider__content
white-space nowrap
diff --git a/src/style/index.styl b/src/style/index.styl
index 03d300a..ba2ad22 100644
--- a/src/style/index.styl
+++ b/src/style/index.styl
@@ -12,8 +12,9 @@
--color-blue #04ded4
--color-unfocus rgba(255, 255, 255, .5)
--color-focus white
- --login-height: 14vmin
--background-block: rgba(0,0,0,0.45)
+ --gap: 12px
+ --height-bar: 36px
font-size 16px
::-webkit-scrollbar
@@ -37,3 +38,19 @@
animation-iteration-count 1 !important
transition-duration 0.01ms !important
scroll-behavior auto !important
+
+
+// @media screen and (-moz-min-device-pixel-ratio: 2),
+// screen and (-o-min-device-pixel-ratio: 2/1),
+// screen and (-webkit-min-device-pixel-ratio: 2),
+// screen and (min-device-pixel-ratio: 2)
+// body
+// zoom 2
+
+// @media screen and (-webkit-min-device-pixel-ratio: 2)
+// body
+// zoom 2
+
+@media screen and (min-width: 3000px) and (min-height: 1200px)
+ body
+ zoom 2
diff --git a/src/style/setup.styl b/src/style/setup.styl
index 0c29c0d..f1c4e96 100644
--- a/src/style/setup.styl
+++ b/src/style/setup.styl
@@ -86,10 +86,6 @@ img:not([alt])
transition-duration 0.01ms !important
scroll-behavior auto !important
-@media (resolution >= 2dppx)
- body
- zoom 2
-
section
position relative
box-sizing border-box
diff --git a/src/utils/constant.ts b/src/utils/constant.ts
index e3b4671..5cbf9ab 100644
--- a/src/utils/constant.ts
+++ b/src/utils/constant.ts
@@ -31,6 +31,9 @@ export const defaultTheme: AppTheme = {
]
}
+const AGIDA_TYPES = ['agida', 'knife', 'yin yang'] as const
+export type AgidaTypes = typeof AGIDA_TYPES[number]
+
export const AppThemes: AppTheme[] = [
{
name: 'Agida',
@@ -55,6 +58,13 @@ export const AppThemes: AppTheme[] = [
['#fc5185', '#3fc1c9'],
['#f5f5f5', '#364f6b']
]
+ },
+ {
+ name: 'type',
+ label: 'type',
+ type: 'selector',
+ value: 'agida',
+ values: AGIDA_TYPES
}
]
},
diff --git a/src/utils/helper.ts b/src/utils/helper.ts
index f32f54b..2444261 100644
--- a/src/utils/helper.ts
+++ b/src/utils/helper.ts
@@ -1,4 +1,4 @@
-import { AppInputButton, AppInputThemeGeneral, AppInputThemeSlider, AppInputThemeValue, AppTheme } from '@/models/app'
+import { AppInputButton, AppInputThemeGeneral, AppInputThemePalette, AppInputThemeSlider, AppInputThemeValue, AppTheme } from '@/models/app'
import { AppModule } from '@/store/app'
import { PageModule } from '@/store/page'
import { debounce, DebounceSettings } from 'lodash'
@@ -6,7 +6,6 @@ import { RawLocation } from 'vue-router'
import router from '../router'
import { LightdmHandler } from '@/utils/lightdm'
-const isFinalBuild = process.env.VUE_APP_VIEW === 'build'
export const modKey = 'ctrl'
export const languageMap: Record = {
ru: 'Русский',
@@ -162,18 +161,18 @@ export function hasSomeParentClass(element: HTMLElement, tag: string): boolean {
}
export function randomizeSettingsTheme(theme: AppTheme) {
- const generateValueObject: Record AppInputThemeValue> = {
+ const generateValueObject: Record any> = {
slider: (input: AppInputThemeSlider) => generateRandomSliderValue(input),
checkbox: () => Math.random() > 0.5,
color: () => generateRandomColor(),
- palette: (input: AppInputThemeGeneral) => Math.floor(randomize(0, (input.values?.length || 2) - 1))
+ palette: (input: AppInputThemePalette) => Math.floor(randomize(0, (input.values?.length || 2) - 1))
}
return theme.settings?.map(input => {
const changeValueFunction = generateValueObject[input.type]
if (changeValueFunction) {
- input.value = changeValueFunction(input as AppInputThemeSlider)
+ input.value = changeValueFunction(input)
}
return input
diff --git a/src/utils/lightdm.ts b/src/utils/lightdm.ts
index 3e90ef0..28c9c33 100644
--- a/src/utils/lightdm.ts
+++ b/src/utils/lightdm.ts
@@ -1,19 +1,68 @@
-import { Lightdm } from '@/models/lightdm'
-import { Greeter } from 'nody-greeter-types'
+import { AppState } from '@/store/app'
+
+/**
+ * INFO: To avoid recoursive requires modules (lightdm and AppModule)
+ * @returns AppState
+ */
+async function getAppModule(): Promise {
+ const module = await import('@/store/app') as any
+ return module.AppModule
+}
const DEBUG_PASSWORD = 'password'
const lightdmDebug = window.lightdm === undefined
-const localLight = window.lightdm as unknown as Lightdm
+
+function setIsAuthenticated(value: boolean) {
+ (window.lightdm as any).is_authenticated = value
+}
if (lightdmDebug) {
window.lightdm = {
is_authenticated: false,
authentication_user: undefined,
default_session: 'plasma-shell',
+ can_access_battery: true,
+ can_access_brightness: true,
can_suspend: true,
can_restart: true,
can_hibernate: true,
can_shutdown: true,
+
+ battery_data: {
+ level: Math.ceil(Math.random() * 99 + 1),
+ ac_status: true
+ },
+ brightness: Math.ceil(Math.random() * 99 + 1),
+
+ battery_update: {
+ _callbacks: [],
+ _emit: () => {
+ window.lightdm?.battery_update._callbacks.forEach((cb) => cb())
+ },
+ connect: (callback: () => void) => {
+ window.lightdm?.battery_update._callbacks.push(callback)
+ }
+ },
+ authentication_complete: {
+ _callbacks: [],
+ _emit: () => {
+ console.log(window.lightdm?.authentication_complete._callbacks)
+ window.lightdm?.authentication_complete._callbacks.forEach((cb) => cb())
+ },
+ connect: (callback: () => void) => {
+ window.lightdm?.authentication_complete._callbacks.push(callback)
+ }
+ },
+ brightness_update: {
+ _callbacks: [],
+ _emit: () => {
+ window.lightdm?.brightness_update._callbacks.forEach((cb) => cb())
+ },
+ connect: (callback: () => void) => {
+ window.lightdm?.brightness_update._callbacks.push(callback)
+ }
+ },
+
sessions: [
{
name: 'i3wm',
@@ -60,39 +109,48 @@ if (lightdmDebug) {
}
],
languages: [
- {
- name: 'American English',
- code: 'en_US.utf8'
- },
{
name: 'Русский',
code: 'ru_RU.utf8'
+ },
+ {
+ name: 'American English',
+ code: 'en_US.utf8'
}
],
- language: 'American English',
+ language: { code: 'en_US', name: 'American English' },
+
start_authentication: (username: string) => {
console.log(`Starting authenticating here: '${username}'`)
const inputNode = document.getElementById('password') as HTMLInputElement
- localLight.respond(inputNode?.value || '')
+ window.lightdm?.respond(inputNode?.value || '')
},
authenticate: (username: string) => {
+ const inputNode = document.getElementById('password') as HTMLInputElement
console.log(`Starting authenticating user: '${username}'`)
+
+ if (window.lightdm) {
+ (window.lightdm as any).authentication_user = username
+ }
+
+ window.lightdm?.respond(inputNode?.value || '')
},
cancel_authentication: () => {
console.log('Auth cancelled')
},
+ start_session(session: string) {
+ alert(`Start session: ${session}`)
+ },
respond: (password: string) => {
console.log(`Password provided : '${password}'`)
if (password === DEBUG_PASSWORD) {
- localLight.is_authenticated = true
+ setIsAuthenticated(true)
+ } else {
+ setIsAuthenticated(false)
}
-
- window.authentication_complete()
- },
- login(user: string, session: string) {
- alert(`Logged with '${user}' (Session: '${session}') !`)
+ window.lightdm?.authentication_complete._emit()
},
shutdown() {
alert('(DEBUG: System is shutting down)')
@@ -109,21 +167,17 @@ if (lightdmDebug) {
} as any
}
-const isNode = 'batteryData' in (window.lightdm || {})
+const isSupportFullApi = 'battery_data' in (window.lightdm || {})
class LightdmWebkit {
protected _inputErrorTimer!: null | NodeJS.Timeout
- // get session() {
- // return ''
- // }
-
get defaultSession() {
return this.sessions[0]?.key || window.lightdm?.default_session || 'i3'
}
- get isNode() {
- return isNode
+ get isSupportFullApi() {
+ return isSupportFullApi
}
get sessions() {
@@ -195,96 +249,50 @@ class LightdmWebkit {
}
}
-class LightdmPython extends LightdmWebkit {
- private _password = ''
- private _completeCallback!: () => void
-
- constructor() {
- super()
- this.init()
- }
-
- get light() {
- return window.lightdm as unknown as Lightdm
- }
-
- public login(username: string, password: string, session?: string): void {
- this.lightdmLogin(username, password, () => this.lightdmStart(session || this.defaultSession))
- }
-
- private lightdmStart(session: string): void {
- this.light.login(this.light.authentication_user || '', session)
- }
-
- private lightdmLogin(username: string, password: string, callback: () => void) {
- this._completeCallback = callback
- this._password = password
-
- this.light.start_authentication(username)
- }
-
- private init() {
- window.authentication_complete = () => {
- if (window.lightdm?.is_authenticated && this._completeCallback) {
- this._completeCallback()
- } else {
- this.light.cancel_authentication()
- this._setInputError()
- }
- }
-
- window.show_message = (text) => {
- alert(text)
- }
-
- window.show_prompt = (text) => {
- if (text === 'Password: ') {
- if (window.lightdm) {
- window.lightdm.respond(this._password)
- }
- }
- }
- }
-}
-
class LightdmNode extends LightdmWebkit {
- private _username!: string
- private _password!: string
- private _session!: undefined | string
+ public _username!: string
+ public _password!: string
+ public _session!: string
constructor() {
super()
this.init()
}
- get light() {
- return window.lightdm as Greeter
- }
-
public login(username: string, password: string, session?: string): void {
this._username = username
this._password = password
- this._session = session
+ this._session = session || this.defaultSession
- this.light.authenticate(null)
+ window.lightdm?.authenticate(username)
}
public setAuthenticationDone(): void {
- this.light.authentication_complete.connect(() => {
- if (this.light.is_authenticated) {
- this.light.start_session(this._session || this.light.default_session)
+ window.lightdm?.authentication_complete?.connect(() => {
+ if (window.lightdm?.is_authenticated) {
+ window.lightdm?.start_session(this._session || window.lightdm?.default_session)
} else {
this._authenticationFailed()
}
})
+
+ window.lightdm_cancel_login = () => {
+ window.lightdm?.cancel_authentication()
+ }
}
- public _authenticationFailed(): void {
- this.light.cancel_authentication()
+ private _authenticationFailed(): void {
+ this._setInputError()
+ window.lightdm?.cancel_authentication()
}
public setSignalHandler(): void {
- this.light.show_prompt.connect((_message, type) => {
+ window.lightdm?.show_message?.connect(function(text, type) {
+ console.log({ text, type })
+ })
+
+ window.lightdm?.show_prompt?.connect((_message, type) => {
+ console.log({ _message, type })
if (!window.lightdm) return
if (type === 0) {
window.lightdm.respond(this._username)
@@ -292,6 +300,26 @@ class LightdmNode extends LightdmWebkit {
window.lightdm.respond(this._password)
}
})
+
+ if (window.lightdm?.can_access_brightness) {
+ this.updateBrightData()
+ window.lightdm?.brightness_update.connect(this.updateBrightData)
+ }
+
+ if (window.lightdm?.can_access_battery) {
+ this.updateBatteryData()
+ window.lightdm?.battery_update.connect(this.updateBatteryData)
+ }
+ }
+
+ public async updateBatteryData(): Promise {
+ const module = await getAppModule()
+ module.SET_STATE_APP({ key: 'battery', value: window.lightdm?.battery_data })
+ }
+
+ public async updateBrightData(): Promise {
+ const module = await getAppModule()
+ module.SET_STATE_APP({ key: 'brightness', value: window.lightdm?.brightness })
}
public init(): void {
@@ -300,4 +328,26 @@ class LightdmNode extends LightdmWebkit {
}
}
-export const LightdmHandler = isNode ? new LightdmNode() : new LightdmPython()
+export const LightdmHandler = new LightdmNode()
+
+window.lightdm_cancel_login = () => {
+ window.lightdm?.cancel_authentication()
+}
+
+window.lightdm_start = (desktop: string) => {
+ window.lightdm?.start_session(desktop)
+}
+
+window.show_prompt = (text, type) => {
+ if (text === 'Password: ' && LightdmHandler._password !== undefined) {
+ window.lightdm?.respond(LightdmHandler._password)
+ }
+}
+
+window.authentication_complete = () => {
+ if (window.lightdm?.is_authenticated) {
+ window.lightdm_start(LightdmHandler._session)
+ } else if (document.head.dataset.wintype === 'primary') {
+ window.lightdm?.cancel_authentication()
+ }
+}
diff --git a/src/utils/time.ts b/src/utils/time.ts
new file mode 100644
index 0000000..b242373
--- /dev/null
+++ b/src/utils/time.ts
@@ -0,0 +1,41 @@
+import { PageModule } from '@/store/page'
+import Vue from 'vue'
+import { DateTimeFormatOptions } from 'vue-i18n'
+
+const timeRef = Vue.observable({
+ time: new Date(),
+ shortTime: '',
+ longTime: ''
+})
+
+const formatTime = (type: 'long' | 'short' = 'short') => {
+ const options: DateTimeFormatOptions = {
+ month: 'short',
+ day: 'numeric',
+ hour: 'numeric',
+ minute: 'numeric',
+ hour12: false
+ }
+
+ if (type === 'long') {
+ options.month = 'long'
+ options.weekday = 'long'
+ }
+
+ return new Intl.DateTimeFormat(PageModule.locale, options).format(new Date())
+}
+
+export const initTimer = () => {
+ setInterval(updateTime, 1000)
+}
+
+const updateTime = () => {
+ timeRef.time = new Date()
+
+ timeRef.shortTime = formatTime('short')
+ timeRef.longTime = formatTime('long')
+}
+
+updateTime()
+
+export default timeRef
diff --git a/src/views/Home.tsx b/src/views/Home.tsx
index 3f3c065..602a25b 100644
--- a/src/views/Home.tsx
+++ b/src/views/Home.tsx
@@ -4,6 +4,7 @@ import { LoginPosition } from '@/models/page'
import { AppModule } from '@/store/app'
import { PageModule } from '@/store/page'
+import AppBar from '@/components/app/AppBar'
import AppMenu from '@/components/app/AppMenu'
import AppDialog from '@/components/app/AppDialog'
import SettingsComponent from '@/components/base/SettingsComponent'
@@ -66,6 +67,10 @@ export default class HomePage extends Vue {
return !this.isViewThemeOnly && this.isOpenLogin
}
+ get isSupportFullApi() {
+ return AppModule.isSupportFullApi
+ }
+
created() {
// Set language
const language = localStorage.getItem('language') || 'en'
@@ -112,6 +117,7 @@ export default class HomePage extends Vue {
{ !this.isViewThemeOnly && }
{ this.showGithubButton && }
+ { this.isSupportFullApi && }
diff --git a/test-greeter.sh b/test-greeter.sh
index f3690de..258277d 100755
--- a/test-greeter.sh
+++ b/test-greeter.sh
@@ -1,5 +1,6 @@
#!/bin/bash
-dm-tool add-nested-seat --screen 1366x768
+lightdm-webkit2-greeter
+# dm-tool add-nested-seat --screen 1366x768
-# nody-greeter --debug
+# yarn build && sudo sh ./install.sh && nody-greeter --debug