소스 검색

add components/Switch.js

wudebin 6 달 전
부모
커밋
807fc8faa2

+ 34 - 0
Strides-SPAPP/app/components/Switch.js

@@ -0,0 +1,34 @@
+/**
+ * 自定义Switch组件
+ * @邠心vbe on 2023/08/30
+ */
+import React from 'react';
+import { Switch, SwitchProps, Text, View } from 'react-native';
+import Animated from 'react-native-reanimated';
+import utils from '../utils/utils';
+
+//const switchStyle = { false: "#B2B2B2", true: colorAccent };
+
+export default SwitchBase = (props, {...SwitchProps}) => {
+  const colors = utils.hexColorToRgb(colorAccent);
+  var thumbColor = null;
+  var trackColor = { false: "#B2B2B2", true: colorAccent }
+  if (!isIOS) {
+    thumbColor = (props.value ? utils.getRgbaColor(colors, 0.9) : "#EBEDEC")
+    trackColor = {false: "#B2B2B2", true: utils.getRgbaColor(colors, 0.3)}
+  }
+  return (
+    <Animated.View style={ui.flexc}>
+      <Switch
+        {...props}
+        trackColor={trackColor}
+        thumbColor={thumbColor}
+      />
+      {/* <Switch
+        {...props}
+      />
+      <Text style={{color: utils.getRgbaColor(colors, 0.9)}}>■■■</Text>
+      <Text style={{color: utils.getRgbaColor(colors, 0.3)}}>■■■</Text> */}
+    </Animated.View>
+  );
+}

+ 101 - 0
Strides-SPAPP/app/components/TextView.js

@@ -0,0 +1,101 @@
+/**
+ * 自定义Text组件
+ * @邠心vbe on 2023/08/30
+ */
+import React from 'react';
+import { Text, View } from 'react-native';
+import app from '../../app.json';
+
+const getRadius = (style, fixedAlign) => {
+  let s = undefined;
+  if (Array.isArray(style)) {
+    let res = {}
+    for (let s of style) {
+      res = {...res, ...s};
+    }
+    s = res;
+  } else {
+    s = style
+  }
+  var view = {}, text = {}
+  for (let name in s) {
+    if (name.indexOf('margin') >= 0) {
+      view[name] = s[name];
+      continue;
+    }
+    if (name.indexOf('padding') >= 0) {
+      view[name] = s[name];
+      continue;
+    }
+    if (name.indexOf('color') == 0) {
+      text[name] = s[name];
+      continue;
+    }
+    if (name.indexOf('font') >= 0) {
+      text[name] = s[name];
+      continue;
+    }
+    if (name.indexOf('border') >= 0) {
+      view[name] = s[name];
+      continue;
+    }
+    if (name.indexOf('background') >= 0) {
+      view[name] = s[name];
+      continue;
+    }
+    if (name.indexOf('text') >= 0) {
+      text[name] = s[name];
+      continue;
+    } 
+    if (name.indexOf('position') >= 0) {
+      view[name] = s[name];
+      continue;
+    }
+    if (name.indexOf('line') >= 0) {
+      text[name] = s[name];
+      continue;
+    }
+    view[name] = s[name];
+  }
+  if (fixedAlign) {
+    //修复RN0.7x+渲染中文无法对齐
+    if (view.alignItems == undefined && view.flexDirection == undefined && text.textAlign == undefined) {
+      view.alignItems = "center";
+      view.flexDirection = "row";
+    }
+    if (!text.lineHeight) {
+      if (text.fontSize) {
+        text.lineHeight = text.fontSize * 1.3;
+      } else {
+        text.fontSize = 14;
+        text.lineHeight = 18.2;
+      }
+    }
+    /*if (text.fontSize && app.isLumiWhitelabel) {
+      text.fontSize -= 2;
+    }*/
+    text.includeFontPadding = false;
+  }
+  return {
+    view: view,
+    text: text
+  }
+}
+
+const TextView = ({style, ellipsizeMode, numberOfLines, allowFontScaling=false, onPress, onLongPress, fixedAlign=true, selectable, children}) => {
+  const styles = getRadius(style, fixedAlign);
+  return (
+    <View style={styles.view}>
+      <Text
+        style={styles.text}
+        allowFontScaling={allowFontScaling}
+        ellipsizeMode={ellipsizeMode}
+        numberOfLines={numberOfLines}
+        selectable={selectable}
+        onPress={onPress}
+        onLongPress={onLongPress}>{children}</Text>
+    </View>
+  );
+};
+
+export default TextView;

+ 24 - 0
Strides-SPAPP/app/components/ThemesConfig.js

@@ -0,0 +1,24 @@
+import React from "react";
+import { View } from "react-native";
+import app from '../../app.json';
+
+export const MyRefreshProps = () => ({
+  title: global.$t('common.pulldown2Refresh'),
+  titleColor: textCancel,
+  colors: [colorAccent, colorPrimary],
+  tintColor: colorAccent
+})
+
+export const UploadThemes = {
+  cropperStatusBarColor: app.isWhitelabel ? "#CCCCCC" : colorPrimary,
+  cropperToolbarColor: app.isWhitelabel ? colorLight : colorPrimary,
+  //cropperTintColor: colorAccent,
+  cropperActiveWidgetColor: colorAccent,
+  cropperToolbarWidgetColor: pageTitleTint
+}
+
+export const TestThemes = () => {
+  return (
+    <View/>
+  )
+}

+ 154 - 0
Strides-SPAPP/app/components/Toolbar.js

@@ -0,0 +1,154 @@
+import React, { useEffect, useState } from 'react';
+import { Pressable, StyleSheet, View } from 'react-native';
+import TopChargeBackground from '../icons/TopChargeBackground';
+import HeaderTitle from './HeaderTitle';
+
+export const BackButton = ({style=Styles.backIcon, color=pageTitleTint, children, onPress}) => {
+  return (
+    <Pressable
+      style={({pressed }) => [
+        (pressed && isIOS) && {
+          opacity: 0.5
+        },
+        style
+      ]}
+      android_ripple = {rippleLessIcon}
+      onPress={() => {
+        if (onPress) {
+          onPress();
+        } else {
+          goBack();
+        }
+      }}>
+      { children
+      ? children
+      : <BackIcon color={color}/>
+      }
+    </Pressable>
+  )
+}
+
+export const BackIcon = ({color=pageTitleTint}) => {
+  return (
+    <MaterialIcons
+      name={isIOS ? 'arrow-back-ios' : 'arrow-back'}
+      size={isIOS ? 20 : 24}
+      color={color}/>
+  )
+}
+
+export const StationBack = ({bottom = 24, scale=1.0}) => {
+  return (
+    // <Image
+    //   style={{
+    //     right: 0,
+    //     bottom: bottom,
+    //     width: 125.8,
+    //     height: 137.64,
+    //     position: 'absolute'
+    //   }}
+    //   source={require('../images/charge/bg-top-station.png')}/>
+    <View
+      style={{
+        right: 0,
+        bottom: bottom,
+        width: 127.5 * scale,
+        height: 136.67 * scale,
+        position: 'absolute',
+        alignItems: 'flex-end'
+      }}>
+      <TopChargeBackground width={127.5 * scale} height={136.67 * scale}/>
+    </View>
+  );
+}
+
+export default Toolbar = ({
+  style=Styles.toolbar,
+  title,
+  scope,
+  showBack=true,
+  rightIcon,
+  onBackPress,
+  height=toolbarSize,
+  children
+}) => {
+  const [viewStyle, setStyle] = useState({})
+  useEffect(() => {
+    if (isIOS) {
+      setStyle({
+        height: height + statusHeight,
+        paddingTop: statusHeight
+      })
+    }
+  }, []);
+  if (children) {
+    return (
+      <View style={[style, viewStyle]}>
+        {children}
+      </View>
+    )
+  } else {
+    return (
+      <View style={[style, viewStyle]}>
+        { showBack &&
+          <BackButton onPress={onBackPress}/>
+        }
+        <HeaderTitle scope={scope} title={title} style={Styles.titleText}/>
+        { rightIcon
+        ? rightIcon()
+        : showBack
+        ? <View style={Styles.backIcon}>
+            <MaterialIcons
+              name={'arrow-back-ios'}
+              size={16}
+              color={'transparent'} />
+          </View>
+        : <></>
+        }
+      </View>
+    )
+  }
+}
+
+export const Styles = StyleSheet.create({
+  toolbar: {
+    height: toolbarSize + statusHeight,
+    paddingLeft: isIOS ? 0 : 2,
+    paddingRight: isIOS ? 0 : 2,
+    paddingTop: statusHeight,
+    alignItems: 'center',
+    flexDirection: 'row',
+    justifyContent: 'center',
+    backgroundColor: colorPrimaryDark
+  },
+  backIcon: {
+    width: 48,
+    height: 48,
+    zIndex: 2,
+    alignItems: 'center',
+    justifyContent: 'center'
+  },
+  content: {
+    flex: 1,
+    paddingRight: 48,
+    alignItems: 'center'
+  },
+  logo: {
+    width:123.8,
+    height: 38.95
+  },
+  rightIcon: {
+    width: 22,
+    height: 22,
+    opacity: 0.9
+  },
+  iconOpacity: {
+    opacity: 0.9
+  },
+  titleText: {
+    flex: 1,
+    color: pageTitleTint,
+    paddingLeft: isIOS ? 8 : 16,
+    textAlign: isIOS ? 'center' : 'left'
+  }
+});

+ 67 - 0
Strides-SPAPP/app/components/ToolbarUgly.js

@@ -0,0 +1,67 @@
+import React from 'react';
+import { StyleSheet, TouchableOpacity, View } from 'react-native';
+import TextView from './TextView';
+
+export default ToolbarUgly = ({
+  title,
+  scope,
+  showBack=true,
+  rightIcon,
+  onBackPress
+}) => (
+  <View style={styles.toolbarUgly}>
+    { showBack &&
+      <TouchableOpacity
+        style={styles.uglyIcon}
+        onPress={() => {
+          if (onBackPress) {
+            onBackPress();
+          } else {
+            goBack();
+          }
+        }}>
+        <MaterialIcons
+          name={'arrow-back-ios'}
+          size={20}
+          color={textPrimary} />
+      </TouchableOpacity>
+    }
+    <TextView style={styles.titleText}>{scope ? $t(scope) : title}</TextView>
+    { rightIcon
+    ? rightIcon()
+    : showBack
+    ? <View style={styles.uglyIcon}>
+        <MaterialIcons
+          name={'arrow-back-ios'}
+          size={16}
+          color={'transparent'} />
+      </View>
+    : <></>
+    }
+  </View>
+)
+
+const styles = StyleSheet.create({
+  toolbarUgly: {
+    paddingTop: statusHeight,
+    alignItems: 'center',
+    flexDirection: 'row',
+    backgroundColor: colorLight
+  },
+  uglyIcon: {
+    height: 40,
+    paddingLeft: 16,
+    paddingRight: 8,
+    alignItems: 'center',
+    justifyContent: 'center'
+  },
+  titleText: {
+    flex: 1,
+    color: textPrimary,
+    padding: 0,
+    fontSize: 20,
+    fontWeight: 'bold',
+    textAlign: 'left',
+    //textTransform: 'uppercase'
+  }
+})