~sirn/fanboi2

ref: 5b482cfc1bfb0bb1e89715cb57c7bac864391768 fanboi2/assets/app/javascripts/components/theme_selector.ts -rw-r--r-- 1.7 KiB
5b482cfcKridsada Thanabulpong 0.30.0 3 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import Cookies = require('js-cookie');
import {VNode, create, diff, patch, h} from 'virtual-dom';
import {SingletonComponent} from './base';
import {ThemeSelectorView, ITheme} from '../views/theme_selector_view';


export class Theme implements ITheme {
    className: string;
    constructor(public identifier: string, public name: string) {}
}


const themes = [
    new Theme('topaz', 'Topaz'),
    new Theme('obsidian', 'Obsidian'),
    new Theme('debug', 'Debug'),
];


export class ThemeSelector extends SingletonComponent {
    public targetSelector = '[data-theme-selector]';

    protected bindOne($target: Element) {
        let selectorView = new ThemeSelectorView(themes);
        let selectorNode = selectorView.render(
            document.body.className.replace(/theme-/, '')
        );

        let $selector = create(selectorNode);

        $target.appendChild($selector);
        $target.addEventListener('click', (e: Event) => {
            let $click = e.target;

            if (
                $click instanceof Element &&
                $click.matches('[data-theme-selector-item]')
            ) {
                let themeId = $click.getAttribute('data-theme-selector-item');

                e.preventDefault();

                if (themeId) {
                  let viewNode = selectorView.render(themeId);
                  let patches = diff(selectorNode, viewNode);

                  $selector = patch($selector, patches);
                  selectorNode = viewNode;

                  document.body.className = `theme-${themeId}`;
                  Cookies.set('_theme', themeId, {
                      expires: 365,
                      path: '/'
                  });
                }
            }
        });
    }
}