27a2b950c250dbd3f0f5c75b826f45ad26ed8857
7 'require shadowsocks-libev as ss';
9 var conf
= 'shadowsocks-libev';
10 var cfgtypes
= ['ss_local', 'ss_redir', 'ss_server', 'ss_tunnel'];
12 var callServiceList
= rpc
.declare({
19 return L
.view
.extend({
20 render: function(stats
) {
23 m
= new form
.Map(conf
,
25 _('Instances of shadowsocks-libev components, e.g. ss-local, \
26 ss-redir, ss-tunnel, ss-server, etc. To enable an instance it \
27 is required to enable both the instance itself and the remote \
28 server it refers to.'));
30 s
= m
.section(form
.GridSection
);
32 s
.cfgsections = function() {
33 return this.map
.data
.sections(this.map
.config
)
34 .filter(function(s
) { return cfgtypes
.indexOf(s
['.type']) !== -1; })
35 .map(function(s
) { return s
['.name']; });
37 s
.sectiontitle = function(section_id
) {
38 var s
= uci
.get(conf
, section_id
);
39 return (s
? s
['.type'] + '.' : '') + section_id
;
41 s
.renderSectionAdd = function(extra_class
) {
42 var el
= form
.GridSection
.prototype.renderSectionAdd
.apply(this, arguments
),
43 optionEl
= [E('option', { value
: '_dummy' }, [_('-- instance type --')])];
44 cfgtypes
.forEach(function(t
) {
45 optionEl
.push(E('option', { value
: t
}, [t
.replace('_', '-')]));
47 var selectEl
= E('select', {
48 class: 'cbi-input-select',
49 change: function(ev
) {
50 ev
.target
.parentElement
.nextElementSibling
.nextElementSibling
51 .toggleAttribute('disabled', ev
.target
.value
=== '_dummy');
54 el
.lastElementChild
.setAttribute('disabled', '');
55 el
.prepend(E('div', {}, selectEl
));
58 s
.handleAdd = function(ev
, name
) {
59 var selectEl
= ev
.target
.parentElement
.firstElementChild
.firstElementChild
,
60 type
= selectEl
.value
;
61 this.sectiontype
= type
;
62 var promise
= form
.GridSection
.prototype.handleAdd
.apply(this, arguments
);
63 this.sectiontype
= undefined;
66 s
.addModalOptions = function(s
, section_id
, ev
) {
67 var sdata
= uci
.get(conf
, section_id
),
68 stype
= sdata
? sdata
['.type'] : null;
70 s
.sectiontype
= stype
;
72 L
.resolveDefault(fs
.stat('/usr/bin/' + stype
.replace('_', '-')), null),
74 ]).then(L
.bind(function(res
) {
75 s
.tab('general', _('General Settings'));
76 s
.tab('advanced', _('Advanced Settings'));
77 s
.taboption('general', form
.Flag
, 'disabled', _('Disable'));
79 ss
.option_install_package(s
, 'general');
81 ss
.options_common(s
, 'advanced');
83 if (stype
=== 'ss_server') {
84 ss
.options_server(s
, { tab
: 'general' });
85 o
= s
.taboption('general', form
.Value
, 'bind_address',
87 _('The address ss-server will initiate connection from'));
88 o
.datatype
= 'ipaddr';
89 o
.placeholder
= '0.0.0.0';
90 ss
.values_ipaddr(o
, res
[1]);
92 ss
.options_client(s
, 'general', res
[1]);
93 if (stype
=== 'ss_tunnel') {
94 o
= s
.taboption('general', form
.Value
, 'tunnel_address',
96 _('The address ss-tunnel will forward traffic to'));
97 o
.datatype
= 'hostport';
104 o
= s
.option(form
.DummyValue
, 'overview', _('Overview'));
108 o
.renderWidget = function(section_id
, option_index
, cfgvalue
) {
109 var sdata
= uci
.get(conf
, section_id
);
111 return form
.DummyValue
.prototype.renderWidget
.call(this, section_id
, option_index
, ss
.cfgvalue_overview(sdata
));
116 o
= s
.option(form
.DummyValue
, 'running', _('Running'));
121 o
= s
.option(form
.Button
, 'disabled', _('Enable/Disable'));
124 o
.inputtitle = function(section_id
) {
125 var s
= uci
.get(conf
, section_id
);
126 if (ss
.ucival_to_bool(s
['disabled'])) {
127 this.inputstyle
= 'reset';
128 return _('Disabled');
130 this.inputstyle
= 'save';
133 o
.onclick = function(ev
) {
134 var inputEl
= ev
.target
.parentElement
.nextElementSibling
;
135 inputEl
.value
= ss
.ucival_to_bool(inputEl
.value
) ? '0' : '1';
136 return this.map
.save();
139 return m
.render().finally(function() {
140 L
.Poll
.add(function() {
141 return L
.resolveDefault(callServiceList(conf
), {})
142 .then(function(res
) {
143 var instances
= null;
145 instances
= res
[conf
]['instances'];
147 if (!instances
) return;
149 .filter(function(s
) { return cfgtypes
.indexOf(s
['.type']) !== -1; })
150 .forEach(function(s
) {
151 var el
= document
.getElementById('cbi-shadowsocks-libev-' + s
['.name'] + '-running');
153 var name
= s
['.type'] + '.' + s
['.name'],
154 running
= instances
.hasOwnProperty(name
)? instances
[name
].running
: false;
155 el
.innerText
= running
? 'yes' : 'no';