xref: /MusicFree/src/lib/react-native-vdebug/index.js (revision ea6d708f22409666b768cda1107ea1066b213247)
1*ea6d708fS猫头猫/// 魔改自 https://github.com/itenl/react-native-vdebug
2*ea6d708fS猫头猫import PropTypes from 'prop-types';
3*ea6d708fS猫头猫import React, {PureComponent} from 'react';
4*ea6d708fS猫头猫import {
5*ea6d708fS猫头猫    ScrollView,
6*ea6d708fS猫头猫    View,
7*ea6d708fS猫头猫    Text,
8*ea6d708fS猫头猫    TouchableOpacity,
9*ea6d708fS猫头猫    PanResponder,
10*ea6d708fS猫头猫    Animated,
11*ea6d708fS猫头猫    Dimensions,
12*ea6d708fS猫头猫    StyleSheet,
13*ea6d708fS猫头猫    TextInput,
14*ea6d708fS猫头猫    Keyboard,
15*ea6d708fS猫头猫    NativeModules,
16*ea6d708fS猫头猫    Platform,
17*ea6d708fS猫头猫    KeyboardAvoidingView,
18*ea6d708fS猫头猫} from 'react-native';
19*ea6d708fS猫头猫import event from './src/event';
20*ea6d708fS猫头猫// import Network, { traceNetwork } from './src/network';
21*ea6d708fS猫头猫import Log, {traceLog} from './src/log';
22*ea6d708fS猫头猫import HocComp from './src/hoc';
23*ea6d708fS猫头猫import Storage from './src/storage';
24*ea6d708fS猫头猫import {replaceReg} from './src/tool';
25*ea6d708fS猫头猫
26*ea6d708fS猫头猫const {width, height} = Dimensions.get('window');
27*ea6d708fS猫头猫
28*ea6d708fS猫头猫let commandContext = global;
29*ea6d708fS猫头猫
30*ea6d708fS猫头猫export const setExternalContext = externalContext => {
31*ea6d708fS猫头猫    if (externalContext) commandContext = externalContext;
32*ea6d708fS猫头猫};
33*ea6d708fS猫头猫
34*ea6d708fS猫头猫// Log/network trace when Element is not initialized.
35*ea6d708fS猫头猫export const initTrace = () => {
36*ea6d708fS猫头猫    traceLog();
37*ea6d708fS猫头猫    //   traceNetwork();
38*ea6d708fS猫头猫};
39*ea6d708fS猫头猫
40*ea6d708fS猫头猫class VDebug extends PureComponent {
41*ea6d708fS猫头猫    static propTypes = {
42*ea6d708fS猫头猫        // Expansion panel (Optional)
43*ea6d708fS猫头猫        panels: PropTypes.array,
44*ea6d708fS猫头猫    };
45*ea6d708fS猫头猫
46*ea6d708fS猫头猫    static defaultProps = {
47*ea6d708fS猫头猫        panels: null,
48*ea6d708fS猫头猫    };
49*ea6d708fS猫头猫
50*ea6d708fS猫头猫    constructor(props) {
51*ea6d708fS猫头猫        super(props);
52*ea6d708fS猫头猫        initTrace();
53*ea6d708fS猫头猫        this.containerHeight = (height / 3) * 2;
54*ea6d708fS猫头猫        this.refsObj = {};
55*ea6d708fS猫头猫        this.state = {
56*ea6d708fS猫头猫            commandValue: '',
57*ea6d708fS猫头猫            showPanel: false,
58*ea6d708fS猫头猫            currentPageIndex: 0,
59*ea6d708fS猫头猫            pan: new Animated.ValueXY(),
60*ea6d708fS猫头猫            scale: new Animated.Value(1),
61*ea6d708fS猫头猫            panelHeight: new Animated.Value(0),
62*ea6d708fS猫头猫            panels: this.addPanels(),
63*ea6d708fS猫头猫            history: [],
64*ea6d708fS猫头猫            historyFilter: [],
65*ea6d708fS猫头猫            showHistory: false,
66*ea6d708fS猫头猫        };
67*ea6d708fS猫头猫        this.panResponder = PanResponder.create({
68*ea6d708fS猫头猫            onStartShouldSetPanResponder: () => true,
69*ea6d708fS猫头猫            onPanResponderGrant: () => {
70*ea6d708fS猫头猫                this.state.pan.setOffset({
71*ea6d708fS猫头猫                    x: this.state.pan.x._value,
72*ea6d708fS猫头猫                    y: this.state.pan.y._value,
73*ea6d708fS猫头猫                });
74*ea6d708fS猫头猫                this.state.pan.setValue({x: 0, y: 0});
75*ea6d708fS猫头猫                Animated.spring(this.state.scale, {
76*ea6d708fS猫头猫                    useNativeDriver: true,
77*ea6d708fS猫头猫                    toValue: 1.3,
78*ea6d708fS猫头猫                    friction: 7,
79*ea6d708fS猫头猫                }).start();
80*ea6d708fS猫头猫            },
81*ea6d708fS猫头猫            onPanResponderMove: Animated.event([
82*ea6d708fS猫头猫                null,
83*ea6d708fS猫头猫                {dx: this.state.pan.x, dy: this.state.pan.y},
84*ea6d708fS猫头猫            ]),
85*ea6d708fS猫头猫            onPanResponderRelease: ({nativeEvent}, gestureState) => {
86*ea6d708fS猫头猫                if (
87*ea6d708fS猫头猫                    Math.abs(gestureState.dx) < 5 &&
88*ea6d708fS猫头猫                    Math.abs(gestureState.dy) < 5
89*ea6d708fS猫头猫                )
90*ea6d708fS猫头猫                    this.togglePanel();
91*ea6d708fS猫头猫                setTimeout(() => {
92*ea6d708fS猫头猫                    Animated.spring(this.state.scale, {
93*ea6d708fS猫头猫                        useNativeDriver: true,
94*ea6d708fS猫头猫                        toValue: 1,
95*ea6d708fS猫头猫                        friction: 7,
96*ea6d708fS猫头猫                    }).start(() => {
97*ea6d708fS猫头猫                        this.setState({
98*ea6d708fS猫头猫                            top: nativeEvent.pageY,
99*ea6d708fS猫头猫                        });
100*ea6d708fS猫头猫                    });
101*ea6d708fS猫头猫                    this.state.pan.flattenOffset();
102*ea6d708fS猫头猫                }, 0);
103*ea6d708fS猫头猫            },
104*ea6d708fS猫头猫        });
105*ea6d708fS猫头猫    }
106*ea6d708fS猫头猫
107*ea6d708fS猫头猫    componentDidMount() {
108*ea6d708fS猫头猫        this.state.pan.setValue({x: 0, y: 0});
109*ea6d708fS猫头猫        Storage.support() &&
110*ea6d708fS猫头猫            Storage.get('react-native-vdebug@history').then(res => {
111*ea6d708fS猫头猫                if (res) {
112*ea6d708fS猫头猫                    this.setState({
113*ea6d708fS猫头猫                        history: res,
114*ea6d708fS猫头猫                    });
115*ea6d708fS猫头猫                }
116*ea6d708fS猫头猫            });
117*ea6d708fS猫头猫    }
118*ea6d708fS猫头猫
119*ea6d708fS猫头猫    getRef(index) {
120*ea6d708fS猫头猫        return ref => {
121*ea6d708fS猫头猫            if (!this.refsObj[index]) this.refsObj[index] = ref;
122*ea6d708fS猫头猫        };
123*ea6d708fS猫头猫    }
124*ea6d708fS猫头猫
125*ea6d708fS猫头猫    addPanels() {
126*ea6d708fS猫头猫        let defaultPanels = [
127*ea6d708fS猫头猫            {
128*ea6d708fS猫头猫                title: 'Log',
129*ea6d708fS猫头猫                component: HocComp(Log, this.getRef(0)),
130*ea6d708fS猫头猫            },
131*ea6d708fS猫头猫            //   {
132*ea6d708fS猫头猫            //     title: 'Network',
133*ea6d708fS猫头猫            //     component: HocComp(Network, this.getRef(1))
134*ea6d708fS猫头猫            //   },
135*ea6d708fS猫头猫        ];
136*ea6d708fS猫头猫        if (this.props.panels && this.props.panels.length) {
137*ea6d708fS猫头猫            this.props.panels.forEach((item, index) => {
138*ea6d708fS猫头猫                // support up to five extended panels
139*ea6d708fS猫头猫                if (index >= 3) return;
140*ea6d708fS猫头猫                if (item.title && item.component) {
141*ea6d708fS猫头猫                    item.component = HocComp(
142*ea6d708fS猫头猫                        item.component,
143*ea6d708fS猫头猫                        this.getRef(defaultPanels.length),
144*ea6d708fS猫头猫                    );
145*ea6d708fS猫头猫                    defaultPanels.push(item);
146*ea6d708fS猫头猫                }
147*ea6d708fS猫头猫            });
148*ea6d708fS猫头猫        }
149*ea6d708fS猫头猫        return defaultPanels;
150*ea6d708fS猫头猫    }
151*ea6d708fS猫头猫
152*ea6d708fS猫头猫    togglePanel() {
153*ea6d708fS猫头猫        this.state.panelHeight.setValue(
154*ea6d708fS猫头猫            this.state.panelHeight._value ? 0 : this.containerHeight,
155*ea6d708fS猫头猫        );
156*ea6d708fS猫头猫    }
157*ea6d708fS猫头猫
158*ea6d708fS猫头猫    clearLogs() {
159*ea6d708fS猫头猫        const tabName = this.state.panels[this.state.currentPageIndex].title;
160*ea6d708fS猫头猫        event.trigger('clear', tabName);
161*ea6d708fS猫头猫    }
162*ea6d708fS猫头猫
163*ea6d708fS猫头猫    showDev() {
164*ea6d708fS猫头猫        NativeModules?.DevMenu?.show();
165*ea6d708fS猫头猫    }
166*ea6d708fS猫头猫
167*ea6d708fS猫头猫    reloadDev() {
168*ea6d708fS猫头猫        NativeModules?.DevMenu?.reload();
169*ea6d708fS猫头猫    }
170*ea6d708fS猫头猫
171*ea6d708fS猫头猫    evalInContext(js, context) {
172*ea6d708fS猫头猫        return function (str) {
173*ea6d708fS猫头猫            let result = '';
174*ea6d708fS猫头猫            try {
175*ea6d708fS猫头猫                // eslint-disable-next-line no-eval
176*ea6d708fS猫头猫                result = eval(str);
177*ea6d708fS猫头猫            } catch (err) {
178*ea6d708fS猫头猫                result = 'Invalid input';
179*ea6d708fS猫头猫            }
180*ea6d708fS猫头猫            return event.trigger('addLog', result);
181*ea6d708fS猫头猫        }.call(context, `with(this) { ${js} } `);
182*ea6d708fS猫头猫    }
183*ea6d708fS猫头猫
184*ea6d708fS猫头猫    execCommand() {
185*ea6d708fS猫头猫        if (!this.state.commandValue) return;
186*ea6d708fS猫头猫        this.evalInContext(this.state.commandValue, commandContext);
187*ea6d708fS猫头猫        this.syncHistory();
188*ea6d708fS猫头猫        Keyboard.dismiss();
189*ea6d708fS猫头猫    }
190*ea6d708fS猫头猫
191*ea6d708fS猫头猫    clearCommand() {
192*ea6d708fS猫头猫        this.textInput.clear();
193*ea6d708fS猫头猫        this.setState({
194*ea6d708fS猫头猫            historyFilter: [],
195*ea6d708fS猫头猫        });
196*ea6d708fS猫头猫    }
197*ea6d708fS猫头猫
198*ea6d708fS猫头猫    scrollToPage(index, animated = true) {
199*ea6d708fS猫头猫        this.scrollToCard(index, animated);
200*ea6d708fS猫头猫    }
201*ea6d708fS猫头猫
202*ea6d708fS猫头猫    scrollToCard(cardIndex, animated = true) {
203*ea6d708fS猫头猫        if (cardIndex < 0) cardIndex = 0;
204*ea6d708fS猫头猫        else if (cardIndex >= this.cardCount) cardIndex = this.cardCount - 1;
205*ea6d708fS猫头猫        if (this.scrollView) {
206*ea6d708fS猫头猫            this.scrollView.scrollTo({
207*ea6d708fS猫头猫                x: width * cardIndex,
208*ea6d708fS猫头猫                y: 0,
209*ea6d708fS猫头猫                animated: animated,
210*ea6d708fS猫头猫            });
211*ea6d708fS猫头猫        }
212*ea6d708fS猫头猫    }
213*ea6d708fS猫头猫
214*ea6d708fS猫头猫    scrollToTop() {
215*ea6d708fS猫头猫        const item = this.refsObj[this.state.currentPageIndex];
216*ea6d708fS猫头猫        const instance = item?.getScrollRef && item?.getScrollRef();
217*ea6d708fS猫头猫        if (instance) {
218*ea6d708fS猫头猫            // FlatList
219*ea6d708fS猫头猫            instance.scrollToOffset &&
220*ea6d708fS猫头猫                instance.scrollToOffset({
221*ea6d708fS猫头猫                    animated: true,
222*ea6d708fS猫头猫                    viewPosition: 0,
223*ea6d708fS猫头猫                    index: 0,
224*ea6d708fS猫头猫                });
225*ea6d708fS猫头猫            // ScrollView
226*ea6d708fS猫头猫            instance.scrollTo &&
227*ea6d708fS猫头猫                instance.scrollTo({x: 0, y: 0, animated: true});
228*ea6d708fS猫头猫        }
229*ea6d708fS猫头猫    }
230*ea6d708fS猫头猫
231*ea6d708fS猫头猫    renderPanelHeader() {
232*ea6d708fS猫头猫        return (
233*ea6d708fS猫头猫            <View style={styles.panelHeader}>
234*ea6d708fS猫头猫                {this.state.panels.map((item, index) => (
235*ea6d708fS猫头猫                    <TouchableOpacity
236*ea6d708fS猫头猫                        key={index.toString()}
237*ea6d708fS猫头猫                        onPress={() => {
238*ea6d708fS猫头猫                            if (index != this.state.currentPageIndex) {
239*ea6d708fS猫头猫                                this.scrollToPage(index);
240*ea6d708fS猫头猫                                this.setState({currentPageIndex: index});
241*ea6d708fS猫头猫                            } else {
242*ea6d708fS猫头猫                                this.scrollToTop();
243*ea6d708fS猫头猫                            }
244*ea6d708fS猫头猫                        }}
245*ea6d708fS猫头猫                        style={[
246*ea6d708fS猫头猫                            styles.panelHeaderItem,
247*ea6d708fS猫头猫                            index === this.state.currentPageIndex &&
248*ea6d708fS猫头猫                                styles.activeTab,
249*ea6d708fS猫头猫                        ]}>
250*ea6d708fS猫头猫                        <Text style={styles.panelHeaderItemText}>
251*ea6d708fS猫头猫                            {item.title}
252*ea6d708fS猫头猫                        </Text>
253*ea6d708fS猫头猫                    </TouchableOpacity>
254*ea6d708fS猫头猫                ))}
255*ea6d708fS猫头猫            </View>
256*ea6d708fS猫头猫        );
257*ea6d708fS猫头猫    }
258*ea6d708fS猫头猫
259*ea6d708fS猫头猫    syncHistory() {
260*ea6d708fS猫头猫        if (!Storage.support()) return;
261*ea6d708fS猫头猫        const res = this.state.history.filter(f => {
262*ea6d708fS猫头猫            return f == this.state.commandValue;
263*ea6d708fS猫头猫        });
264*ea6d708fS猫头猫        if (res && res.length) return;
265*ea6d708fS猫头猫        this.state.history.splice(0, 0, this.state.commandValue);
266*ea6d708fS猫头猫        this.state.historyFilter.splice(0, 0, this.state.commandValue);
267*ea6d708fS猫头猫        this.setState(
268*ea6d708fS猫头猫            {
269*ea6d708fS猫头猫                history: this.state.history,
270*ea6d708fS猫头猫                historyFilter: this.state.historyFilter,
271*ea6d708fS猫头猫            },
272*ea6d708fS猫头猫            () => {
273*ea6d708fS猫头猫                Storage.save('react-native-vdebug@history', this.state.history);
274*ea6d708fS猫头猫                this.forceUpdate();
275*ea6d708fS猫头猫            },
276*ea6d708fS猫头猫        );
277*ea6d708fS猫头猫    }
278*ea6d708fS猫头猫
279*ea6d708fS猫头猫    onChange(text) {
280*ea6d708fS猫头猫        const state = {commandValue: text};
281*ea6d708fS猫头猫        if (text) {
282*ea6d708fS猫头猫            const res = this.state.history.filter(f =>
283*ea6d708fS猫头猫                f.toLowerCase().match(replaceReg(text)),
284*ea6d708fS猫头猫            );
285*ea6d708fS猫头猫            if (res && res.length) state.historyFilter = res;
286*ea6d708fS猫头猫        } else {
287*ea6d708fS猫头猫            state.historyFilter = [];
288*ea6d708fS猫头猫        }
289*ea6d708fS猫头猫        this.setState(state);
290*ea6d708fS猫头猫    }
291*ea6d708fS猫头猫
292*ea6d708fS猫头猫    renderCommandBar() {
293*ea6d708fS猫头猫        return (
294*ea6d708fS猫头猫            <KeyboardAvoidingView
295*ea6d708fS猫头猫                keyboardVerticalOffset={Platform.OS == 'android' ? 0 : 300}
296*ea6d708fS猫头猫                contentContainerStyle={{flex: 1}}
297*ea6d708fS猫头猫                behavior={'position'}
298*ea6d708fS猫头猫                style={{
299*ea6d708fS猫头猫                    height: this.state.historyFilter.length ? 120 : 40,
300*ea6d708fS猫头猫                    borderWidth: StyleSheet.hairlineWidth,
301*ea6d708fS猫头猫                    borderColor: '#d9d9d9',
302*ea6d708fS猫头猫                }}>
303*ea6d708fS猫头猫                <View
304*ea6d708fS猫头猫                    style={[
305*ea6d708fS猫头猫                        styles.historyContainer,
306*ea6d708fS猫头猫                        {height: this.state.historyFilter.length ? 80 : 0},
307*ea6d708fS猫头猫                    ]}>
308*ea6d708fS猫头猫                    <ScrollView>
309*ea6d708fS猫头猫                        {this.state.historyFilter.map(text => {
310*ea6d708fS猫头猫                            return (
311*ea6d708fS猫头猫                                <TouchableOpacity
312*ea6d708fS猫头猫                                    style={{
313*ea6d708fS猫头猫                                        borderBottomWidth: 1,
314*ea6d708fS猫头猫                                        borderBottomColor: '#eeeeeea1',
315*ea6d708fS猫头猫                                    }}
316*ea6d708fS猫头猫                                    onPress={() => {
317*ea6d708fS猫头猫                                        if (text && text.toString) {
318*ea6d708fS猫头猫                                            this.setState({
319*ea6d708fS猫头猫                                                commandValue: text.toString(),
320*ea6d708fS猫头猫                                            });
321*ea6d708fS猫头猫                                        }
322*ea6d708fS猫头猫                                    }}>
323*ea6d708fS猫头猫                                    <Text style={{lineHeight: 25}}>{text}</Text>
324*ea6d708fS猫头猫                                </TouchableOpacity>
325*ea6d708fS猫头猫                            );
326*ea6d708fS猫头猫                        })}
327*ea6d708fS猫头猫                    </ScrollView>
328*ea6d708fS猫头猫                </View>
329*ea6d708fS猫头猫                <View style={styles.commandBar}>
330*ea6d708fS猫头猫                    <TextInput
331*ea6d708fS猫头猫                        ref={ref => {
332*ea6d708fS猫头猫                            this.textInput = ref;
333*ea6d708fS猫头猫                        }}
334*ea6d708fS猫头猫                        style={styles.commandBarInput}
335*ea6d708fS猫头猫                        placeholderTextColor={'#000000a1'}
336*ea6d708fS猫头猫                        placeholder="Command..."
337*ea6d708fS猫头猫                        onChangeText={this.onChange.bind(this)}
338*ea6d708fS猫头猫                        value={this.state.commandValue}
339*ea6d708fS猫头猫                        onFocus={() => {
340*ea6d708fS猫头猫                            this.setState({showHistory: true});
341*ea6d708fS猫头猫                        }}
342*ea6d708fS猫头猫                        onSubmitEditing={this.execCommand.bind(this)}
343*ea6d708fS猫头猫                    />
344*ea6d708fS猫头猫                    <TouchableOpacity
345*ea6d708fS猫头猫                        style={styles.commandBarBtn}
346*ea6d708fS猫头猫                        onPress={this.clearCommand.bind(this)}>
347*ea6d708fS猫头猫                        <Text>X</Text>
348*ea6d708fS猫头猫                    </TouchableOpacity>
349*ea6d708fS猫头猫                    <TouchableOpacity
350*ea6d708fS猫头猫                        style={styles.commandBarBtn}
351*ea6d708fS猫头猫                        onPress={this.execCommand.bind(this)}>
352*ea6d708fS猫头猫                        <Text>OK</Text>
353*ea6d708fS猫头猫                    </TouchableOpacity>
354*ea6d708fS猫头猫                </View>
355*ea6d708fS猫头猫            </KeyboardAvoidingView>
356*ea6d708fS猫头猫        );
357*ea6d708fS猫头猫    }
358*ea6d708fS猫头猫
359*ea6d708fS猫头猫    renderPanelFooter() {
360*ea6d708fS猫头猫        return (
361*ea6d708fS猫头猫            <View style={styles.panelBottom}>
362*ea6d708fS猫头猫                <TouchableOpacity
363*ea6d708fS猫头猫                    onPress={this.clearLogs.bind(this)}
364*ea6d708fS猫头猫                    style={styles.panelBottomBtn}>
365*ea6d708fS猫头猫                    <Text style={styles.panelBottomBtnText}>Clear</Text>
366*ea6d708fS猫头猫                </TouchableOpacity>
367*ea6d708fS猫头猫                {__DEV__ && Platform.OS == 'ios' && (
368*ea6d708fS猫头猫                    <TouchableOpacity
369*ea6d708fS猫头猫                        onPress={this.showDev.bind(this)}
370*ea6d708fS猫头猫                        onLongPress={this.reloadDev.bind(this)}
371*ea6d708fS猫头猫                        style={styles.panelBottomBtn}>
372*ea6d708fS猫头猫                        <Text style={styles.panelBottomBtnText}>Dev</Text>
373*ea6d708fS猫头猫                    </TouchableOpacity>
374*ea6d708fS猫头猫                )}
375*ea6d708fS猫头猫                <TouchableOpacity
376*ea6d708fS猫头猫                    onPress={this.togglePanel.bind(this)}
377*ea6d708fS猫头猫                    style={styles.panelBottomBtn}>
378*ea6d708fS猫头猫                    <Text style={styles.panelBottomBtnText}>Hide</Text>
379*ea6d708fS猫头猫                </TouchableOpacity>
380*ea6d708fS猫头猫            </View>
381*ea6d708fS猫头猫        );
382*ea6d708fS猫头猫    }
383*ea6d708fS猫头猫
384*ea6d708fS猫头猫    onScrollAnimationEnd({nativeEvent}) {
385*ea6d708fS猫头猫        const currentPageIndex = Math.floor(
386*ea6d708fS猫头猫            nativeEvent.contentOffset.x / Math.floor(width),
387*ea6d708fS猫头猫        );
388*ea6d708fS猫头猫        currentPageIndex != this.state.currentPageIndex &&
389*ea6d708fS猫头猫            this.setState({
390*ea6d708fS猫头猫                currentPageIndex: currentPageIndex,
391*ea6d708fS猫头猫            });
392*ea6d708fS猫头猫    }
393*ea6d708fS猫头猫
394*ea6d708fS猫头猫    renderPanel() {
395*ea6d708fS猫头猫        return (
396*ea6d708fS猫头猫            <Animated.View
397*ea6d708fS猫头猫                style={[styles.panel, {height: this.state.panelHeight}]}>
398*ea6d708fS猫头猫                {this.renderPanelHeader()}
399*ea6d708fS猫头猫                <ScrollView
400*ea6d708fS猫头猫                    onMomentumScrollEnd={this.onScrollAnimationEnd.bind(this)}
401*ea6d708fS猫头猫                    ref={ref => {
402*ea6d708fS猫头猫                        this.scrollView = ref;
403*ea6d708fS猫头猫                    }}
404*ea6d708fS猫头猫                    pagingEnabled={true}
405*ea6d708fS猫头猫                    showsHorizontalScrollIndicator={false}
406*ea6d708fS猫头猫                    horizontal={true}
407*ea6d708fS猫头猫                    style={styles.panelContent}>
408*ea6d708fS猫头猫                    {this.state.panels.map((item, index) => {
409*ea6d708fS猫头猫                        return (
410*ea6d708fS猫头猫                            <View key={index} style={{width: width}}>
411*ea6d708fS猫头猫                                <item.component {...(item.props ?? {})} />
412*ea6d708fS猫头猫                            </View>
413*ea6d708fS猫头猫                        );
414*ea6d708fS猫头猫                    })}
415*ea6d708fS猫头猫                </ScrollView>
416*ea6d708fS猫头猫                {this.renderCommandBar()}
417*ea6d708fS猫头猫                {this.renderPanelFooter()}
418*ea6d708fS猫头猫            </Animated.View>
419*ea6d708fS猫头猫        );
420*ea6d708fS猫头猫    }
421*ea6d708fS猫头猫
422*ea6d708fS猫头猫    renderDebugBtn() {
423*ea6d708fS猫头猫        const {pan, scale} = this.state;
424*ea6d708fS猫头猫        const [translateX, translateY] = [pan.x, pan.y];
425*ea6d708fS猫头猫        const btnStyle = {transform: [{translateX}, {translateY}, {scale}]};
426*ea6d708fS猫头猫
427*ea6d708fS猫头猫        return (
428*ea6d708fS猫头猫            <Animated.View
429*ea6d708fS猫头猫                {...this.panResponder.panHandlers}
430*ea6d708fS猫头猫                style={[styles.homeBtn, btnStyle]}>
431*ea6d708fS猫头猫                <Text style={styles.homeBtnText}>调试</Text>
432*ea6d708fS猫头猫            </Animated.View>
433*ea6d708fS猫头猫        );
434*ea6d708fS猫头猫    }
435*ea6d708fS猫头猫
436*ea6d708fS猫头猫    render() {
437*ea6d708fS猫头猫        return (
438*ea6d708fS猫头猫            <View style={{flex: 1}}>
439*ea6d708fS猫头猫                {this.renderPanel()}
440*ea6d708fS猫头猫                {this.renderDebugBtn()}
441*ea6d708fS猫头猫            </View>
442*ea6d708fS猫头猫        );
443*ea6d708fS猫头猫    }
444*ea6d708fS猫头猫}
445*ea6d708fS猫头猫
446*ea6d708fS猫头猫const styles = StyleSheet.create({
447*ea6d708fS猫头猫    activeTab: {
448*ea6d708fS猫头猫        backgroundColor: '#fff',
449*ea6d708fS猫头猫    },
450*ea6d708fS猫头猫    panel: {
451*ea6d708fS猫头猫        position: 'absolute',
452*ea6d708fS猫头猫        zIndex: 99998,
453*ea6d708fS猫头猫        elevation: 99998,
454*ea6d708fS猫头猫        backgroundColor: '#fff',
455*ea6d708fS猫头猫        width,
456*ea6d708fS猫头猫        bottom: 0,
457*ea6d708fS猫头猫        right: 0,
458*ea6d708fS猫头猫    },
459*ea6d708fS猫头猫    panelHeader: {
460*ea6d708fS猫头猫        width,
461*ea6d708fS猫头猫        backgroundColor: '#eee',
462*ea6d708fS猫头猫        flexDirection: 'row',
463*ea6d708fS猫头猫        borderWidth: StyleSheet.hairlineWidth,
464*ea6d708fS猫头猫        borderColor: '#d9d9d9',
465*ea6d708fS猫头猫    },
466*ea6d708fS猫头猫    panelHeaderItem: {
467*ea6d708fS猫头猫        flex: 1,
468*ea6d708fS猫头猫        height: 40,
469*ea6d708fS猫头猫        color: '#000',
470*ea6d708fS猫头猫        borderRightWidth: StyleSheet.hairlineWidth,
471*ea6d708fS猫头猫        borderColor: '#d9d9d9',
472*ea6d708fS猫头猫        justifyContent: 'center',
473*ea6d708fS猫头猫    },
474*ea6d708fS猫头猫    panelHeaderItemText: {
475*ea6d708fS猫头猫        textAlign: 'center',
476*ea6d708fS猫头猫    },
477*ea6d708fS猫头猫    panelContent: {
478*ea6d708fS猫头猫        width,
479*ea6d708fS猫头猫        flex: 0.9,
480*ea6d708fS猫头猫    },
481*ea6d708fS猫头猫    panelBottom: {
482*ea6d708fS猫头猫        width,
483*ea6d708fS猫头猫        borderWidth: StyleSheet.hairlineWidth,
484*ea6d708fS猫头猫        borderColor: '#d9d9d9',
485*ea6d708fS猫头猫        flexDirection: 'row',
486*ea6d708fS猫头猫        alignItems: 'center',
487*ea6d708fS猫头猫        backgroundColor: '#eee',
488*ea6d708fS猫头猫        height: 40,
489*ea6d708fS猫头猫    },
490*ea6d708fS猫头猫    panelBottomBtn: {
491*ea6d708fS猫头猫        flex: 1,
492*ea6d708fS猫头猫        height: 40,
493*ea6d708fS猫头猫        borderRightWidth: StyleSheet.hairlineWidth,
494*ea6d708fS猫头猫        borderColor: '#d9d9d9',
495*ea6d708fS猫头猫        justifyContent: 'center',
496*ea6d708fS猫头猫    },
497*ea6d708fS猫头猫    panelBottomBtnText: {
498*ea6d708fS猫头猫        color: '#000',
499*ea6d708fS猫头猫        fontSize: 14,
500*ea6d708fS猫头猫        textAlign: 'center',
501*ea6d708fS猫头猫    },
502*ea6d708fS猫头猫    panelEmpty: {
503*ea6d708fS猫头猫        flex: 1,
504*ea6d708fS猫头猫        alignItems: 'center',
505*ea6d708fS猫头猫        justifyContent: 'center',
506*ea6d708fS猫头猫    },
507*ea6d708fS猫头猫    homeBtn: {
508*ea6d708fS猫头猫        width: 60,
509*ea6d708fS猫头猫        paddingVertical: 5,
510*ea6d708fS猫头猫        backgroundColor: '#04be02',
511*ea6d708fS猫头猫        borderRadius: 4,
512*ea6d708fS猫头猫        alignItems: 'center',
513*ea6d708fS猫头猫        justifyContent: 'center',
514*ea6d708fS猫头猫        position: 'absolute',
515*ea6d708fS猫头猫        zIndex: 99999,
516*ea6d708fS猫头猫        bottom: height / 2,
517*ea6d708fS猫头猫        right: 0,
518*ea6d708fS猫头猫        shadowColor: 'rgb(18,34,74)',
519*ea6d708fS猫头猫        shadowOffset: {width: 0, height: 1},
520*ea6d708fS猫头猫        shadowOpacity: 0.08,
521*ea6d708fS猫头猫        elevation: 99999,
522*ea6d708fS猫头猫    },
523*ea6d708fS猫头猫    homeBtnText: {
524*ea6d708fS猫头猫        color: '#fff',
525*ea6d708fS猫头猫    },
526*ea6d708fS猫头猫    commandBar: {
527*ea6d708fS猫头猫        borderWidth: StyleSheet.hairlineWidth,
528*ea6d708fS猫头猫        borderColor: '#d9d9d9',
529*ea6d708fS猫头猫        flexDirection: 'row',
530*ea6d708fS猫头猫        height: 40,
531*ea6d708fS猫头猫    },
532*ea6d708fS猫头猫    commandBarInput: {
533*ea6d708fS猫头猫        flex: 1,
534*ea6d708fS猫头猫        paddingLeft: 10,
535*ea6d708fS猫头猫        backgroundColor: '#ffffff',
536*ea6d708fS猫头猫        color: '#000000',
537*ea6d708fS猫头猫    },
538*ea6d708fS猫头猫    commandBarBtn: {
539*ea6d708fS猫头猫        width: 40,
540*ea6d708fS猫头猫        alignItems: 'center',
541*ea6d708fS猫头猫        justifyContent: 'center',
542*ea6d708fS猫头猫        backgroundColor: '#eee',
543*ea6d708fS猫头猫    },
544*ea6d708fS猫头猫    historyContainer: {
545*ea6d708fS猫头猫        borderTopWidth: 1,
546*ea6d708fS猫头猫        borderTopColor: '#d9d9d9',
547*ea6d708fS猫头猫        backgroundColor: '#ffffff',
548*ea6d708fS猫头猫        paddingHorizontal: 10,
549*ea6d708fS猫头猫    },
550*ea6d708fS猫头猫});
551*ea6d708fS猫头猫
552*ea6d708fS猫头猫export default VDebug;
553