| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316 |
- /**
- * @author oldj
- * @blog http://oldj.net
- */
- 'use strict';
- import React from 'react';
- import ListItem from './list_item';
- import update from 'react-addons-update';
- import './list.less';
- class List extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- current: this.props.current,
- list: this.props.hosts.list
- };
- this.last_content = this.props.hosts.sys.content;
- SH_event.on('imported', () => {
- this.setState({
- current: this.props.current,
- list: this.props.hosts.list
- }, () => {
- SH_event.emit('change');
- });
- });
- SH_event.on('change', () => {
- SH_event.emit('save_data', this.state.list);
- let content = this.getOnContent();
- if (content !== this.last_content) {
- SH_event.emit('apply', content, () => {
- this.last_content = content;
- });
- }
- });
- SH_event.on('host_added', (data) => {
- this.setState({
- list: update(this.state.list, {$push: [data]})
- }, () => {
- this.selectOne(data);
- setTimeout(() => {
- SH_event.emit('change', true);
- let el = this.refs.items;
- el.scrollTop = document.querySelector('.list-item.selected').offsetTop - el.offsetHeight + 50;
- this.checkUpdateHost(data);
- }, 100);
- });
- });
- SH_event.on('host_edited', (data, host) => {
- let idx = this.state.list.findIndex((item) => item == host);
- if (idx == -1) return;
- this.setState({
- list: update(this.state.list, {$splice: [[idx, 1, data]]})
- }, () => {
- this.selectOne(data);
- setTimeout(() => {
- SH_event.emit('change', true);
- this.checkUpdateHost(data, true);
- }, 100);
- });
- });
- SH_event.on('host_refreshed', (data, host) => {
- let idx = this.state.list.findIndex((item) => item == host);
- if (idx == -1) return;
- this.setState({
- list: update(this.state.list, {$splice: [[idx, 1, data]]})
- }, () => {
- setTimeout(() => {
- if (host === this.state.current) {
- this.selectOne(data);
- }
- SH_event.emit('change', true);
- }, 100);
- });
- });
- SH_event.on('del_host', (host) => {
- let list = this.state.list;
- let idx_to_del = list.findIndex((item) => {
- return host === item;
- });
- if (idx_to_del == -1) return;
- // list.splice(idx_to_del, 1);
- this.setState({
- list: update(this.state.list, {$splice: [[idx_to_del, 1]]})
- // list: this.state.list.filter((item, idx) => idx != idx_to_del)
- }, () => {
- setTimeout(() => {
- let list = this.state.list;
- let next_host = list[idx_to_del] || list[list.length - 1] || this.props.hosts.sys;
- if (next_host) {
- this.selectOne(next_host);
- }
- SH_event.emit('change');
- }, 100);
- });
- });
- SH_event.on('get_on_hosts', (callback) => {
- callback(this.getOnItems());
- });
- ipcRenderer.on('get_host_list', () => {
- ipcRenderer.send('send_host_list', this.state.list);
- });
- ipcRenderer.on('get_export_data', (e, fn) => {
- let data = Object.assign({}, {
- version: require('../../configs').version,
- list: this.state.list.map(item => {
- let new_item = Object.assign({}, item);
- new_item.on = false;
- return new_item;
- })
- });
- ipcRenderer.send('export_data', fn, JSON.stringify(data));
- });
- SH_event.on('top_toggle', (on, items) => {
- this.setState({
- list: this.state.list.map((item) => {
- if (items.findIndex((i) => i == item) > -1) {
- item.on = on;
- }
- return item;
- })
- }, () => {
- SH_event.emit('change');
- });
- });
- SH_event.on('loading_done', (host, data) => {
- SH_event.emit('host_refreshed', data, host);
- // if (host == this.state.current || host._ == this.state.current) {
- // setTimeout(() => {
- // this.selectOne(this.state.current);
- // }, 100);
- // }
- if (data.error) {
- console.log(data.error);
- }
- });
- // auto check refresh
- setTimeout(() => {
- this.autoCheckRefresh();
- }, 1000 * 5);
- }
- /**
- * 检查当前 host 是否需要从网络下载更新
- * @param host
- * @param force {Boolean} 如果为 true,则只要是 remote 且 refresh_interval != 0,则强制更新
- */
- checkUpdateHost(host, force = false) {
- SH_event.emit('check_host_refresh', host, force);
- }
- autoCheckRefresh() {
- let remote_idx = -1;
- this.state.list.map((host, idx) => {
- if (host.where === 'remote') {
- remote_idx++;
- }
- setTimeout(() => {
- SH_event.emit('check_host_refresh', host);
- }, 1000 * 5 * remote_idx + idx);
- });
- // let wait = 1000 * 60 * 10;
- let wait = 1000 * 30; // test only
- setTimeout(() => {
- this.autoCheckRefresh();
- }, wait);
- }
- apply(content, success) {
- SH_event.emit('apply', content, () => {
- this.last_content = content;
- success();
- SH_event.emit('save_data', this.state.list);
- SH_Agent.notify({
- message: 'host updated.'
- });
- });
- }
- selectOne(host) {
- this.setState({
- current: host
- });
- this.props.setCurrent(host);
- }
- toggleOne(idx, success) {
- let content = this.getOnContent(idx);
- this.apply(content, () => {
- let choice_mode = SH_Agent.pref.get('choice_mode');
- if (choice_mode === 'single') {
- // 单选模式
- this.setState({
- list: this.state.list.map((item, _idx) => {
- if (idx != _idx) {
- item.on = false;
- }
- return item;
- })
- });
- }
- if (typeof success === 'function') {
- success();
- }
- });
- }
- getOnItems(idx = -1) {
- let choice_mode = SH_Agent.pref.get('choice_mode');
- return this.state.list.filter((item, _idx) => {
- if (choice_mode === 'single') {
- return !item.on && _idx == idx;
- } else {
- return (item.on && _idx != idx) || (!item.on && _idx == idx);
- }
- });
- }
- getOnContent(idx = -1) {
- let contents = this.getOnItems(idx).map((item) => {
- return item.content || '';
- });
- contents.unshift('# SwitchHosts!');
- return contents.join(`\n\n`);
- }
- customItems() {
- return this.state.list.map((item, idx) => {
- return (
- <ListItem
- data={item}
- idx={idx}
- selectOne={this.selectOne.bind(this)}
- current={this.state.current}
- onToggle={(success)=> this.toggleOne(idx, success)}
- key={'host-' + idx}
- dragOrder={(sidx, tidx) => this.dragOrder(sidx, tidx)}
- />
- )
- });
- }
- dragOrder(source_idx, target_idx) {
- let source = this.state.list[source_idx];
- let target = this.state.list[target_idx];
- let list = this.state.list.filter((item, idx) => idx != source_idx);
- let new_target_idx = list.findIndex((item) => item == target);
- let to_idx;
- if (source_idx < target_idx) {
- // append
- to_idx = new_target_idx + 1;
- } else {
- // insert before
- to_idx = new_target_idx;
- }
- list.splice(to_idx, 0, source);
- this.setState({
- list: list
- });
- setTimeout(() => {
- SH_event.emit('change');
- }, 100);
- }
- componentDidMount() {
- }
- render() {
- return (
- <div id="sh-list">
- <ListItem
- data={this.props.hosts.sys}
- selectOne={this.selectOne.bind(this)}
- current={this.state.current}
- sys="1"/>
- <div ref="items" className="custom-items">
- {this.customItems()}
- </div>
- </div>
- );
- }
- }
- export default List;
|