Passed
Push — develop ( f77af9...ea209b )
by Daniel
01:00 queued 10s
created

src/javascript/enhancements/watch2gether.ts   A

Complexity

Total Complexity 14
Complexity/F 2.8

Size

Lines of Code 107
Function Count 5

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 82
dl 0
loc 107
rs 10
c 0
b 0
f 0
wmc 14
mnd 9
bc 9
fnc 5
bpm 1.8
cpm 2.8
noi 0

5 Functions

Rating   Name   Duplication   Size   Complexity  
A watch2gether.ts ➔ addCharCounter 0 19 1
B watch2gether.ts ➔ addAutohideListener 0 20 6
A watch2gether.ts ➔ updateCharCounter 0 17 2
A watch2gether.ts ➔ init 0 20 3
A watch2gether.ts ➔ manipulateChatInput 0 10 2
1
import * as core from '../utils/aniwatchCore';
2
import { v4 as uuidv4 } from 'uuid';
3
import { getGlobalConfiguration, SETTINGS_w2gDisplayCharacterCounter, SETTINGS_w2gAutotoggleHide } from '../configuration/configuration';
4
import { assigned } from '../utils/helpers';
5
import { findPlayerElement } from "../enhancements/anilyr";
6
7
const PLAYER_ID = 'wPlayer';
8
let hidden: boolean;
9
10
export function init(): void {
11
    getGlobalConfiguration().getProperty(SETTINGS_w2gDisplayCharacterCounter, value => {
12
        if (value) {
13
            core.runAfterLoad(() => {
14
                manipulateChatInput();
15
            }, "^/watch2gether/.*$");
16
            core.runAfterLocationChange(() => {
17
                manipulateChatInput();
18
            }, "^/watch2gether/.*$");
19
        }
20
    });
21
    getGlobalConfiguration().getProperty(SETTINGS_w2gAutotoggleHide, value => {
22
        if (value) {
23
            core.runAfterLoad(() => {
24
                addAutohideListener();
25
            }, "^/watch2gether/.*$");
26
            core.runAfterLocationChange(() => {
27
                addAutohideListener();
28
            }, "^/watch2gether/.*$");
29
        }
30
    });
31
}
32
33
function manipulateChatInput(): void {
34
    let textarea = document.querySelector('.chat-input textarea') as HTMLTextAreaElement;
35
36
    // avoid duplicate registration
37
    if (assigned(textarea.dataset.charCounterId)) {
38
        return;
39
    }
40
41
    addCharCounter(textarea);
42
}
43
44
function addCharCounter(textarea: HTMLTextAreaElement): void {
45
    let chatDiv = textarea.parentElement.parentElement; // div with chat input and controls
46
    let controlRow = chatDiv.children[1]; // row with controls
47
    let btn = controlRow.querySelector('button'); // find send button
48
49
    let charCounterSpan = document.createElement('span'); // create span for counter
50
    charCounterSpan.classList.add('awp-w2g-chatCounter');
51
52
    // id and "connection"
53
    let counterId = `awp-${uuidv4()}`
54
    charCounterSpan.id = counterId;
55
    textarea.dataset.charCounterId = counterId;
56
57
    btn.parentElement.insertBefore(charCounterSpan, btn); // and insert in front of the button
58
    updateCharCounter(textarea, charCounterSpan);
59
60
    textarea.addEventListener('keyup', () => {
61
        updateCharCounter(textarea, charCounterSpan)
62
    });
63
}
64
65
function updateCharCounter(textarea: HTMLTextAreaElement, charCounterSpan: HTMLSpanElement): void {
66
    const SHAKE_CLASS = 'awp-w2g-chatCounter-max';
67
68
    let current = textarea.value.length;
69
    let max = textarea.maxLength;
70
71
    charCounterSpan.innerText = `${current} / ${max}`;
72
73
    // animation if at max
74
    if (current >= max && !charCounterSpan.classList.contains(SHAKE_CLASS)) {
75
        charCounterSpan.classList.add(SHAKE_CLASS);
76
77
        // remove css class after animation finished, so it can be restarted again
78
        setTimeout(() => {
79
            charCounterSpan.classList.remove(SHAKE_CLASS);
80
        }, 200);
81
    }
82
}
83
84
function addAutohideListener(): void {
85
    let playerElement = findPlayerElement(PLAYER_ID);
86
    let hideButton: HTMLButtonElement = document.getElementsByClassName('no-margin md-button md-ink-ripple layout-align-center-center layout-row')[0] as HTMLButtonElement;
87
    if (assigned(playerElement) && assigned(hideButton)) {
88
        if (hideButton.textContent.includes('HIDE')) {
89
            hidden = false;
90
        } else if (hideButton.textContent.includes('SHOW')) {
91
            hidden = true;
92
        }
93
        playerElement.addEventListener('play', fn => {
94
            if (!hidden) {
95
                hideButton.click();
96
                hidden = !hidden;
97
            }
98
        })
99
        playerElement.addEventListener('pause', fn => {
100
            if (hidden) {
101
                hideButton.click();
102
                hidden = !hidden;
103
            }
104
        })
105
    }
106
}
107