console state as action/reducer in redux
This commit is contained in:
parent
8593b3f5cd
commit
e8056d2a70
6 changed files with 129 additions and 84 deletions
28
src/actions/console.js
Normal file
28
src/actions/console.js
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
import actions from '../actions';
|
||||||
|
|
||||||
|
export function showCommand(text) {
|
||||||
|
return {
|
||||||
|
type: actions.CONSOLE_SHOW_COMMAND,
|
||||||
|
text: text
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setCompletions(completions) {
|
||||||
|
return {
|
||||||
|
type: actions.CONSOLE_SET_COMPLETIONS,
|
||||||
|
completions: completions
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function showError(text) {
|
||||||
|
return {
|
||||||
|
type: actions.CONSOLE_SHOW_ERROR,
|
||||||
|
text: text
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function hide() {
|
||||||
|
return {
|
||||||
|
type: actions.CONSOLE_HIDE
|
||||||
|
};
|
||||||
|
}
|
6
src/actions/index.js
Normal file
6
src/actions/index.js
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
export default {
|
||||||
|
CONSOLE_SHOW_COMMAND: 'vimvixen.console.show.command',
|
||||||
|
CONSOLE_SET_COMPLETIONS: 'vimvixen.console.set.completions',
|
||||||
|
CONSOLE_SHOW_ERROR: 'vimvixen.console.show.error',
|
||||||
|
CONSOLE_HIDE: 'vimvixen.console.hide'
|
||||||
|
};
|
|
@ -1,4 +1,5 @@
|
||||||
import './console-frame.scss';
|
import './console-frame.scss';
|
||||||
|
import * as consoleActions from '../actions/console';
|
||||||
|
|
||||||
export default class ConsoleFrame {
|
export default class ConsoleFrame {
|
||||||
constructor(win) {
|
constructor(win) {
|
||||||
|
@ -16,26 +17,17 @@ export default class ConsoleFrame {
|
||||||
|
|
||||||
showCommand(text) {
|
showCommand(text) {
|
||||||
this.showFrame();
|
this.showFrame();
|
||||||
|
|
||||||
let message = {
|
|
||||||
type: 'vimvixen.console.show.command',
|
|
||||||
text: text
|
|
||||||
};
|
|
||||||
this.errorShown = false;
|
this.errorShown = false;
|
||||||
return browser.runtime.sendMessage(message);
|
return browser.runtime.sendMessage(consoleActions.showCommand(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
showError(text) {
|
showError(text) {
|
||||||
this.showFrame();
|
this.showFrame();
|
||||||
|
|
||||||
let message = {
|
|
||||||
type: 'vimvixen.console.show.error',
|
|
||||||
text: text
|
|
||||||
};
|
|
||||||
this.errorShown = true;
|
this.errorShown = true;
|
||||||
this.element.blur();
|
this.element.blur();
|
||||||
|
|
||||||
return browser.runtime.sendMessage(message);
|
return browser.runtime.sendMessage(consoleActions.showError(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
showFrame() {
|
showFrame() {
|
||||||
|
@ -46,6 +38,8 @@ export default class ConsoleFrame {
|
||||||
this.element.style.display = 'none';
|
this.element.style.display = 'none';
|
||||||
this.element.blur();
|
this.element.blur();
|
||||||
this.errorShown = false;
|
this.errorShown = false;
|
||||||
|
|
||||||
|
return browser.runtime.sendMessage(consoleActions.hide());
|
||||||
}
|
}
|
||||||
|
|
||||||
isErrorShown() {
|
isErrorShown() {
|
||||||
|
@ -53,9 +47,6 @@ export default class ConsoleFrame {
|
||||||
}
|
}
|
||||||
|
|
||||||
setCompletions(completions) {
|
setCompletions(completions) {
|
||||||
return browser.runtime.sendMessage({
|
return browser.runtime.sendMessage(consoleActions.setCompletions(completions));
|
||||||
type: 'vimvixen.console.set.completions',
|
|
||||||
completions: completions
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
import './console.scss';
|
import './console.scss';
|
||||||
import Completion from './completion';
|
import Completion from './completion';
|
||||||
|
import consoleReducer, { defaultState } from '../reducers/console';
|
||||||
|
|
||||||
// TODO consider object-oriented
|
// TODO consider object-oriented
|
||||||
var prevValue = "";
|
var prevValue = "";
|
||||||
var completion = null;
|
var completion = null;
|
||||||
var completionOrigin = "";
|
var completionOrigin = "";
|
||||||
|
let state = defaultState;
|
||||||
|
|
||||||
const blurMessage = () => {
|
const blurMessage = () => {
|
||||||
return {
|
return {
|
||||||
|
@ -96,38 +98,6 @@ window.addEventListener('load', () => {
|
||||||
input.addEventListener('keyup', handleKeyup);
|
input.addEventListener('keyup', handleKeyup);
|
||||||
});
|
});
|
||||||
|
|
||||||
const showCommand = (text) => {
|
|
||||||
let command = window.document.querySelector('#vimvixen-console-command');
|
|
||||||
command.style.display = 'block';
|
|
||||||
|
|
||||||
let error = window.document.querySelector('#vimvixen-console-error');
|
|
||||||
error.style.display = 'none';
|
|
||||||
|
|
||||||
let input = window.document.querySelector('#vimvixen-console-command-input');
|
|
||||||
input.value = text;
|
|
||||||
input.focus();
|
|
||||||
|
|
||||||
completion = null;
|
|
||||||
let container = window.document.querySelector('#vimvixen-console-completion');
|
|
||||||
container.innerHTML = '';
|
|
||||||
|
|
||||||
return browser.runtime.sendMessage(keyupMessage(input));
|
|
||||||
}
|
|
||||||
|
|
||||||
const showError = (text) => {
|
|
||||||
let error = window.document.querySelector('#vimvixen-console-error');
|
|
||||||
error.textContent = text;
|
|
||||||
error.style.display = 'block';
|
|
||||||
|
|
||||||
let command = window.document.querySelector('#vimvixen-console-command');
|
|
||||||
command.style.display = 'none';
|
|
||||||
|
|
||||||
let completion = window.document.querySelector('#vimvixen-console-completion');
|
|
||||||
completion.style.display = 'none';
|
|
||||||
|
|
||||||
return Promise.resolve();
|
|
||||||
}
|
|
||||||
|
|
||||||
const createCompletionTitle = (text) => {
|
const createCompletionTitle = (text) => {
|
||||||
let li = document.createElement('li');
|
let li = document.createElement('li');
|
||||||
li.className = 'vimvixen-console-completion-title';
|
li.className = 'vimvixen-console-completion-title';
|
||||||
|
@ -152,33 +122,6 @@ const createCompletionItem = (icon, caption, url) => {
|
||||||
return li;
|
return li;
|
||||||
}
|
}
|
||||||
|
|
||||||
const setCompletions = (completions) => {
|
|
||||||
let container = window.document.querySelector('#vimvixen-console-completion');
|
|
||||||
container.style.display = 'block';
|
|
||||||
container.innerHTML = '';
|
|
||||||
|
|
||||||
let pairs = [];
|
|
||||||
|
|
||||||
for (let group of completions) {
|
|
||||||
let title = createCompletionTitle(group.name);
|
|
||||||
container.append(title);
|
|
||||||
|
|
||||||
for (let item of group.items) {
|
|
||||||
let li = createCompletionItem(item.icon, item.caption, item.url);
|
|
||||||
container.append(li);
|
|
||||||
|
|
||||||
pairs.push([item, li]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
completion = new Completion(pairs);
|
|
||||||
|
|
||||||
let input = window.document.querySelector('#vimvixen-console-command-input');
|
|
||||||
completionOrigin = input.value.split(' ')[0];
|
|
||||||
|
|
||||||
return Promise.resolve();
|
|
||||||
}
|
|
||||||
|
|
||||||
const selectCompletion = (target) => {
|
const selectCompletion = (target) => {
|
||||||
let container = window.document.querySelector('#vimvixen-console-completion');
|
let container = window.document.querySelector('#vimvixen-console-completion');
|
||||||
Array.prototype.forEach.call(container.children, (ele) => {
|
Array.prototype.forEach.call(container.children, (ele) => {
|
||||||
|
@ -193,15 +136,54 @@ const selectCompletion = (target) => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const updateCompletions = (completions) => {
|
||||||
|
let completionsContainer = window.document.querySelector('#vimvixen-console-completion');
|
||||||
|
let input = window.document.querySelector('#vimvixen-console-command-input');
|
||||||
|
|
||||||
|
completionsContainer.innerHTML = '';
|
||||||
|
|
||||||
|
let pairs = [];
|
||||||
|
|
||||||
|
for (let group of completions) {
|
||||||
|
let title = createCompletionTitle(group.name);
|
||||||
|
completionsContainer.append(title);
|
||||||
|
|
||||||
|
for (let item of group.items) {
|
||||||
|
let li = createCompletionItem(item.icon, item.caption, item.url);
|
||||||
|
completionsContainer.append(li);
|
||||||
|
|
||||||
|
pairs.push([item, li]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
completion = new Completion(pairs);
|
||||||
|
completionOrigin = input.value.split(' ')[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
const update = (prevState, state) => {
|
||||||
|
let error = window.document.querySelector('#vimvixen-console-error');
|
||||||
|
let command = window.document.querySelector('#vimvixen-console-command');
|
||||||
|
let input = window.document.querySelector('#vimvixen-console-command-input');
|
||||||
|
|
||||||
|
error.style.display = state.errorShown ? 'block' : 'none';
|
||||||
|
error.textContent = state.errorText;
|
||||||
|
|
||||||
|
command.style.display = state.commandShown ? 'block' : 'none';
|
||||||
|
if (!prevState.commandShown && state.commandShown) {
|
||||||
|
// setup input on firstly shown
|
||||||
|
input.value = state.commandText;
|
||||||
|
input.focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (JSON.stringify(state.completions) !== JSON.stringify(prevState.completions)) {
|
||||||
|
updateCompletions(state.completions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
browser.runtime.onMessage.addListener((action) => {
|
browser.runtime.onMessage.addListener((action) => {
|
||||||
switch (action.type) {
|
let nextState = consoleReducer(state, action);
|
||||||
case 'vimvixen.console.show.error':
|
if (JSON.stringify(nextState) !== JSON.stringify(state)) {
|
||||||
return showError(action.text);
|
update(state, nextState);
|
||||||
case 'vimvixen.console.set.completions':
|
state = nextState;
|
||||||
return setCompletions(action.completions);
|
|
||||||
case 'vimvixen.console.show.command':
|
|
||||||
return showCommand(action.text);
|
|
||||||
default:
|
|
||||||
return Promise.resolve();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -6,7 +6,6 @@ import Follow from './follow';
|
||||||
|
|
||||||
let vvConsole = new ConsoleFrame(window);
|
let vvConsole = new ConsoleFrame(window);
|
||||||
|
|
||||||
|
|
||||||
browser.runtime.onMessage.addListener((action) => {
|
browser.runtime.onMessage.addListener((action) => {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case actions.CMD_OPEN:
|
case actions.CMD_OPEN:
|
||||||
|
|
39
src/reducers/console.js
Normal file
39
src/reducers/console.js
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
import actions from '../actions';
|
||||||
|
|
||||||
|
export const defaultState = {
|
||||||
|
errorText: '',
|
||||||
|
errorShown: false,
|
||||||
|
commandText: '',
|
||||||
|
commandShown: false,
|
||||||
|
completions: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function reducer(state = defaultState, action = {}) {
|
||||||
|
switch (action.type) {
|
||||||
|
case actions.CONSOLE_SHOW_COMMAND:
|
||||||
|
return Object.assign({}, state, {
|
||||||
|
commandShown: true,
|
||||||
|
commandText: action.text,
|
||||||
|
errorShow: false,
|
||||||
|
completions: []
|
||||||
|
});
|
||||||
|
case actions.CONSOLE_SET_COMPLETIONS:
|
||||||
|
return Object.assign({}, state, {
|
||||||
|
completions: action.completions
|
||||||
|
});
|
||||||
|
case actions.CONSOLE_SHOW_ERROR:
|
||||||
|
return Object.assign({}, state, {
|
||||||
|
errorText: action.message,
|
||||||
|
errorShow: true,
|
||||||
|
commandShown: false,
|
||||||
|
});
|
||||||
|
case actions.CONSOLE_HIDE:
|
||||||
|
return Object.assign({}, state, {
|
||||||
|
errorShown: false,
|
||||||
|
commandShown: false
|
||||||
|
|
||||||
|
});
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
}
|
Reference in a new issue