mirror of
https://github.com/anticensority/runet-censorship-bypass.git
synced 2024-11-28 04:13:43 +03:00
Show error and status in PUP
This commit is contained in:
parent
94bbb92764
commit
82a2994dcc
|
@ -3,28 +3,152 @@ import Component from 'inferno-component';
|
||||||
import createElement from 'inferno-create-element';
|
import createElement from 'inferno-create-element';
|
||||||
|
|
||||||
import getNotControlledWarning from './NotControlledWarning';
|
import getNotControlledWarning from './NotControlledWarning';
|
||||||
import getTabPannel from './TabPannel';
|
import getTabPanel from './TabPanel';
|
||||||
import getPacChooser from './PacChooser';
|
import getPacChooser from './PacChooser';
|
||||||
|
|
||||||
import getFooter from './Footer';
|
import getFooter from './Footer';
|
||||||
|
|
||||||
export default function getApp(theState) {
|
export default function getApp(theState) {
|
||||||
|
|
||||||
|
const NotControlledWarning = getNotControlledWarning(theState);
|
||||||
|
const TabPanel = getTabPanel(theState);
|
||||||
|
const PacChooser = getPacChooser(theState);
|
||||||
|
const Footer = getFooter(theState);
|
||||||
|
|
||||||
return class App extends Component {
|
return class App extends Component {
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
status: 'Загрузка...',
|
||||||
|
areInputsDisabled: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
|
||||||
|
this.showErrors({ message: 'PANIC!' });
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
setStatusTo(msg) {
|
||||||
|
|
||||||
|
this.setState(
|
||||||
|
{
|
||||||
|
status: msg,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
showErrors(err, ...warns) {
|
||||||
|
|
||||||
|
const warningHtml = warns
|
||||||
|
.map(
|
||||||
|
(w) => w && w.messageHtml || ''
|
||||||
|
)
|
||||||
|
.filter( (m) => m )
|
||||||
|
.map( (m) => '✘ ' + m )
|
||||||
|
.join('<br/>');
|
||||||
|
|
||||||
|
let messageHtml = '';
|
||||||
|
if (err) {
|
||||||
|
let wrapped = err.wrapped;
|
||||||
|
messageHtml = err.message || '';
|
||||||
|
|
||||||
|
while( wrapped ) {
|
||||||
|
const deeperMsg = wrapped && wrapped.message;
|
||||||
|
if (deeperMsg) {
|
||||||
|
messageHtml = messageHtml + ' > ' + deeperMsg;
|
||||||
|
}
|
||||||
|
wrapped = wrapped.wrapped;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
messageHtml = messageHtml.trim();
|
||||||
|
if (warningHtml) {
|
||||||
|
messageHtml = messageHtml ? messageHtml + '<br/>' + warningHtml : warningHtml;
|
||||||
|
}
|
||||||
|
this.setStatusTo(
|
||||||
|
(<span>
|
||||||
|
<span style="color:red">
|
||||||
|
{err ? <span><span class="emoji">🔥</span> Ошибка!</span> : 'Некритичная oшибка.'}
|
||||||
|
</span>
|
||||||
|
<br/>
|
||||||
|
<span style="font-size: 0.9em; color: darkred" dangerouslySetInnerHTML={{__html: messageHtml}}></span>
|
||||||
|
{err && <a href="" onClick={(evt) => {
|
||||||
|
|
||||||
|
this.props.apis.errorHandlers.viewError('pup-ext-err', err);
|
||||||
|
evt.preventDefault();
|
||||||
|
|
||||||
|
}}> [Техн.детали]</a>}
|
||||||
|
</span>)
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
switchInputs(val) {
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
areInputsDisabled: val === 'off' ? true : false,
|
||||||
|
});
|
||||||
|
/*
|
||||||
|
const inputs = document.querySelectorAll('input');
|
||||||
|
for ( let i = 0; i < inputs.length; i++ ) {
|
||||||
|
const input = inputs[i];
|
||||||
|
if (val === 'off') {
|
||||||
|
input.dataset.previousDisabledValue = input.disabled;
|
||||||
|
input.disabled = true;
|
||||||
|
} else {
|
||||||
|
input.disabled = input.dataset.previousDisabledValue === 'true';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
conduct(
|
||||||
|
beforeStatus, operation, afterStatus,
|
||||||
|
onSuccess = () => {}, onError = () => {}
|
||||||
|
) {
|
||||||
|
|
||||||
|
this.setStatusTo(beforeStatus);
|
||||||
|
this.switchInputs('off');
|
||||||
|
operation((err, res, ...warns) => {
|
||||||
|
|
||||||
|
warns = warns.filter( (w) => w );
|
||||||
|
if (err || warns.length) {
|
||||||
|
showErrors(err, ...warns);
|
||||||
|
} else {
|
||||||
|
this.setStatusTo(afterStatus);
|
||||||
|
}
|
||||||
|
this.switchInputs('on');
|
||||||
|
if (!err) {
|
||||||
|
onSuccess(res);
|
||||||
|
} else {
|
||||||
|
onError(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
render(props) {
|
render(props) {
|
||||||
|
|
||||||
return createElement('div', {
|
props = Object.assign({}, props, {
|
||||||
onClick: () => console.log('DDDDDCLICK'),
|
funs: {
|
||||||
onDick: () => console.log('DICK!'),
|
setStatusTo: this.setStatusTo,
|
||||||
ondick: () => console.log('dddDICK!'),
|
conduct: this.conduct,
|
||||||
}, [
|
},
|
||||||
createElement(getNotControlledWarning(theState), props),
|
});
|
||||||
createElement(getTabPannel(theState), {
|
|
||||||
|
return createElement('div', null, [
|
||||||
|
createElement(NotControlledWarning, props),
|
||||||
|
createElement(TabPanel, {
|
||||||
tabs:[
|
tabs:[
|
||||||
{
|
{
|
||||||
label: 'PAC-скрипт',
|
label: 'PAC-скрипт',
|
||||||
content: createElement(getPacChooser(theState), props),
|
content: createElement(PacChooser, props),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Исключения',
|
label: 'Исключения',
|
||||||
|
@ -44,7 +168,7 @@ export default function getApp(theState) {
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}),
|
}),
|
||||||
createElement(getFooter(theState), props),
|
createElement(Footer, Object.assign({ status: this.state.status }, props)),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,24 +6,24 @@ export default function getFooter() {
|
||||||
|
|
||||||
const scopedCss = css`
|
const scopedCss = css`
|
||||||
|
|
||||||
#statusRow {
|
.statusRow {
|
||||||
padding: 0 0.3em 1em;
|
padding: 0 0.3em 1em;
|
||||||
}
|
}
|
||||||
#status {
|
.status {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.controlRow {
|
.controlRow {
|
||||||
margin: 1em 0 1em 0;
|
margin: 1em 0 1em 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
return function (props) {
|
return function (props) {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class="horPadded">
|
<div class="horPadded">
|
||||||
<section id="statusRow">
|
<section class={scopedCss.statusRow}>
|
||||||
<div id="status" style="will-change: contents">{props.status}</div>
|
<div clss={scopedCss.status} style="will-change: contents">{props.status}</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<footer class={scopedCss.controlRow + ' horFlex nowrap'}>
|
<footer class={scopedCss.controlRow + ' horFlex nowrap'}>
|
||||||
|
|
|
@ -98,12 +98,11 @@ export default function getInfoRow() {
|
||||||
|
|
||||||
render(props) {
|
render(props) {
|
||||||
|
|
||||||
// Object.assign is left-associative, let's make it right.
|
props = Object.assign({}, {
|
||||||
Object.assign(props, Object.assign({
|
|
||||||
idPrefix: '',
|
idPrefix: '',
|
||||||
ifDashify: false,
|
ifDashify: false,
|
||||||
htmlAfterLabel: '',
|
htmlAfterLabel: '',
|
||||||
}, props));
|
}, props);
|
||||||
|
|
||||||
const iddy = props.idPrefix + ( props.ifDashify ? camelToDash(props.conf.key) : props.conf.key );
|
const iddy = props.idPrefix + ( props.ifDashify ? camelToDash(props.conf.key) : props.conf.key );
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import Inferno from 'inferno';
|
import Inferno from 'inferno';
|
||||||
import Component from 'inferno-component';
|
import Component from 'inferno-component';
|
||||||
|
import createElement from 'inferno-create-element';
|
||||||
import css from 'csjs-inject';
|
import css from 'csjs-inject';
|
||||||
|
|
||||||
import getInfoLi from './InfoLi';
|
import getInfoLi from './InfoLi';
|
||||||
|
@ -103,55 +104,48 @@ export default function getPacChooser(...args) {
|
||||||
|
|
||||||
render(props) {
|
render(props) {
|
||||||
|
|
||||||
const date = this.getDate(props.antiCensorRu);
|
const date = this.getDate(props.apis.antiCensorRu);
|
||||||
return (<div>Обновлялись: <span class="updateDate" title={date.title}>{ date.text }</span></div>);
|
return (<div>Обновлялись: <span class="updateDate" title={date.title}>{ date.text }</span></div>);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const updatePac = function updatePac() {
|
|
||||||
conduct(
|
|
||||||
'Обновляем...', (cb) => antiCensorRu.syncWithPacProviderAsync(cb),
|
|
||||||
'Обновлено.'
|
|
||||||
);
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
const InfoLi = getInfoLi(...args);
|
const InfoLi = getInfoLi(...args);
|
||||||
|
|
||||||
function emit(e) {
|
|
||||||
|
|
||||||
const event = new Event('dick');
|
|
||||||
e.target.dispatchEvent(event);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return class PacChooser extends Component {
|
return class PacChooser extends Component {
|
||||||
|
|
||||||
render(props) {
|
render(props) {
|
||||||
|
|
||||||
const checkedIddy = props.antiCensorRu.getCurrentPacProviderKey() || 'none';
|
const updatePac = function updatePac() {
|
||||||
|
props.funs.conduct(
|
||||||
|
'Обновляем...',
|
||||||
|
(cb) => props.apis.antiCensorRu.syncWithPacProviderAsync(cb),
|
||||||
|
'Обновлено.'
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const checkedIddy = props.apis.antiCensorRu.getCurrentPacProviderKey() || 'none';
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{props.flags.ifInsideOptionsPage && (<header>PAC-скрипт:</header>)}
|
{props.flags.ifInsideOptionsPage && (<header>PAC-скрипт:</header>)}
|
||||||
<ul>
|
<ul>
|
||||||
{
|
{
|
||||||
props.antiCensorRu.getSortedEntriesForProviders().map((provConf) =>
|
props.apis.antiCensorRu.getSortedEntriesForProviders().map((provConf) =>
|
||||||
(<InfoLi
|
(<InfoLi
|
||||||
conf={provConf}
|
conf={provConf}
|
||||||
type="radio"
|
type="radio"
|
||||||
name="pacProvider"
|
name="pacProvider"
|
||||||
checked={checkedIddy === provConf.key}
|
checked={checkedIddy === provConf.key}
|
||||||
>
|
>
|
||||||
<a href="" class={scopedCss.updateButton} onClick={(evt) => { evt.preventDefault(); emit(evt) }}>[обновить]</a>
|
<a href="" class={scopedCss.updateButton} onClick={(evt) => { evt.preventDefault(); updatePac(); }}>[обновить]</a>
|
||||||
</InfoLi>)
|
</InfoLi>)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
<InfoLi type="radio" name="pacProvider" conf={{key: 'none', label: 'Отключить'}} checked={checkedIddy === 'none'}/>
|
<InfoLi type="radio" name="pacProvider" conf={{key: 'none', label: 'Отключить'}} checked={checkedIddy === 'none'}/>
|
||||||
</ul>
|
</ul>
|
||||||
<div id="updateMessage" class="horFlex" style="align-items: center">
|
<div id="updateMessage" class="horFlex" style="align-items: center">
|
||||||
<LastUpdateDate antiCensorRu={props.antiCensorRu}/>
|
{ createElement(LastUpdateDate, props) }
|
||||||
<div class={scopedCss.fullLineHeight}>
|
<div class={scopedCss.fullLineHeight}>
|
||||||
{
|
{
|
||||||
props.flags.ifMini
|
props.flags.ifMini
|
||||||
|
|
|
@ -25,6 +25,9 @@ export default function getTabsPannel({ flags }) {
|
||||||
.underlined {
|
.underlined {
|
||||||
border-bottom: 1px solid var(--cr-options-headline);
|
border-bottom: 1px solid var(--cr-options-headline);
|
||||||
}
|
}
|
||||||
|
:root.ifInsideOptionsPage .navLabels {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
/* HIDE starts. */
|
/* HIDE starts. */
|
||||||
|
|
||||||
|
@ -113,7 +116,6 @@ export default function getTabsPannel({ flags }) {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
|
|
||||||
super(props);
|
super(props);
|
||||||
console.log('CONSTRUCTOR');
|
|
||||||
this.state = {
|
this.state = {
|
||||||
chosenTabIndex: 0,
|
chosenTabIndex: 0,
|
||||||
};
|
};
|
||||||
|
@ -126,7 +128,6 @@ export default function getTabsPannel({ flags }) {
|
||||||
if (/^#tab(\d+)$/.test(window.location.hash)) {
|
if (/^#tab(\d+)$/.test(window.location.hash)) {
|
||||||
const inputIndex = RegExp.$1;
|
const inputIndex = RegExp.$1;
|
||||||
if (inputIndex < this.props.tabs.length) {
|
if (inputIndex < this.props.tabs.length) {
|
||||||
console.log('SET STATE');
|
|
||||||
this.setState({chosenTabIndex: inputIndex});
|
this.setState({chosenTabIndex: inputIndex});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -137,6 +138,9 @@ export default function getTabsPannel({ flags }) {
|
||||||
|
|
||||||
return (<div ref={(dom) => {
|
return (<div ref={(dom) => {
|
||||||
|
|
||||||
|
if (!dom) {
|
||||||
|
return /* Unmounting. */;
|
||||||
|
}
|
||||||
const target = dom.querySelector(`.${scopedCss.mainNav} *:target`);
|
const target = dom.querySelector(`.${scopedCss.mainNav} *:target`);
|
||||||
if (target) {
|
if (target) {
|
||||||
const tabIndex = parseInt(target.id.replace('tab', ''));
|
const tabIndex = parseInt(target.id.replace('tab', ''));
|
|
@ -26,14 +26,12 @@ chrome.runtime.getBackgroundPage( (backgroundPage) =>
|
||||||
|
|
||||||
theState = {
|
theState = {
|
||||||
utils: backgroundPage.utils,
|
utils: backgroundPage.utils,
|
||||||
antiCensorRu: backgroundPage.apis.antiCensorRu,
|
apis: backgroundPage.apis,
|
||||||
errorHandlers: apis.errorHandlers,
|
|
||||||
flags: {
|
flags: {
|
||||||
/* Shortcuts to boolean values. */
|
/* Shortcuts to boolean values. */
|
||||||
ifNotControlled: !apis.errorHandlers.ifControllable,
|
ifNotControlled: !apis.errorHandlers.ifControllable,
|
||||||
ifMini: apis.version.ifMini,
|
ifMini: apis.version.ifMini,
|
||||||
},
|
},
|
||||||
status: 'Хорошего настроения Вам!',
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user