react-native-paper#TouchableRipple JavaScript Examples

The following examples show how to use react-native-paper#TouchableRipple. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: Image.js    From Legacy with Mozilla Public License 2.0 6 votes vote down vote up
export default function CompetitionImage({ type, count, viewMode }) {
  var { t } = useTranslation();
  var theme = useSelector(i => i.themes[i.theme]);
  var [open, setOpen] = React.useState(false);
  if(viewMode==="list") {
    return <View style={{ flexDirection: "row", alignItems: "center", paddingVertical: 2, width: 400, maxWidth: "100%", opacity: (count ?? 1) ? 1 : 0.2 }}>
      <Image style={{ height: 32, width: 32, marginHorizontal: 4 }} source={getIcon(type.icon?.includes?.('NA.png') ? 'https://server.cuppazee.app/missing.png' : type.icon)} />
      <Text style={{flex : 1, marginHorizontal: 4, fontWeight: "bold"}}>{count !== undefined ? `${count}x ` : ""}{type.name || t('inventory:unknown_name')}</Text>
      <Text style={{marginHorizontal: 4}}>{(count ?? 1) * (type.health ? type.health : -type.damage)} HP</Text>
    </View>
  }
  return <Menu
    visible={open}
    onDismiss={() => setOpen(false)}
    anchor={
      <TouchableRipple onPress={() => setOpen(true)}>
        <View key={type.icon} style={{ padding: 2, alignItems: "center", opacity: (count ?? 1) ? 1 : 0.2 }}>
          <Image style={{ height: 32, width: 32 }} source={getIcon(type.icon?.includes?.('NA.png') ? 'https://server.cuppazee.app/missing.png' : type.icon)} />
          <Text allowFontScaling={false} style={{ ...font(), color: theme.page_content.fg, fontSize: 16 }}>{(count ?? (type.health ? type.health : -type.damage)) || "-"}</Text>
        </View>
      </TouchableRipple>
    }
    contentStyle={{backgroundColor:theme.page_content.bg}}
  >
    <View style={{ paddingHorizontal: 4, alignItems: "center" }}>
      <Image style={{ height: 48, width: 48 }} source={getIcon(type.icon?.includes?.('NA.png') ? 'https://server.cuppazee.app/missing.png' : type.icon)} />
      <Text allowFontScaling={false} style={{ fontSize: 16, ...font("bold"), color: theme.page_content.fg }}>{count !== undefined ? `${count}x ` : ""}{type.name || t('inventory:unknown_name')}</Text>
      <Text allowFontScaling={false} style={{ fontSize: 16, ...font("bold"), color: theme.page_content.fg }}>{(count ?? 1) * (type.health ? type.health : -type.damage)} HP</Text>
    </View>
  </Menu>;
}
Example #2
Source File: Drawer.js    From Legacy with Mozilla Public License 2.0 6 votes vote down vote up
function DrawerItem(props) {
  return <TouchableRipple onPress={props.onPress} style={{
    marginHorizontal: 8, borderRadius: 20, opacity: 1 ?? props.style?.opacity ?? (props.focused ? 1 : 1),
    marginLeft: 0, marginRight: 4, borderTopLeftRadius: 0, borderBottomLeftRadius: 0
  }}>
    <View style={{
      padding: 4, paddingHorizontal: 8, borderRadius: 20, backgroundColor: props.focused ? props.activeBackgroundColor : "transparent", flexDirection: "row", alignItems: "center",
      borderTopLeftRadius: 0, borderBottomLeftRadius: 0
    }}>
      <View style={{height:32,width:32}}>
        <props.icon color={props.focused ? props.activeTintColor : props.inactiveTintColor} />
      </View>
      {!props.mini && <>
        <View style={{ width: 4 }}></View>
        {typeof props.label == "string" ? <Text numberOfLines={1} ellipsizeMode="tail" allowFontScaling={false} style={{ color: props.focused ? props.activeTintColor : props.inactiveTintColor, fontSize: 14, ...font("500") }}>{props.label}</Text> : <props.label color={props.focused ? props.activeTintColor : props.inactiveTintColor} />}
      </>}
      <View style={{flex:1}}></View>
      {props.right && <View style={{height:32,width:32}}>
        <props.right color={props.focused ? props.activeTintColor : props.inactiveTintColor} />
      </View>}
    </View>
  </TouchableRipple>
}
Example #3
Source File: Card.js    From Legacy with Mozilla Public License 2.0 6 votes vote down vote up
export default function (props) {
  var theme = useSelector(i=>i.themes[i.theme]);
  return (
    <TouchableRipple rippleColor="rgba(0, 0, 0, .32)" style={{ flex: props.noFlex===undefined?1:null, borderRadius: 8 }} onPress={props.onPress}>
      <Surface style={{ ...(theme.page_content.border?{borderWidth:1,borderColor:theme.page_content.border}:{}), flex: props.noFlex===undefined?1:null, elevation: theme.page_content.border?0:4, padding: props.noPad === undefined ? 8 : 0, borderRadius: 8, backgroundColor: theme.page_content.bg, ...(props.cardStyle||{}) }}>
        {props.children}
      </Surface>
    </TouchableRipple>
  )
}
Example #4
Source File: Card.js    From Legacy with Mozilla Public License 2.0 6 votes vote down vote up
export default function UserActivityDash({ user_id, username, displayUsername }) {
  var { t } = useTranslation();
  var theme = useSelector(i => i.themes[i.theme])
  var nav = useNavigation();
  var moment = useMoment();
  var date = moment().tz('America/Chicago');
  var dateString = `${date.year()}-${(date.month() + 1).toString().padStart(2, '0')}-${(date.date()).toString().padStart(2, '0')}`
  const { data, status } = useAPIRequest({
    endpoint: 'user/activity',
    data: { day: dateString, user_id },
    cuppazee: true
  }, true)
  return (
    <Card noPad>
      <TouchableRipple onPress={displayUsername ? () => nav.navigate('UserDetails', { username: username }) : () => nav.navigate('UserActivity', { username: username })}>
        <View style={{ ...(theme.page_content.border ? { borderBottomWidth: 1, borderBottomColor: theme.page_content.border } : {}), backgroundColor: (theme.clanCardHeader || theme.navigation).bg, padding: 8, borderTopLeftRadius: 8, borderTopRightRadius: 8, flexDirection: "row", alignItems: "center" }}>
          {displayUsername ?
            <Image style={{ height: 32, width: 32, borderRadius: 16 }} source={{ uri: `https://munzee.global.ssl.fastly.net/images/avatars/ua${Number(user_id).toString(36)}.png` }} /> :
            <MaterialCommunityIcons style={{ marginHorizontal: 4 }} name="format-list-bulleted" size={24} color={(theme.clanCardHeader || theme.navigation).fg} />}
          <Text allowFontScaling={false} style={{ paddingLeft: 4, ...font("bold"), fontSize: 16, flex: 1, color: (theme.clanCardHeader || theme.navigation).fg }}>{displayUsername ? username : t('user:activity')}</Text>
          <MaterialCommunityIcons name="chevron-right" size={24} color={(theme.clanCardHeader || theme.navigation).fg} />
        </View>
      </TouchableRipple>
      {!status ?
        <View style={{ paddingBottom: 4 }}><ActivityOverview username={username} user_id={user_id} /></View> :
        (status === "loading" ? <View style={{ flex: 1, justifyContent: "center", alignItems: "center", padding: 8 }}>
          <ActivityIndicator size="large" color={theme.page_content.fg} />
        </View> : <View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
            <MaterialCommunityIcons name="alert" color={theme.page.fg} size={48} />
            <Text allowFontScaling={false} style={{ fontSize: 16, ...font("bold"), textAlign: "center", color: theme.page_content.fg }}>{t('error:' + status)}</Text>
          </View>)}
    </Card>
  );
}
Example #5
Source File: Overview.js    From Legacy with Mozilla Public License 2.0 6 votes vote down vote up
function OverviewItem({ i, total }) {
  var small = total > 25;
  var theme = useSelector(i => i.themes[i.theme]);
  var [open, setOpen] = React.useState(false);
  var nav = useNavigation();
  var { t } = useTranslation();
  return <Menu
    visible={open}
    onDismiss={() => setOpen(false)}
    anchor={
      <TouchableRipple onPress={() => setOpen(true)}>
        <View key={i.icon} style={{ padding: 2, alignItems: "center" }}>
          <Image style={{ height: small ? 24 : 32, width: small ? 24 : 32 }} source={getIcon(i[0])} />
          <Text allowFontScaling={false} style={{ color: theme.page_content.fg, ...font(), fontSize: 12 }}>{i[1].total}</Text>
          {hostIcon(i[0]) && <Image style={{ height: small ? 16 : 24, width: small ? 16 : 24, position: "absolute", right: small ? -3 : -5, bottom: small ? 18 : 15 }} source={hostIcon(i[0])} />}
        </View>
      </TouchableRipple>
    }
    style={{ marginTop: 61 }}
    contentStyle={{ backgroundColor: theme.page_content.bg, borderWidth: theme.page_content.border ? 1 : 0, borderColor: theme.page_content.border }}
  >
    <View style={{ paddingHorizontal: 4, alignItems: "center" }}>
      <View>
        <Image style={{ height: 48, width: 48 }} source={getIcon(i[0])} />
        {hostIcon(i[0]) && <Image style={{ height: 36, width: 36, position: "absolute", right: -7.5, bottom: -7.5 }} source={hostIcon(i[0])} />}
      </View>
      <Text allowFontScaling={false} style={{ color: theme.page_content.fg, fontSize: 16, ...font("bold") }}>{i[1].total}x {(getType(i[0]) || { name: i[0].slice(49, -4) }).name}</Text>
      <Text allowFontScaling={false} style={{ color: theme.page_content.fg, fontSize: 16, ...font("bold") }}>{t('activity:point', { count: i[1].points })}</Text>
      <Button
        mode="contained"
        style={{ backgroundColor: theme.navigation.bg }}
        onPress={() => { setOpen(false); nav.push('DBType', { munzee: i[0].slice(49, -4) }) }}>
        {t('db:type_info')}
      </Button>
    </View>
  </Menu>
}
Example #6
Source File: Blast.js    From Legacy with Mozilla Public License 2.0 6 votes vote down vote up
function BlastType({ data, icon }) {
  var { t } = useTranslation();
  var theme = useSelector(i => i.themes[i.theme]);
  var [open, setOpen] = React.useState(false);
  return <Menu
    visible={open}
    onDismiss={() => setOpen(false)}
    anchor={
      <TouchableRipple onPress={() => setOpen(true)}>
        <View key={icon} style={{ padding: 2, alignItems: "center" }}>
          <Image style={{ height: 36, width: 36 }} source={getIcon(icon)} />
          <Text allowFontScaling={false} style={{ ...font(), color: theme.page_content.fg, fontSize: 16 }}>{data.total}</Text>
        </View>
      </TouchableRipple>
    }
    style={{ marginTop: 61 }}
  >
    <View style={{ paddingHorizontal: 4, alignItems: "center" }}>
      <Image style={{ height: 48, width: 48 }} source={getIcon(icon)} />
      <Text allowFontScaling={false} style={{ fontSize: 16, ...font("bold") }}>{data.total}x {getType(icon)?.name || icon}</Text>
      <Text allowFontScaling={false} style={{ fontSize: 16, ...font("bold") }}>{t('blast_checker:type_points',data.points)}</Text>
    </View>
  </Menu>;
}
Example #7
Source File: Colour.js    From Legacy with Mozilla Public License 2.0 6 votes vote down vote up
function SHCItem({ i, m }) {
  var {t} = useTranslation();
  var theme = useSelector(i => i.themes[i.theme]);
  var [open, setOpen] = React.useState(false);
  return <Menu
    visible={open}
    onDismiss={() => setOpen(false)}
    anchor={
      <TouchableRipple onPress={() => setOpen(true)}>
        <View key={i.icon} style={{ padding: 2, alignItems: "center", position: "relative" }}>
          <Image style={{ height: 32, width: 32 }} source={getIcon(i.pin)} />
          {m && <Image style={{ height: 20, width: 20, position: "absolute", bottom: 0, right: -4 }} source={getIcon(m.pin)} />}
        </View>
      </TouchableRipple>
    }
    style={{ marginTop: 61 }}
  >
    <View style={{ paddingHorizontal: 4, alignItems: "center" }}>
      <Image style={{ height: 48, width: 48 }} source={getIcon(i.pin)} />
      <Text allowFontScaling={false} style={{ fontSize: 12, ...font("bold") }}>{i.friendly_name}</Text>
      <Text allowFontScaling={false} style={{ fontSize: 12, ...font("bold") }}>{t('activity:by_user',{user:i.username})}</Text>
    </View>
  </Menu>;
}
Example #8
Source File: POI.js    From Legacy with Mozilla Public License 2.0 6 votes vote down vote up
function SHCItem({ i, m }) {
  var {t} = useTranslation();
  var theme = useSelector(i => i.themes[i.theme]);
  var [open, setOpen] = React.useState(false);
  return <Menu
    visible={open}
    onDismiss={() => setOpen(false)}
    anchor={
      <TouchableRipple onPress={() => setOpen(true)}>
        <View key={i.icon} style={{ padding: 2, alignItems: "center", position: "relative" }}>
          <Image style={{ height: 32, width: 32 }} source={getIcon(i.pin)} />
          {m && <Image style={{ height: 20, width: 20, position: "absolute", bottom: 0, right: -4 }} source={getIcon(m.pin)} />}
        </View>
      </TouchableRipple>
    }
    style={{ marginTop: 61 }}
  >
    <View style={{ paddingHorizontal: 4, alignItems: "center" }}>
      <Image style={{ height: 48, width: 48 }} source={getIcon(i.pin)} />
      <Text allowFontScaling={false} style={{ fontSize: 12, ...font("bold") }}>{i.friendly_name}</Text>
      <Text allowFontScaling={false} style={{ fontSize: 12, ...font("bold") }}>{t('activity:by_user',{user:i.username})}</Text>
    </View>
  </Menu>;
}
Example #9
Source File: SHCLite.js    From Legacy with Mozilla Public License 2.0 6 votes vote down vote up
function SHCItem({ i, m }) {
  var {t} = useTranslation();
  var theme = useSelector(i => i.themes[i.theme]);
  var [open, setOpen] = React.useState(false);
  return <Menu
    visible={open}
    onDismiss={() => setOpen(false)}
    anchor={
      <TouchableRipple onPress={() => setOpen(true)}>
        <View key={i.icon} style={{ padding: 2, alignItems: "center", position: "relative" }}>
          <Image style={{ height: 32, width: 32 }} source={getIcon(i.pin)} />
          {m && <Image style={{ height: 20, width: 20, position: "absolute", bottom: 0, right: -4 }} source={getIcon(m.pin)} />}
        </View>
      </TouchableRipple>
    }
    style={{ marginTop: 61 }}
  >
    <View style={{ paddingHorizontal: 4, alignItems: "center" }}>
      <Image style={{ height: 48, width: 48 }} source={getIcon(i.pin)} />
      <Text allowFontScaling={false} style={{ fontSize: 12, ...font("bold") }}>{i.friendly_name}</Text>
      <Text allowFontScaling={false} style={{ fontSize: 12, ...font("bold") }}>{t('activity:by_user',{user:i.username})}</Text>
    </View>
  </Menu>;
}
Example #10
Source File: SHCPro.js    From Legacy with Mozilla Public License 2.0 6 votes vote down vote up
function SHCItem({ i, m }) {
  var {t} = useTranslation();
  var theme = useSelector(i => i.themes[i.theme]);
  var [open, setOpen] = React.useState(false);
  return <Menu
    visible={open}
    onDismiss={() => setOpen(false)}
    anchor={
      <TouchableRipple onPress={() => setOpen(true)}>
        <View key={i.icon} style={{ padding: 2, alignItems: "center", position: "relative" }}>
          <Image style={{ height: 32, width: 32 }} source={getIcon(i.pin)} />
          {m && <Image style={{ height: 20, width: 20, position: "absolute", bottom: 0, right: -4 }} source={getIcon(m.pin)} />}
        </View>
      </TouchableRipple>
    }
    style={{ marginTop: 61 }}
  >
    <View style={{ paddingHorizontal: 4, alignItems: "center" }}>
      <Image style={{ height: 48, width: 48 }} source={getIcon(i.pin)} />
      <Text allowFontScaling={false} style={{ fontSize: 12, ...font("bold") }}>{i.friendly_name}</Text>
      <Text allowFontScaling={false} style={{ fontSize: 12, ...font("bold") }}>{t('activity:by_user',{user:i.username})}</Text>
    </View>
  </Menu>;
}
Example #11
Source File: Item.js    From Legacy with Mozilla Public License 2.0 6 votes vote down vote up
export default function InventoryItem({ i }) {
  var { t } = useTranslation();
  var theme = useSelector(i => i.themes[i.theme]);
  var [open, setOpen] = React.useState(false);
  return <Menu
    visible={open}
    onDismiss={() => setOpen(false)}
    anchor={
      <TouchableRipple onPress={() => setOpen(true)}>
        <View key={i.icon} style={{ padding: 2, alignItems: "center", opacity: i.amount ? 1 : 0.2 }}>
          <Image style={{ height: 36, width: 36 }} source={getIcon(i.icon?.includes?.('NA.png') ? 'https://server.cuppazee.app/missing.png' : i.icon)} />
          <Text allowFontScaling={false} style={{ ...font(), color: theme.page_content.fg, fontSize: 16 }}>{i.amount}</Text>
        </View>
      </TouchableRipple>
    }
    style={{ marginTop: 61 }}
    contentStyle={{backgroundColor:theme.page_content.bg}}
  >
    <View style={{ paddingHorizontal: 4, alignItems: "center" }}>
      <Image style={{ height: 48, width: 48 }} source={getIcon(i.icon?.includes?.('NA.png') ? 'https://server.cuppazee.app/missing.png' : i.icon)} />
      <Text allowFontScaling={false} style={{ fontSize: 16, ...font("bold"), color: theme.page_content.fg }}>{i.amount}x {i.name || t('inventory:unknown_name')}</Text>
    </View>
  </Menu>;
}
Example #12
Source File: POTMSept2020.js    From Legacy with Mozilla Public License 2.0 6 votes vote down vote up
function OverviewItem({ i, total }) {
  var small = total > 25;
  var theme = useSelector(i => i.themes[i.theme]);
  var [open, setOpen] = React.useState(false);
  var nav = useNavigation();
  var { t } = useTranslation();
  return <Menu
    visible={open}
    onDismiss={() => setOpen(false)}
    anchor={
      <TouchableRipple onPress={() => setOpen(true)}>
        <View key={i.icon} style={{ padding: 2, alignItems: "center" }}>
          <Image style={{ height: small ? 24 : 32, width: small ? 24 : 32 }} source={getIcon(i[0])} />
          <Text allowFontScaling={false} style={{ color: theme.page_content.fg, ...font(), fontSize: 12 }}>{i[1].total}</Text>
        </View>
      </TouchableRipple>
    }
    style={{ marginTop: 61 }}
    contentStyle={{ backgroundColor: theme.page_content.bg, borderWidth: theme.page_content.border ? 1 : 0, borderColor: theme.page_content.border }}
  >
    <View style={{ paddingHorizontal: 4, alignItems: "center" }}>
      <View>
        <Image style={{ height: 48, width: 48 }} source={getIcon(i[0])} />
      </View>
      <Text allowFontScaling={false} style={{ color: theme.page_content.fg, fontSize: 16, ...font("bold") }}>{i[1].total}x {(getType(i[0]) || { name: i[0].slice(49, -4) }).name}</Text>
      <Text allowFontScaling={false} style={{ color: theme.page_content.fg, fontSize: 16, ...font("bold") }}>{t('activity:point', { count: i[1].points })}</Text>
      <Button
        mode="contained"
        style={{ backgroundColor: theme.navigation.bg }}
        onPress={() => { setOpen(false); nav.push('DBType', { munzee: i[0].slice(49, -4) }) }}>
        {t('db:type_info')}
      </Button>
    </View>
  </Menu>
}
Example #13
Source File: NavLink.js    From mern-stack with MIT License 6 votes vote down vote up
NavLink = ({ navigation, text, routeName, disabled, theme }) => {
  return (
    <TouchableRipple
      disabled={disabled}
      onPress={() => navigation.navigate(routeName)}
    >
      <Text style={{ ...styles.link, color: theme.colors.primary }}>
        {text}
      </Text>
    </TouchableRipple>
  );
}
Example #14
Source File: Requirements.js    From Legacy with Mozilla Public License 2.0 5 votes vote down vote up
function ClanRequirement({ i, data, level_colors, s, t: ty, index }) {
  var theme = useSelector(i => i.themes[i.theme]);
  var [open, setOpen] = React.useState(false);
  var { t } = useTranslation();
  return <Menu
    visible={open}
    onDismiss={() => setOpen(false)}
    anchor={
      <TouchableRipple onPress={() => setOpen(true)}>
        <View style={{ ...((ty==="gro"&&index==0)?{borderLeftWidth:2*s,borderLeftColor:level_colors.border}:{}), height: (96 - 19) * s, borderBottomWidth: 2 * s, borderBottomColor: level_colors.border, padding: 4 * s, alignItems: "center",marginHorizontal:-1*s }}>
          <Image source={getIcon(data?.requirements?.[i]?.icon ?? data?.requirements?.[i]?.icons?.[tick % data?.requirements?.[i]?.icons?.length])} style={{ height: 36 * s, width: 36 * s }} />
          <Text allowFontScaling={false} numberOfLines={1} style={{ color: level_colors[ty].fg, textAlign: "center", ...font("bold"), fontSize: 12 * s }}>{t('clan_req:' + data?.requirements?.[i]?.top)}</Text>
          <Text allowFontScaling={false} numberOfLines={1} style={{ color: level_colors[ty].fg, textAlign: "center", ...font(), fontSize: 12 * s }}>{t('clan_req:' + data?.requirements?.[i]?.bottom)}</Text>
        </View>
      </TouchableRipple>
    }
    style={{ marginTop: (96 - 19) * s }}
    contentStyle={{ backgroundColor: theme.page_content.bg, borderWidth: theme.page_content.border ? 1 : 0, borderColor: theme.page_content.border }}
  >
    <View style={{ paddingHorizontal: 4, alignItems: "center" }}>
      <Text allowFontScaling={false} style={{ color: theme.page_content.fg, fontSize: 16, ...font("bold") }}>{data?.requirements?.[i]?.meta?.activity.map(y => ((data?.requirements?.[i]?.meta?.points || data?.requirements?.[i]?.meta?.days) ? {
        capture: 'Capture',
        deploy: 'Deploy',
        capon: 'Cap-on'
      } : {
          capture: 'Captures',
          deploy: 'Deploys',
          capon: 'Cap-ons'
        })[y]).join('/')}{data?.requirements?.[i]?.meta?.points && " Points"}{data?.requirements?.[i]?.meta?.days && " Days"}</Text>
      {(!data?.requirements?.[i]?.meta?.types && !data?.requirements?.[i]?.meta?.exclude) ?
        <Text allowFontScaling={false} style={{ color: theme.page_content.fg, fontSize: 16 }}>of All Types</Text> :
        (
          data?.requirements?.[i]?.meta?.types ?
            <>
              <Text allowFontScaling={false} style={{ color: theme.page_content.fg, fontSize: 16 }}>of these types:</Text>
              <View style={{ flexDirection: "row", flexWrap: "wrap", maxWidth: 300 }}>
                {types.filter(data?.requirements?.[i]?.meta?.types).filter(i => (!(data?.requirements?.[i]?.meta?.exclude || (() => false))(i))).slice(0, 15).map(i => <View style={{ padding: 4 }}>
                  <Image source={getIcon(i.icon)} style={{ height: 24 * s, width: 24 * s }} />
                </View>)}
                {types.filter(data?.requirements?.[i]?.meta?.types).filter(i => (!(data?.requirements?.[i]?.meta?.exclude || (() => false))(i))).length > 15 && <Text allowFontScaling={false} style={{ color: theme.page_content.fg, fontSize: 12 }}>and more</Text>}
              </View>
            </> :
            <>
              <Text allowFontScaling={false} style={{ color: theme.page_content.fg, fontSize: 16 }}>of All except these types:</Text>
              <View style={{ flexDirection: "row", flexWrap: "wrap", maxWidth: 300 }}>
                {types.filter(data?.requirements?.[i]?.meta?.exclude).slice(0, 15).map(i => <View style={{ padding: 4 }}>
                  <Image source={getIcon(i.icon)} style={{ height: 24 * s, width: 24 * s }} />
                </View>)}
                {types.filter(data?.requirements?.[i]?.meta?.exclude).length > 15 && <Text allowFontScaling={false} style={{ color: theme.page_content.fg, fontSize: 12 }}>and more</Text>}
              </View>
            </>
        )}
    </View>
  </Menu>
}
Example #15
Source File: Search.js    From Legacy with Mozilla Public License 2.0 5 votes vote down vote up
export default function SearchScreen({ navigation }) {
  var { t } = useTranslation();
  var theme = useSelector(i => i.themes[i.theme])
  var input = React.useRef();
  var [value, setValue] = React.useState('');
  var [search, setSearch] = React.useState('');
  var [timeoutC, setTimeoutC] = React.useState(null);
  function onValue(val) {
    if (timeoutC) clearTimeout(timeoutC)
    setValue(val);
    setTimeoutC(setTimeout(() => {
      return setSearch(val);
    }, 500))
  }
  var dispatch = useDispatch();

  var reqData = {
    endpoint: 'user/find',
    data: { text: search },
    cuppazee: true
  }
  var users = useSelector(i => i.request_data[stringify(reqData)] ?? {})
  useFocusEffect(
    React.useCallback(() => {
      if (search.length >= 1) dispatch(request.add(reqData))
      return () => {
        if (search.length >= 1) dispatch(request.remove(reqData))
      };
    }, [search])
  );
  return (
    <ScrollView
      contentContainerStyle={{ width: 600, maxWidth: "100%", alignItems: "stretch", flexDirection: "column", alignSelf: "center", padding: 4 }}
      style={{ flex: 1, backgroundColor: theme.page.bg }}>
      <View style={{ padding: 4, width: "100%" }}>
        <Card noPad cardStyle={{ flexDirection: "row", backgroundColor: "#fff", alignItems: "stretch" }}>
          <TextInput
            onSubmitEditing={() => setSearch(value)}
            ref={input}
            style={{ paddingHorizontal: 8, flex: 1, borderRadius: 8, borderBottomLeftRadius: 8, height: 40 }}
            onChangeText={onValue}
            value={value}
            returnKeyType="search"
          />
        </Card>
      </View>
      <View style={{ padding: 4 }}>
        <Card noPad>
          <View>
            {search.length < 3 && <Text allowFontScaling={false} style={{ textAlign: "center", ...font("bold"), fontSize: 16, color: theme.page_content.fg, marginVertical: 4 }}>Type in your Username</Text>}
            {search.length >= 3 && !users?.data?.users && <View style={{ height: 100, justifyContent: "center", alignItems: "center" }}>
              <ActivityIndicator size={32} color={theme.page_content.fg} />
            </View>}
            {users?.data?.users?.length === 0 && <Text allowFontScaling={false} style={{ textAlign: "center", ...font("bold"), fontSize: 16, color: theme.page_content.fg }}>{t('search:empty')}</Text>}
            {users?.data?.users?.slice?.(0, 20)?.map?.(i => <TouchableRipple onPress={() => navigation.navigate('CompetitionAuth', { username: i.username })}>
              <View key={i.clan_id} style={{ padding: 4, flexDirection: "row", alignItems: "center" }}>
                <Image style={{ height: 24, width: 24, marginRight: 8, marginLeft: 4, borderRadius: 12 }} source={{ uri: i.avatar ?? `https://munzee.global.ssl.fastly.net/images/avatars/ua${Number(i.user_id).toString(36)}.png` }} />
                <View style={{ flex: 1 }}>
                  <Text allowFontScaling={false} style={{ ...font("bold"), fontSize: 16, color: theme.page_content.fg }}>{i.username}</Text>
                  <Text allowFontScaling={false} style={{ ...font("bold"), fontSize: 12, color: theme.page_content.fg }}>#{i.user_id}</Text>
                </View>
                <MaterialCommunityIcons size={24} name="chevron-right" color={theme.page_content.fg} />
              </View>
            </TouchableRipple>)}
          </View>
        </Card>
      </View>
    </ScrollView>
  );
}
Example #16
Source File: Category.js    From Legacy with Mozilla Public License 2.0 5 votes vote down vote up
export default function SearchScreen({ navigation, route }) {
  var { t } = useTranslation();
  var moment = useMoment();
  var category = route.params.category;
  var theme = useSelector(i => i.themes[i.theme])
  var category_data = categories.find(i => i.id == category);
  var parent_datas = categories.filter(i => category_data.parents.includes(i.id));
  return (
    <ScrollView
      contentContainerStyle={{ width: 600, maxWidth: "100%", alignItems: "stretch", flexDirection: "column", alignSelf: "center", padding: 4 }}
      style={{ flex: 1, backgroundColor: theme.page.bg }}>
      <View style={{ padding: 4 }}>
        <Card noPad>
          <View>
            {parent_datas.map(parent_data => parent_data.id !== "root" ? <View style={{ padding: 4, flexDirection: "row", alignItems: "center" }}>
              <IconButton size={24} onPress={() => navigation.push('DBCategory', { category: parent_data.id })} icon="chevron-left" color={theme.page_content.fg} />
              <Image style={{ height: 32, width: 32, marginHorizontal: 8 }} source={getIcon(parent_data.custom_icon ?? parent_data.icon)} />
              <View style={{ flex: 1 }}>
                <Text allowFontScaling={false} style={{ ...font("bold"), fontSize: 16, color: theme.page_content.fg }}>{parent_data.name}</Text>
                <Text allowFontScaling={false} style={{ ...font("bold"), fontSize: 12, color: theme.page_content.fg }}>{t(`db:go_back`)}</Text>
              </View>
            </View> : <View style={{ padding: 4, flexDirection: "row", alignItems: "center" }}>
                <IconButton size={24} onPress={() => navigation.push('DBSearch')} icon="chevron-left" color={theme.page_content.fg} />
                {/* <Image style={{height:32,width:32,marginHorizontal:8}} source={{uri:parent_data.custom_icon??`https://munzee.global.ssl.fastly.net/images/pins/${encodeURIComponent(parent_data.icon)}.png`}} /> */}
                <View style={{ flex: 1 }}>
                  <Text allowFontScaling={false} style={{ ...font("bold"), fontSize: 16, color: theme.page_content.fg }}>{t('screens:DBSearch')}</Text>
                  <Text allowFontScaling={false} style={{ ...font("bold"), fontSize: 12, color: theme.page_content.fg }}>{t(`db:go_back`)}</Text>
                </View>
              </View>)}
            <Text allowFontScaling={false} style={{ ...font("bold"), fontSize: 24, color: theme.page_content.fg, padding: 4, textAlign: "center" }}>{category_data.name}</Text>
            {category_data?.seasonal && <>
              {/* <Text allowFontScaling={false} style={{...font("bold"),fontSize:20,color:theme.page_content.fg,textAlign:"center"}}>{category_data.id}</Text> */}
              <Text allowFontScaling={false} style={{ ...font(), textAlign: "center", color: theme.page_content.fg }}>{moment(category_data.seasonal.starts).format('L LT')} - {moment(category_data.seasonal.ends).format('L LT')}</Text>
              <Text allowFontScaling={false} style={{ ...font(), textAlign: "center", color: theme.page_content.fg }}>{t('bouncers:duration', { duration: moment.duration(moment(category_data.seasonal.starts).diff(moment(category_data.seasonal.ends))).humanize() })}</Text>
            </>}
            {[...types.filter(i => i.category === category), ...categories.filter(i => i.parents.includes(category))].filter(i => !i.hidden).map(i => <TouchableRipple key={i.id} onPress={i.category ? () => navigation.push('DBType', { munzee: i.icon }) : () => navigation.push('DBCategory', { category: i.id })}>
              <View style={{ padding: 8, flexDirection: "row", alignItems: "center" }}>
                <Image style={{ height: 32, width: 32, marginHorizontal: 4 }} source={getIcon(i.custom_icon ?? i.icon)} />
                <View style={{ flex: 1 }}>
                  <Text allowFontScaling={false} style={{ ...font("bold"), fontSize: 16, color: theme.page_content.fg }}>{i.name}</Text>
                  <Text allowFontScaling={false} style={{ ...font("bold"), fontSize: 12, color: theme.page_content.fg }}>{i.category ? `#${i.id}` : t(`db:category`)}</Text>
                </View>
                <MaterialCommunityIcons size={24} name="chevron-right" color={theme.page_content.fg} />
              </View>
            </TouchableRipple>)}
          </View>
        </Card>
      </View>
    </ScrollView>
  );
}
Example #17
Source File: Search.js    From Legacy with Mozilla Public License 2.0 5 votes vote down vote up
export default function SearchScreen({ navigation }) {
  var { t } = useTranslation()
  var theme = useSelector(i => i.themes[i.theme])
  var input = React.useRef();
  var [value, setValue] = React.useState('');
  var [search, setSearch] = React.useState('');
  var [timeoutC, setTimeoutC] = React.useState(null);
  function onValue(val) {
    if (timeoutC) clearTimeout(timeoutC)
    setValue(val);
    setTimeoutC(setTimeout(() => {
      return setSearch(val);
    }, 500))
  }
  var list = search.length >= 3 ? fuse.search(search) : [];
  return (
    <ScrollView
      contentContainerStyle={{ width: 600, maxWidth: "100%", alignItems: "stretch", flexDirection: "column", alignSelf: "center", padding: 4 }}
      style={{ flex: 1, backgroundColor: theme.page.bg }}>
      <View style={{ padding: 4, width: "100%" }}>
        <Card noPad cardStyle={{ flexDirection: "row", backgroundColor: "#fff", alignItems: "stretch" }}>
          <TextInput
            onSubmitEditing={() => setSearch(value)}
            ref={input}
            style={{ paddingHorizontal: 8, flex: 1, borderRadius: 8, borderBottomLeftRadius: 8, height: 40 }}
            onChangeText={onValue}
            value={value}
            returnKeyType="search"
          />
        </Card>
      </View>
      <View style={{ padding: 4 }}>
        <Card noPad>
          <View>
            {search.length < 3 && <Text allowFontScaling={false} style={{ textAlign: "center", ...font("bold"), fontSize: 16, color: theme.page_content.fg }}>{t('search:type')}</Text>}
            {search.length >= 3 && list.length === 0 && <Text allowFontScaling={false} style={{ textAlign: "center", ...font("bold"), fontSize: 16, color: theme.page_content.fg }}>No Results {":("}</Text>}
            {
              (search.length < 3 ?
                categories.filter(i => i.parents.includes('root')).filter(i => !i.hidden).map(i => ({ item: i })) :
                list.slice(0, 20))
                .map(({ item: i }) => <TouchableRipple key={i.id} onPress={i.category ? () => navigation.navigate('DBType', { munzee: i.icon }) : () => navigation.navigate('DBCategory', { category: i.id })}>
                  <View style={{ padding: 8, flexDirection: "row", alignItems: "center" }}>
                    <Image style={{ height: 32, width: 32, marginHorizontal: 4 }} source={getIcon(i.custom_icon ?? i.icon)} />
                    <View style={{ flex: 1 }}>
                      <Text allowFontScaling={false} style={{ ...font("bold"), fontSize: 16, color: theme.page_content.fg }}>{i.name}</Text>
                      <Text allowFontScaling={false} style={{ ...font("bold"), fontSize: 12, color: theme.page_content.fg }}>{i.category ? `#${i.id}` : t(`db:category`)}</Text>
                    </View>
                    <MaterialCommunityIcons size={24} name="chevron-right" color={theme.page_content.fg} />
                  </View>
                </TouchableRipple>)
            }
          </View>
        </Card>
      </View>
    </ScrollView>
  );
}
Example #18
Source File: Bouncers.js    From Legacy with Mozilla Public License 2.0 5 votes vote down vote up
export default function SearchScreen({ navigation }) {
  var {t} = useTranslation();
  var moment = useMoment();
  var theme = useSelector(i => i.themes[i.theme])
  function hasChild(cat) {
    return !!categories.find(i => i.parents.includes(cat.id));
  }
  var data = useAPIRequest({
    endpoint: 'bouncers/overview/v1',
    cuppazee: true
  })
  function get(i) {
    var x = 0;
    for(var icon of [i.icon,...i.alt_icons||[]]) {
      x = (data||{})[`https://munzee.global.ssl.fastly.net/images/pins/${icon}.png`]||x;
    }
    return x;
  }
  return (
    <ScrollView
      contentContainerStyle={{ width: 800, maxWidth: "100%", alignItems: "stretch", flexDirection: "column", alignSelf: "center", padding: 4 }}
      style={{ flex: 1, backgroundColor: theme.page.bg }}>
      {Object.entries(data||{}).filter(i=>!getType(i[0])).length>0&&<View style={{ padding: 4 }}>
        <Card noPad>
          <View>
            <View style={{flexDirection:"row",justifyContent:"center",alignItems:"center"}}>
              <Text allowFontScaling={false} style={{ ...font("bold"), fontSize: 24, color: theme.page_content.fg, paddingVertical: 4, textAlign: "center" }}>Uncategorised</Text>
              {/* <IconButton icon="map" color={theme.page_content.fg} onPress={()=>navigation.navigate("BouncerMap",{type:cdata.id})} /> */}
            </View>
            <View style={{flexDirection:"row",flexWrap:"wrap",justifyContent:"center"}}>
              {Object.entries(data||{}).filter(i=>!getType(i[0])).map(i => <TouchableRipple>
                <View key={i.id} style={{ padding: 4, width: 80, alignItems: "center", opacity: i[1]>0?1:0.4 }}>
                  <Image style={{ height: 32, width: 32, marginHorizontal: 8 }} source={getIcon(i[0])} />
                  <Text allowFontScaling={false} numberOfLines={1} ellipsizeMode="middle" style={{ ...font("bold"), fontSize: 12, color: theme.page_content.fg }}>{i[0].replace(/https:\/\/munzee.global.ssl.fastly.net\/images\/pins\/(.+)\.png/,'$1')}</Text>
                  <Text allowFontScaling={false} style={{ ...font("bold"), fontSize: 16, color: theme.page_content.fg }}>{i[1].toString()}</Text>
                </View>
              </TouchableRipple>)}
            </View>
          </View>
        </Card>
      </View>}
      {[...categories.filter(i=>i.seasonal&&i.seasonal.starts<Date.now()&&i.seasonal.ends>Date.now()),...categories.filter(i => i.parents.includes('bouncer')),...categories.filter(i => i.id=="temppob_other"),...categories.filter(i => i.id=="temppob_evo"),...categories.filter(i => i.id=="scatter")].filter(i => !hasChild(i)).filter(i=>!i.hidden&&i.id!="bouncerhost").map(cdata=><View style={{ padding: 4 }}>
        <Card noPad>
          <View>
            <View style={{flexDirection:"row",justifyContent:"center",alignItems:"center"}}>
              <Text allowFontScaling={false} style={{ ...font("bold"), fontSize: 24, color: theme.page_content.fg, paddingVertical: 4, textAlign: "center" }}>{cdata.name}</Text>
              <IconButton icon="map" color={theme.page_content.fg} onPress={()=>navigation.navigate("BouncerMap",{type:cdata.id})} />
            </View>
            {cdata?.seasonal && <>
              {/* <Text allowFontScaling={false} style={{...font("bold"),fontSize:20,color:theme.page_content.fg,textAlign:"center"}}>{category_data.id}</Text> */}
              <Text allowFontScaling={false} style={{ ...font(), textAlign: "center", color: theme.page_content.fg }}>{moment(cdata.seasonal.starts).format('L LT')} - {moment(cdata.seasonal.ends).format('L LT')}</Text>
              <Text allowFontScaling={false} style={{ ...font(), textAlign: "center", color: theme.page_content.fg }}>{t('bouncers:duration',{duration:moment.duration(moment(cdata.seasonal.starts).diff(moment(cdata.seasonal.ends))).humanize()})}</Text>
            </>}
            <View style={{flexDirection:"row",flexWrap:"wrap",justifyContent:"center"}}>
              {types.filter(i => i.category === cdata.id).filter(i=>!i.hidden&&!i.capture_only).map(i => <TouchableRipple onPress={()=>navigation.navigate("BouncerMap",{type:i.icon})}>
                <View key={i.id} style={{ padding: 4, width: 80, alignItems: "center", opacity: get(i)>0?1:0.4 }}>
                  <Image style={{ height: 32, width: 32, marginHorizontal: 8 }} source={getIcon(i.custom_icon ?? i.icon)} />
                  <Text allowFontScaling={false} numberOfLines={1} ellipsizeMode="middle" style={{ ...font("bold"), fontSize: 12, color: theme.page_content.fg }}>{i.name}</Text>
                  <Text allowFontScaling={false} style={{ ...font("bold"), fontSize: 16, color: theme.page_content.fg }}>{get(i).toString()}</Text>
                </View>
              </TouchableRipple>)}
            </View>
          </View>
        </Card>
      </View>)}
    </ScrollView>
  );
}
Example #19
Source File: ListItem.js    From Legacy with Mozilla Public License 2.0 5 votes vote down vote up
export default function ActivityListItem({ act: acti, userdata }) {
  var moment = useMoment();
  var { t } = useTranslation();
  var theme = useSelector(i => i.themes[i.theme]);
  var navigation = useNavigation();
  return <View style={{ padding: 4 }}>
    <Card noPad>
      {[acti,...acti.subCaptures||[]].map((act,index,list)=><TouchableRipple key={act.key} onPress={() => { navigation.navigate('MunzeeDetails', { username: act.creator, code: act.code }) }}>
        <View style={{ flexDirection: "row", alignItems: "center" }}>
          <View style={{ width: 60, paddingVertical: 4, marginRight: 4, borderTopLeftRadius: index===0?8:0, borderBottomLeftRadius: index===list.length-1?8:0, backgroundColor: theme.dark ? null : theme.activity[act.type]?.bg, borderRightWidth: theme.dark ? 2 : 0, borderRightColor: theme.activity[act.type]?.fg, position: "relative", alignContent: 'center', alignItems: "center", flexGrow: 0 }}>
            <View style={{ justifyContent: 'center', flexDirection: "row", flexWrap: "wrap", flexGrow: 0 }}>
              <View style={{ paddingHorizontal: 8, borderRadius: 9.5 }}>
                <Text allowFontScaling={false} style={{ alignSelf: "stretch", textAlign: "center", color: theme.activity[act.type]?.fg, ...font("bold") }}>{(act.points) > 0 && '+'}{(Number(act.points)) || t('activity:none')}</Text>
              </View>
            </View>
            <View style={{ position: 'relative' }}>
              <Image style={{ height: 32, width: 32 }} source={getIcon(act.pin)} />
              {hostIcon(act.pin) && <Image style={{ height: 24, width: 24, position: "absolute", right: -5, bottom: -4 }} source={hostIcon(act.pin)} />}
            </View>
          </View>
          <View style={{ flex: 1 }}>
            {index===0&&<Text allowFontScaling={false} numberOfLines={1} ellipsizeMode="middle" style={{ color: theme.page_content.fg, ...font() }}>
              {({
                capon_reno: () => t('activity:user_renovated', { user: act.capper }),
                capon: () => t('activity:user_captured', { user: act.capper }),
                capture_reno: () => t('activity:you_renovated'),
                capture: () => t('activity:you_captured'),
                deploy: () => t('activity:you_deployed')
              })[act.type + (isRenovation(act) ? "_reno" : "")]?.() || "What"}
            </Text>}
            {!isRenovation(act) && <Text allowFontScaling={false} numberOfLines={1} ellipsizeMode="middle" style={{ color: theme.page_content.fg, ...font("bold") }}>{act.name}</Text>}
            {!isRenovation(act) && <Text allowFontScaling={false} numberOfLines={1} ellipsizeMode="middle" style={{ color: theme.page_content.fg, opacity: 0.8, ...font() }}>
              {({
                capon: () => t('activity:by_you'),
                capture: () => act.creator === userdata?.username ? t('activity:by_you') : t('activity:by_user', { user: act.creator }),
                deploy: () => t('activity:by_you')
              })[act.type]?.() || "What"}
            </Text>}
          </View>
          <View style={{ padding: 8, flexGrow: 0, paddingLeft: 16, alignContent: 'center', position: "relative", alignItems: "flex-end" }}>
            {(moment(act.time).tz('America/Chicago').format('DD/MM') !== moment(act.time).format('DD/MM')) && <Text allowFontScaling={false} style={{ alignSelf: "stretch", textAlign: "right", fontSize: 10, color: theme.page_content.fg, ...font("bold") }}>{moment(act.time).format('DD/MM')}</Text>}
            <Text allowFontScaling={false} style={{ alignSelf: "stretch", textAlign: "right", color: theme.page_content.fg, ...font("bold") }}>{moment(act.time).format('LT')}</Text>
            <Text allowFontScaling={false} style={{ alignSelf: "stretch", textAlign: "right", fontSize: 10, color: theme.page_content.fg, ...font("bold") }}>Local</Text>
          </View>
        </View>
      </TouchableRipple>)}
    </Card>
  </View>
}
Example #20
Source File: Leaderboard.js    From Legacy with Mozilla Public License 2.0 5 votes vote down vote up
UserTile = React.memo(function ({ i, index, week }) {
  var theme = useSelector(i => i.themes[i.theme]);
  var [open, setOpen] = React.useState(false);
  var dark = false;
  var route = useRoute();
  var level_colors = useLevelColours();
  if (theme.dark) {
    dark = true;
  }
  const types = week?.requirements ?? []
  var user = useAPIRequest(open ? {
    endpoint: `weekly/player/v1`,
    data: {
      user_id: i.i,
      week_id: route.params.week
    },
    cuppazee: true
  } : null)
  return <View style={{ padding: 4 }}>
    <Card noPad>
      <TouchableRipple onPress={() => {
        setOpen(!open)
      }}>
        <View style={{ flexDirection: "row", alignItems: "center" }}>
          <View style={{ paddingHorizontal: 8, paddingVertical: 4 }}>
            <Image source={getIcon(`https://munzee.global.ssl.fastly.net/images/avatars/ua${i?.i?.toString?.(36)}.png`)} style={{ width: 36, height: 36, borderRadius: 18 }} />
          </View>
          <View style={{ paddingHorizontal: 8, paddingLeft: 0, flex: 1, flexDirection: "row", alignItems: "center" }}>
            <Text allowFontScaling={false} style={{ fontSize: 16, ...font("bold"), color: theme.page_content.fg }} numberOfLines={1} ellipsizeMode={"tail"}>#{index + 1} - {i.n}</Text>
          </View>
          <View style={{ alignSelf: "stretch", borderTopRightRadius: 8, borderBottomRightRadius: open ? 0 : 8, borderLeftWidth: dark ? 2 : 0, borderLeftColor: dark ? level_colors[Math.max(0, Math.min(Math.ceil(i.p / 50), 5))].bg : undefined, backgroundColor: dark ? undefined : level_colors[Math.max(0, Math.min(Math.ceil(i.p / 50), 5))].bg, width: 60, flexDirection: "row", alignItems: "center", justifyContent: "center" }}>
            <Text allowFontScaling={false} style={{ color: level_colors[Math.max(0, Math.min(Math.ceil(i.p / 50), 5))].fg, fontSize: 16, ...font("bold") }}>{i.p?.toLocaleString?.() || "0"}</Text>
            {week && !!i.f && status(week) === "resultssoon" && <MaterialCommunityIcons name="check-bold" color={theme.page_content.fg} style={{ marginLeft: 4 }} size={16} />}
          </View>
        </View>
      </TouchableRipple>
      <Portal>
        <Dialog
          visible={open}
          onDismiss={() => { setOpen(false) }}
          style={{ maxWidth: 390, alignSelf: "center", borderRadius: 8, backgroundColor: theme.page_content.bg }}>
          <View style={{ flexDirection: "row", alignItems: "center" }}>
            <View style={{ paddingHorizontal: 8, paddingVertical: 4 }}>
              <Image source={getIcon(`https://munzee.global.ssl.fastly.net/images/avatars/ua${i?.i?.toString?.(36)}.png`)} style={{ width: 36, height: 36, borderRadius: 18 }} />
            </View>
            <View style={{ paddingHorizontal: 8, paddingLeft: 0, flex: 1, justifyContent: "center" }}>
              <Text allowFontScaling={false} style={{ fontSize: 16, ...font("bold"), color: theme.page_content.fg }} numberOfLines={1} ellipsizeMode={"tail"}>#{index + 1} - {i.n}</Text>
            </View>
            <View style={{ alignSelf: "stretch", borderTopRightRadius: 8, borderBottomRightRadius: open ? 0 : 8, borderLeftWidth: dark ? 2 : 0, borderLeftColor: dark ? level_colors[Math.max(0, Math.min(Math.ceil(i.p / 50), 5))].bg : undefined, backgroundColor: dark ? undefined : level_colors[Math.max(0, Math.min(Math.ceil(i.p / 50), 5))].bg, width: 60, alignItems: "center", justifyContent: "center" }}>
              <Text allowFontScaling={false} style={{ color: level_colors[Math.max(0, Math.min(Math.ceil(i.p / 50), 5))].fg, fontSize: 16, ...font("bold") }}>{i.p?.toLocaleString?.() || "0"}</Text>
            </View>
          </View>
          <View style={{ flexDirection: "row", alignItems: "center", flexWrap: "wrap" }}>
            {types.map((x, xi) => <View key={x.id} style={{ padding: 4, width: 80, flexGrow: 1, alignItems: "center", opacity: ((user?.d || [])[xi] ?? 0) > 0 ? 1 : 0.4 }}>
              <Image style={{ height: 32, width: 32, marginHorizontal: 8 }} source={getIcon(x.type)} />
              <Text allowFontScaling={false} style={{ ...font("bold"), fontSize: 16, color: theme.page_content.fg }}>{(user?.d || [])[xi] ?? '?'}</Text>
            </View>)}
          </View>
        </Dialog>
      </Portal>
    </Card>
  </View>
})
Example #21
Source File: Weeks.js    From Legacy with Mozilla Public License 2.0 5 votes vote down vote up
export default function ClanScreen() {
  var moment = useMoment();
  var { t } = useTranslation();
  var theme = useSelector(i => i.themes[i.theme]);
  var dark = false;
  var level_colors = useLevelColours();
  if (theme.dark) {
    dark = true;
    level_colors.border = "#fffa"
  }
  var nav = useNavigation();
  var weeks = useAPIRequest({
    endpoint: 'weekly/weeks/v1',
    cuppazee: true
  });
  if (!weeks) return <View style={{ flex: 1, justifyContent: "center", alignItems: "center", backgroundColor: theme.page.bg }}>
    <ActivityIndicator size="large" color={theme.page.fg} />
  </View>
  return (
    <View style={{ flex: 1 }}>
      <ScrollView
        contentContainerStyle={{ width: 400, maxWidth: "100%", alignItems: "stretch", flexDirection: "column", alignSelf: "center", padding: 4, paddingBottom: 92 }}
        style={{ flex: 1, backgroundColor: theme.page.bg }}>
        {weeks.map(i => <View style={{ padding: 4 }}>
          <Card noPad>
            <TouchableRipple onPress={(status(i) !== "ongoing" && status(i) !== "resultssoon" && status(i) !== "finalresults") ? null : () => {
              nav.navigate('WeeklyLeaderboard', { week: i.id })
            }}>
              <View>
                <View style={{ flexDirection: "row", alignItems: "center" }}>
                  <View style={{ padding: 8 }}>
                    <Image source={getIcon(i.icon || i.id)} style={{ width: 48, height: 48 }} />
                  </View>
                  <View style={{ padding: 8, paddingLeft: 0, flex: 1, justifyContent: "center" }}>
                    <Text allowFontScaling={false} style={{ fontSize: 20, ...font("bold"), color: theme.page_content.fg }} numberOfLines={1} ellipsizeMode={"tail"}>{t('weekly:week',{n:i.week})}</Text>
                    <View style={{flexDirection: "row", alignItems: "center"}}><MaterialCommunityIcons name="information-outline" size={16} /><Text allowFontScaling={false} style={{ fontSize: 16, ...font("bold"), color: theme.page_content.fg, opacity: 0.8, textAlignVertical: "center" }}> {i.description}</Text></View>
                    <View style={{flexDirection: "row", alignItems: "center"}}><MaterialCommunityIcons name="calendar" size={16} /><Text allowFontScaling={false} style={{ fontSize: 16, ...font(500), color: theme.page_content.fg, opacity: 0.8, textAlignVertical: "center" }}> {t(`weekly:${statusKeys[status(i)]}_at`,{time:moment(i[statusTimeKeys[status(i)]]).format('L LT')})}</Text></View>
                  </View>
                  <View style={{ alignSelf: "stretch", borderTopRightRadius: 8, borderBottomRightRadius: status(i)==="finalresults"?8:0, borderLeftWidth: dark ? 2 : 0, borderLeftColor: dark ? level_colors[statusColor[status(i)]]?.bg : undefined, backgroundColor: dark ? undefined : level_colors[statusColor[status(i)]]?.bg, width: 100, alignItems: "center", justifyContent: "center" }}>
                    <Text allowFontScaling={false} numberOfLines={3} style={{ textAlign: "center", color: level_colors[statusColor[status(i)]]?.fg, fontSize: 16, ...font("bold") }}>{t(`weekly:status.${status(i)}`)}</Text>
                  </View>
                </View>
                {status(i)!=="finalresults"&&<View style={{ flexDirection: "row", alignItems: "center", flexWrap: "wrap" }}>
                  {i.requirements.map(x => <View key={x.id} style={{ padding: 4, width: 60, flexGrow: 1, alignItems: "center" }}>
                    <Image style={{ height: 32, width: 32, marginHorizontal: 8 }} source={getIcon(x.type)} />
                    <Text allowFontScaling={false} style={{ ...font("bold"), fontSize: 12, color: theme.page_content.fg }}>{t('weekly:points',{count:x.points})}</Text>
                  </View>)}
                </View>}
              </View>
            </TouchableRipple>
          </Card>
        </View>)}
      </ScrollView>
    </View>
  );
}
Example #22
Source File: sign.js    From astrale with GNU General Public License v3.0 5 votes vote down vote up
/**
 * @param sign {string}
 * @param title {string}
 * @param showTitle {boolean}
 * @param subtitle {string}
 * @param onPress {function}
 * @param style {object}
 * @param signHeight {string|number}
 * @param signWidth {string|number}
 * @param styleTitle {object}
 * @param styleSubtitle {object}
 * @returns {*}
 * @constructor
 */
function Sign({
  sign,
  title,
  showTitle,
  subtitle,
  onPress,
  style,
  signHeight,
  signWidth,
  styleTitle,
  styleSubtitle,
}) {
  const ParsedSign = signs[sign];
  const isAndroid = PlatformUtils.isAndroid;
  return (
    <TouchableRipple
      onPress={() => onPress(sign)}
      underlayColor="#ffffff00"
      rippleColor="#ffffff00"
      style={[{ alignItems: 'center', justifyContent: 'center' }, style]}
    >
      <>
        <View
          style={[
            {
              shadowColor: '#000000',
              width: signWidth,
              height: signHeight,
            },
            {
              elevation: isAndroid ? 0 : 10,
            },
            styles.signContainer,
            styles.signShadow,
          ]}
        >
          <ParsedSign width={signHeight} height={signWidth} />
        </View>
        {showTitle && (
          <Subheading style={styleTitle}>{title ?? i18n.t(sign)}</Subheading>
        )}
        {subtitle && <Caption style={styleSubtitle}>{subtitle}</Caption>}
      </>
    </TouchableRipple>
  );
}
Example #23
Source File: Requirements.js    From Legacy with Mozilla Public License 2.0 4 votes vote down vote up
export default function ClanRequirementsCard({ game_id, scale: s = 1, list }) {
  var moment = useMoment();
  var { t } = useTranslation();
  var theme = useSelector(i => i.themes[i.theme]);
  var [reward, setReward] = React.useState(false);
  var level_colors = useLevelColours();
  var unformatted_requirements = useAPIRequest({
    endpoint: 'clan/v2/requirements',
    data: { clan_id: 1349, game_id }
  })
  var unformatted_rewards = useAPIRequest({
    endpoint: 'clan/rewards/v1',
    data: {
      game_id
    },
    cuppazee: true
  })
  var data = ClanRequirementsConverter(unformatted_requirements, unformatted_rewards);
  if (!unformatted_requirements?.battle) {
    if (!unformatted_requirements) {
      return (
        <Card>
          <View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
            <ActivityIndicator size="large" color={theme.page_content.fg} />
          </View>
        </Card>
      )
    } else {
      return (
        <Card cardStyle={{ backgroundColor: theme.error.bg }}>
          <View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
            <Text allowFontScaling={false} style={{ color: theme.error.fg }}>An Error Occurred</Text>
          </View>
        </Card>
      );
    }
  }
  if (list) {
    if(unformatted_requirements && data?.levels?.length === 0) return null;
    return <Card noPad>
      <View style={{ ...(theme.dark ? { borderBottomWidth: 2 * s, borderBottomColor: level_colors.border } : {}), backgroundColor: (theme.clanCardHeader || theme.navigation).bg, paddingHorizontal: 8 * s, borderTopLeftRadius: 8 * s, borderTopRightRadius: 8 * s, flexDirection: "row", alignItems: "center" }}>
        <View style={{ flex: 1, paddingVertical: 8 * s }}>
          <Text allowFontScaling={false} style={{ color: (theme.clanCardHeader || theme.navigation).fg, ...font("bold"), fontSize: 12 * s, opacity: 0.7, lineHeight: 12 * s }}>{moment(dateFromGameID(game_id)).format('MMMM YYYY')}</Text>
          <Text allowFontScaling={false} style={{ color: (theme.clanCardHeader || theme.navigation).fg, ...font("bold"), fontSize: 16 * s, lineHeight: 16 * s }}>{reward ? t('clan:rewards') : t('clan:requirements')}</Text>
        </View>
      </View>
      <View style={{ padding: 4 }}>
        {data.levels.map(i => <View style={{ paddingBottom: 16 }}>
          <Text allowFontScaling={false} style={{ color: theme.page_content.fg, ...font(), fontSize: 24 * s }}>{t('clan:level_n', { level: i.level })}</Text>
          <Text allowFontScaling={false} style={{ color: theme.page_content.fg, ...font(), fontSize: 20 * s }}>{t('clan:individual')}</Text>
          {(data?.order?.individual ?? []).filter(r => i.individual[r]).map(r => <View style={{ flexDirection: "row", alignItems: "center", paddingVertical: 4 }}>
            <Image style={{ height: 24, width: 24, marginRight: 4 }} source={getIcon(data.requirements[r].icon)} />
            <Text allowFontScaling={false} style={{ color: theme.page_content.fg, ...font(), fontSize: 16 * s }}><Text style={font("bold")}>{i.individual[r].toLocaleString()}</Text> {t('clan_req:' + data?.requirements?.[r]?.top)} {t('clan_req:' + data?.requirements?.[r]?.bottom)}</Text>
          </View>)}
          <Text allowFontScaling={false} style={{ color: theme.page_content.fg, ...font(), fontSize: 20 * s, marginTop: 4 }}>{t('clan:group')}</Text>
          {(data?.order?.group ?? []).filter(r => i.group[r]).map(r => <View style={{ flexDirection: "row", alignItems: "center", paddingVertical: 4 }}>
            <Image style={{ height: 24, width: 24, marginRight: 4 }} source={getIcon(data.requirements[r].icon)} />
            <Text allowFontScaling={false} style={{ color: theme.page_content.fg, ...font(), fontSize: 16 * s }}><Text style={font("bold")}>{i.group[r].toLocaleString()}</Text> {t('clan_req:' + data?.requirements?.[r]?.top)} {t('clan_req:' + data?.requirements?.[r]?.bottom)}</Text>
          </View>)}
          <Text allowFontScaling={false} style={{ color: theme.page_content.fg, ...font(), fontSize: 20 * s, marginTop: 4 }}>{t('clan:rewards')}</Text>
          {(data?.order?.rewards ?? []).filter(r => i.rewards[r]).map(r => <View style={{ flexDirection: "row", alignItems: "center", paddingVertical: 4 }}>
            <Image style={{ height: 24, width: 24, marginRight: 4 }} source={getIcon(data.rewards[r].logo)} />
            <Text allowFontScaling={false} style={{ color: theme.page_content.fg, ...font(), fontSize: 16 * s }}><Text style={font("bold")}>{i.rewards[r].toLocaleString()}x</Text> {data.rewards[r].name}</Text>
          </View>)}
        </View>)}
      </View>
    </Card>
  }
  return (
    <Card noPad>
      <View style={{ ...(theme.dark ? { borderBottomWidth: 2 * s, borderBottomColor: level_colors.border } : {}), backgroundColor: (theme.clanCardHeader || theme.navigation).bg, paddingHorizontal: 8 * s, borderTopLeftRadius: 8 * s, borderTopRightRadius: 8 * s, flexDirection: "row", alignItems: "center" }}>
        <View style={{ flex: 1, paddingVertical: 8 * s }}>
          <Text allowFontScaling={false} style={{ color: (theme.clanCardHeader || theme.navigation).fg, ...font("bold"), fontSize: 12 * s, opacity: 0.7, lineHeight: 12 * s }}>{moment(dateFromGameID(game_id)).format('MMMM YYYY')}</Text>
          <Text allowFontScaling={false} style={{ color: (theme.clanCardHeader || theme.navigation).fg, ...font("bold"), fontSize: 16 * s, lineHeight: 16 * s }}>{reward ? t('clan:rewards') : t('clan:requirements')}</Text>
        </View>
        <TouchableRipple style={{ borderRadius: 24 * s, padding: 4 * s }} onPress={() => { setReward(!reward) }}>
          <MaterialCommunityIcons name="gift" size={24 * s} color={(theme.clanCardHeader || theme.navigation).fg} />
        </TouchableRipple>
      </View>
      {data?.levels?.length > 0 && <View style={{ flexDirection: "row" }}>
        <ScrollView horizontal={true} style={{ flex: 1 }} contentContainerStyle={{ flexDirection: "row", minWidth: '100%', paddingLeft: 55 * s }}>
          {!reward && <>
            <View style={{ flexDirection: "column", flexGrow: 1, alignItems: "stretch", backgroundColor: level_colors.ind.bg }}>
              <View style={{ height: 24 * s, padding: 4 * s }}><Text allowFontScaling={false} style={{ textAlign: "center", ...font("bold"), fontSize: 12 * s, color: level_colors.ind.fg }}>{t('clan:individual')}</Text></View>
              <View style={{ flexDirection: "row" }}>
                {(data?.order?.individual ?? []).map((i, index) => <View key={`Individual${i}`} style={{ flexGrow: 1 }}>
                  <ClanRequirement i={i} data={data} level_colors={level_colors} s={s} t="ind" index={index} />
                  {data?.levels?.map(l => <View key={l.id} style={{ marginHorizontal: -1, height: 24 * s, padding: 4 * s, alignItems: "center", backgroundColor: level_colors[l.id].bg }}>
                    <Text allowFontScaling={false} style={{ textAlign: "center", width: '100%', fontSize: 12 * s, color: level_colors[l.id].fg, ...font() }}>{l.individual?.[i]?.toLocaleString()}</Text>
                  </View>)}
                </View>)}
              </View>
            </View>

            <View style={{ flexDirection: "column", flexGrow: 1, alignItems: "stretch", backgroundColor: level_colors.gro.bg }}>
              <View style={{ borderLeftWidth: 2 * s, borderLeftColor: level_colors.border, marginHorizontal: -1 * s, height: 24 * s, padding: 4 * s }}><Text allowFontScaling={false} style={{ textAlign: "center", ...font("bold"), fontSize: 12 * s, color: level_colors.gro.fg }}>{t('clan:group')}</Text></View>
              <View style={{ flexDirection: "row", marginRight: 1 }}>
                {data?.order?.group?.map((i, index) => <View style={{ flexGrow: 1 }}>
                  <ClanRequirement i={i} data={data} level_colors={level_colors} s={s} t="gro" index={index} />
                  {data?.levels?.map(l => <View style={{ ...(index == 0 ? { borderLeftWidth: 2 * s, borderLeftColor: level_colors.border } : {}), marginHorizontal: -1 * s, height: 24 * s, padding: 4 * s, alignItems: "center", backgroundColor: level_colors[l.id].bg }}>
                    <Text allowFontScaling={false} style={{ color: level_colors[l.id].fg, textAlign: "center", width: '100%', ...font(), fontSize: 12 * s }}>{l.group?.[i]}</Text>
                  </View>)}
                </View>)}
              </View>
            </View>
          </>}

          {reward && <View style={{ flexDirection: "column", flexGrow: 1, alignItems: "stretch", backgroundColor: level_colors.ind.bg }}>
            <View style={{ height: 24 * s, padding: 4 * s }}><Text allowFontScaling={false} style={{ textAlign: "center", ...font("bold"), fontSize: 12 * s, color: level_colors.ind.fg }}>{t('clan:rewards')}</Text></View>
            <View style={{ flexDirection: "row", marginRight: 1 }}>
              {(data?.order?.rewards ?? []).map(i => <View key={`Reward${i}`} style={{ flexGrow: 1 }}>
                <View style={{ height: 60, borderBottomWidth: 2, borderBottomColor: level_colors.border, padding: 4, alignItems: "center" }}>
                  <Image source={getIcon(data?.rewards?.[i]?.logo)} style={{ height: 36 * s, width: 36 * s }} />
                  <Text allowFontScaling={false} numberOfLines={1} style={{ textAlign: "center", ...font("bold"), fontSize: 10 * s, color: level_colors.ind.fg }}>{data?.rewards?.[i]?.short_name ?? data?.rewards?.[i]?.name.replace(/Virtual /, 'V').replace(/Physical /, 'P').replace(/Flat /, '').replace(/ Mystery/, '').replace(/THE /, '').replace(/ Wheel/, 'W').replace(/Hammock/, 'Hamm')}</Text>
                </View>
                {data?.levels?.map(l => <View key={l.id} style={{ marginHorizontal: -1 * s, height: 24 * s, padding: 4 * s, alignItems: "center", backgroundColor: level_colors[l.id].bg }}>
                  <Text allowFontScaling={false} style={{ textAlign: "center", width: '100%', fontSize: 12 * s, color: level_colors[l.id].fg, ...font() }}>{l.rewards?.[i]?.toLocaleString()}</Text>
                </View>)}
              </View>)}
            </View>
          </View>}
        </ScrollView>


        <View style={{ width: 56 * s, position: "absolute", left: 0, top: 0, borderRightWidth: 2 * s, borderRightColor: level_colors.border }}>
          <TouchableWithoutFeedback onPress={()=>console.log(JSON.stringify(data?.order?.requirements))}><View style={{ height: 24 * s, backgroundColor: level_colors.null.bg, padding: 4 * s }}><Text allowFontScaling={false} style={{ ...font("bold"), fontSize: 12 * s, color: level_colors.null.fg }}>{moment(dateFromGameID(game_id)).format('MMM YY')}</Text></View></TouchableWithoutFeedback>
          <View style={{ height: (reward ? 60 : 77) * s, backgroundColor: level_colors.null.bg, flexDirection: "row", alignItems: "center", padding: 4 * s, borderBottomWidth: 2 * s, borderBottomColor: level_colors.border }}>
            <Text allowFontScaling={false} numberOfLines={1} ellipsizeMode="head" style={{ fontSize: 12 * s, color: level_colors.null.fg, ...font() }}>{t('clan:level', { count: data?.levels?.length })}</Text>
          </View>
          {(data?.levels ?? []).map(i => <View style={{ backgroundColor: level_colors[i.id].bg, padding: 4 * s, height: 24 * s }} key={i.name}>
            <Text allowFontScaling={false} style={{ fontSize: 12 * s, color: level_colors[i.id].fg, ...font() }}>{t('clan:level_n', { level: i.level })}</Text>
          </View>)}
        </View>
      </View>}
      {unformatted_requirements && data?.levels?.length === 0 && <ClanCountdown time={data?.battle?.reveal_at} />}
    </Card>
    // </View>
  );
}
Example #24
Source File: Stats.js    From Legacy with Mozilla Public License 2.0 4 votes vote down vote up
export default function UserActivityDash({ game_id, clan_id, scale: s }) {
  var scroll = false;
  if (s === undefined) {
    scroll = true;
    s = 1;
  }
  var { t } = useTranslation();
  var theme = useSelector(i => i.themes[i.theme]);
  var level_colors = useLevelColours();
  var coloredStyles = React.useMemo(() => StyleSheet.create({
    cell_borderLeft: {
      borderLeftWidth: 2,
      borderLeftColor: level_colors.border
    },
    cell_borderTop: {
      borderTopWidth: 2,
      borderTopColor: level_colors.border
    },
    cell_borderBottom: {
      borderBottomWidth: 2,
      borderBottomColor: level_colors.border
    }
  }),[level_colors.check])

  const logins = useSelector(i=>i.logins);
  var [levelTable, setLevelTable] = React.useState(false);
  var nav = useNavigation();
  var dispatch = useDispatch();
  var userBookmarks = useSelector(i => i.userBookmarks.map(i => Number(i.user_id)))
  var ls = useSelector(i => i.clanLevelSelect[clan_id] ?? 4);
  var levelSelect = Number(ls.toString().slice(0, 1));
  var share = !!ls.toString().slice(1, 2);
  var [userLevelSelect, setUserLevelSelect] = React.useState(false);
  var [clanLevelSelect, setClanLevelSelect] = React.useState(false);
  function setLevelSelect(val) {
    var x = {};
    x[clan_id] = val;
    return dispatch(levelSelectX(x));
  }
  var [showGhost, setShowGhost] = React.useState(true);
  const shadow_clans = [
    -1,
    457,
    1349,
    1441,
    1870,
    1902,
    2042,
    1064,
    2049
  ]
  var [unformatted_clan, unformatted_stats, unformatted_shadow] = useAPIRequest([
    Number(clan_id) >= 0 ? {
      endpoint: 'clan/v2',
      data: { clan_id }
    } : null,
    Number(clan_id) >= 0 ? {
      endpoint: 'clan/v2/requirements',
      data: { clan_id, game_id }
    } : {
        endpoint: 'clan/v2/requirements',
        data: { clan_id: 1349, game_id }
      },
    shadow_clans.includes(Number(clan_id)) ? {
      endpoint: `clan/shadow/v1`,
      data: { clan_id, game_id },
      cuppazee: true
    } : null
  ])
  var data = ClanRequirementsConverter(unformatted_stats);
  var clan_data = ClanStatsConverter(Number(clan_id) < 0 ? { shadow: true } : unformatted_clan, unformatted_stats, showGhost ? unformatted_shadow : {}, game_id);
  var clan = clan_data;

  const users = useAPIRequest(clan?.members?.filter(i=>i.no).map(i=>({
    endpoint: `user`,
    data: { user_id: i.user_id }
  })) || [], false, true);

  var members = clan?.members ?? [];
  var [ascending, setAscending] = React.useState(false);
  var [sortReq, setSortReq] = React.useState(3);
  members.sort((a, b) => {
    return (clan?.requirements?.[sortReq]?.users?.[(ascending ? a : b).user_id] || 0) - (clan?.requirements?.[sortReq]?.users?.[(ascending ? b : a).user_id] || 0);
  })

  function calculateLevel(user, value, requirement) {
    var x = false;
    var lvl = 0;
    for (var level of data?.levels) {
      if (level[user ? "individual" : "group"][requirement]) x = true;
      if (level[user ? "individual" : "group"][requirement] <= value || !level[user ? "individual" : "group"][requirement]) lvl = (lvl || 0) + 1;
    }
    if (levelTable && x) {
      if (levelSelect + 1 > lvl) {
        return 0;
      } else {
        return levelSelect + 1;
      }
    }
    return x ? lvl : null;
  }

  function num(x = "noauth", y) {
    return Number(x) < 1 ? (y ? "-" : "-") : Number(x).toLocaleString();
  }

  function calculateLevelT(user) {
    if (user) {
      var lev = Infinity;
      for (var requirement of data?.order?.individual) {
        var lvl = 0;
        var x = false;
        for (var level of data?.levels) {
          if (level.individual[requirement]) x = true;
          if (level.individual[requirement] <= clan?.requirements?.[requirement]?.users?.[user] || !level.individual[requirement]) lvl = (lvl || 0) + 1;
        }
        if (x) lev = Math.min(lev, (lvl || 0));

      }
      if (levelTable) {
        if (levelSelect + 1 > lev) {
          return 0;
        } else {
          return levelSelect + 1;
        }
      }
      return lev;
    } else {
      var lev = Infinity;
      for (var user of clan?.members) {
        lev = Math.min(lev, calculateLevelT(user.user_id));
      }
      for (var requirement of data?.order?.group) {
        var lvl = 0;
        var x = false;
        for (var level of data?.levels) {
          if (level.group[requirement]) x = true;
          if (level.group[requirement] <= clan?.requirements?.[requirement]?.total || !level.group[requirement]) lvl = (lvl || 0) + 1;
        }
        if (x) lev = Math.min(lev, (lvl || 0));
      }
      if (levelTable) {
        if (levelSelect + 1 > lev) {
          return 0;
        } else {
          return levelSelect + 1;
        }
      }
      return lev;
    }
  }
  if (!data?.levels || !clan?.details || !clan?.members) {
    if (!data || !clan) {
      return (
        <Card>
          <View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
            <ActivityIndicator size="large" color={theme.page_content.fg} />
          </View>
        </Card>
      )
    } else {
      return (
        <Card cardStyle={{ backgroundColor: theme.error.bg }}>
          <View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
            <Text allowFontScaling={false} style={{ color: theme.error.fg, ...font() }}>An Error Occurred</Text>
          </View>
        </Card>
      );
    }
  }
  return (
    <Card noPad>
      <View style={{ ...(theme.dark ? { borderBottomWidth: 2 * s, borderBottomColor: level_colors.border } : {}), backgroundColor: (theme.clanCardHeader || theme.navigation).bg, paddingHorizontal: 8 * s, borderTopLeftRadius: 8 * s, borderTopRightRadius: 8 * s, flexDirection: "row", alignItems: "center" }}>
        <View style={{ flex: 1, paddingVertical: 8 * s }}>
          <Text allowFontScaling={false} style={{ color: (theme.clanCardHeader || theme.navigation).fg, ...font("bold"), fontSize: 12 * s, opacity: 0.7, lineHeight: 12 * s }}>{!clan?.details?.goal && t('clan:shadow')}{clan?.details?.goal && ((clan?.details?.goal.startsWith('Level ')?t('clan:level_n',{level:clan?.details?.goal.slice(6)}):clan?.details?.goal) + ' ' + t('clan:goal'))} - {levelTable ? t('clan:view.subtract') : t('clan:view.total')}{!showGhost && " - Hiding Shadow Members"}</Text>
          <Text allowFontScaling={false} style={{ color: (theme.clanCardHeader || theme.navigation).fg, ...font("bold"), fontSize: 16 * s, lineHeight: 16 * s }}>{clan?.details?.name}</Text>
        </View>
        {shadow_clans.includes(Number(clan_id)) && Number(clan_id) >= 0 && <TouchableRipple style={{ borderRadius: 24 * s, padding: 4 * s }} onPress={() => { setShowGhost(!showGhost) }}>
          <MaterialCommunityIcons name="ghost" size={24 * s} color={(theme.clanCardHeader || theme.navigation).fg} />
        </TouchableRipple>}
        <TouchableRipple style={{ borderRadius: 24 * s, padding: 4 * s }} onPress={() => { setLevelTable(!levelTable) }}>
          <MaterialCommunityIcons name="plus-minus" size={24 * s} color={(theme.clanCardHeader || theme.navigation).fg} />
        </TouchableRipple>
      </View>
      <View style={{ flexDirection: "row" }}>
        <MainScrollView scroll={scroll} s={s}>
          <View style={{ flexDirection: "column", flexGrow: 1, alignItems: "stretch", backgroundColor: level_colors.null.bg }}>
            <View style={{ flexDirection: "row", marginRight: 1 }}>
              {(data?.order?.requirements ?? []).map((i,reqIndex) => <View style={{ flexGrow: 1 }}>
                <TouchableRipple onPress={() => {
                  if (sortReq !== i) {
                    setSortReq(i);
                    setAscending(false);
                  } else {
                    setAscending(!ascending);
                  }
                }}>
                  <View style={{ ...((reqIndex===data.order.requirements.findIndex(i=>data.order.group.includes(i)&&data.order.individual.includes(i))||reqIndex===data.order.requirements.findIndex(i=>data.order.group.includes(i)&&!data.order.individual.includes(i)))?{ borderLeftWidth: 2 * s, borderLeftColor: level_colors.border }:{}), marginHorizontal: -1 * s, height: (96 - 19) * s, padding: 4 * s, alignItems: "center", backgroundColor: level_colors[data?.order.individual.includes(i) ? (data?.order.group.includes(i) ? 'bot' : 'ind') : 'gro'].bg }}>
                    <Image source={getIcon(data?.requirements?.[i]?.icon ?? data?.requirements?.[i]?.icons?.[tick % data?.requirements?.[i]?.icons?.length])} style={{ height: 36 * s, width: 36 * s }} />
                    <View style={{ flexDirection: "row", alignItems: "baseline" }}>
                      <Text allowFontScaling={false} numberOfLines={1} style={{ color: level_colors[data?.order.individual.includes(i) ? (data?.order.group.includes(i) ? 'bot' : 'ind') : 'gro'].fg, textAlign: "center", ...font("bold"), fontSize: 12 * s }}>{t('clan_req:'+data?.requirements?.[i]?.top)}</Text>
                      <MaterialCommunityIcons color={level_colors[data?.order.individual.includes(i) ? (data?.order.group.includes(i) ? 'bot' : 'ind') : 'gro'].fg} name={sortReq === i ? (ascending ? 'menu-up' : 'menu-down') : 'menu-swap'} size={12 * s} />
                    </View>
                    <Text allowFontScaling={false} numberOfLines={1} style={{ color: level_colors[data?.order.individual.includes(i) ? (data?.order.group.includes(i) ? 'bot' : 'ind') : 'gro'].fg, textAlign: "center", ...font(), fontSize: 12 * s }}>{t('clan_req:'+data?.requirements?.[i]?.bottom)}</Text>
                  </View>
                </TouchableRipple>
                <View style={[
                  ((reqIndex===data.order.requirements.findIndex(i=>data.order.group.includes(i)&&data.order.individual.includes(i))||reqIndex===data.order.requirements.findIndex(i=>data.order.group.includes(i)&&!data.order.individual.includes(i)))?{ borderLeftWidth: 2 * s, borderLeftColor: level_colors.border }:{}),
                  coloredStyles.cell_borderBottom,
                  styles.cell,
                  { backgroundColor: level_colors[levelSelect + 1].bg }
                ]}>
                  {
                    share ?
                      <Text allowFontScaling={false} style={{ textAlign: "center", ...font(), width: '100%', fontSize: 12 * s, color: level_colors[levelSelect + 1].fg }}>{num(Math.max(data?.levels?.[levelSelect]?.individual?.[i] || 0, Math.ceil((data?.levels?.[levelSelect]?.group?.[i] || 0) / (clan?.members?.length || 100)), 0), true)}</Text>
                      : <Text allowFontScaling={false} style={{ textAlign: "center", ...font(), width: '100%', fontSize: 12 * s, color: level_colors[levelSelect + 1].fg }}>{num(data?.levels?.[levelSelect]?.individual?.[i] || 0, true)}</Text>
                  }
                </View>
                {members?.map(u => <View style={[
                  ((reqIndex===data.order.requirements.findIndex(i=>data.order.group.includes(i)&&data.order.individual.includes(i))||reqIndex===data.order.requirements.findIndex(i=>data.order.group.includes(i)&&!data.order.individual.includes(i)))?coloredStyles.cell_borderLeft:null),
                  styles.cell,
                  { backgroundColor: level_colors[calculateLevel(true, clan.requirements?.[i]?.users?.[u.user_id], i)].bg }
                ]}>
                  {/* WORKING HERE */}
                  <Text allowFontScaling={false} style={[
                    styles.cell_text,
                    font(userBookmarks.includes(Number(u.user_id)) ? "bold" : 400),
                    { color: level_colors[calculateLevel(true, clan.requirements?.[i]?.users?.[u.user_id], i)].fg }
                  ]}>
                    {levelTable ? num((data?.levels?.[levelSelect]?.individual?.[i] || 0) - clan.requirements?.[i]?.users?.[u.user_id]) : num(clan.requirements?.[i]?.users?.[u.user_id])}
                  </Text>
                </View>)}
                <View style={[
                  ((reqIndex===data.order.requirements.findIndex(i=>data.order.group.includes(i)&&data.order.individual.includes(i))||reqIndex===data.order.requirements.findIndex(i=>data.order.group.includes(i)&&!data.order.individual.includes(i)))?coloredStyles.cell_borderLeft:null),
                  coloredStyles.cell_borderTop,
                  styles.cell,
                  { backgroundColor: level_colors[calculateLevel(false, clan.requirements?.[i]?.total, i)].bg }
                ]}>
                  <Text allowFontScaling={false} style={[styles.cell_text, font(), { color: level_colors[calculateLevel(false, clan.requirements?.[i]?.total, i)].fg }]}>
                    {levelTable ? num((data?.levels?.[levelSelect]?.group?.[i] || 0) - clan.requirements?.[i]?.total) : num(clan.requirements?.[i]?.total)}
                  </Text>
                </View>
                <View style={[
                  ((reqIndex===data.order.requirements.findIndex(i=>data.order.group.includes(i)&&data.order.individual.includes(i))||reqIndex===data.order.requirements.findIndex(i=>data.order.group.includes(i)&&!data.order.individual.includes(i)))?coloredStyles.cell_borderLeft:null),
                  styles.cell,
                  { backgroundColor: level_colors[levelSelect + 1].bg }
                ]}>
                  <Text allowFontScaling={false} style={[
                    styles.cell_text,
                    font(), 
                    { color: level_colors[levelSelect + 1].fg }
                  ]}>{num(data?.levels?.[levelSelect]?.group?.[i] || 0, true)}</Text>
                </View>
              </View>)}
            </View>
          </View>
        </MainScrollView>


        <View style={{ width: 101 * s, position: "absolute", left: 0, top: 0, borderRightWidth: 2 * s, borderRightColor: level_colors.border }}>
          <View style={{ height: (96 - 19) * s, backgroundColor: level_colors.null.bg, justifyContent: "center", alignItems: "center", padding: 4 * s }}>
            <Text allowFontScaling={false} style={{ fontSize: 12 * s, ...font(), color: level_colors.null.fg }}>{t('clan:players', { count: clan?.members?.length })}</Text>
            {clan?.details?.rank>0&&<Text allowFontScaling={false} style={{ fontSize: 12 * s, ...font(), color: level_colors.null.fg }}>{t('clan:rank', { rank: clan?.details?.rank })}</Text>}
          </View>
          <View style={{ borderBottomWidth: 2 * s, borderBottomColor: level_colors.border, height: 24 * s, justifyContent: "center", backgroundColor: level_colors[levelSelect + 1].bg }}>
            <Menu
              visible={userLevelSelect}
              onDismiss={() => setUserLevelSelect(false)}
              position="bottom"
              anchor={
                <TouchableRipple style={{ height: 24 * s, justifyContent: "center", paddingHorizontal: 4 * s }} onPress={() => setUserLevelSelect(true)}>
                  <View style={{ flexDirection: "row", alignItems: "center" }}>
                    <Text allowFontScaling={false} style={{ fontSize: 12 * s, flex: 1, color: level_colors[levelSelect + 1].fg, ...font() }}>{t('clan:level_n',{level:data?.levels?.[levelSelect]?.level})} {(ls || "")?.endsWith?.('s') ? t('clan:share') : t('clan:indiv')}</Text>
                    <MaterialCommunityIcons color={level_colors[levelSelect + 1].fg} name="chevron-down" size={12} />
                  </View>
                </TouchableRipple>
              }
              contentContainerStyle={{ padding: 0 }}
            >
              {data?.levels?.map((i, index) => <Menu.Item
                key={index}
                style={[styles.levelSelect_menuItem,{ backgroundColor: level_colors[index + 1].bg }]}
                onPress={() => { setLevelSelect(index); setUserLevelSelect(false) }}
                title={<Text allowFontScaling={false} style={{ fontSize: 12 * s, ...font(), color: level_colors[index + 1].fg }}>{t('clan:level_n',{level:i.level})} {t('clan:indiv')}</Text>}
              />)}
              {data?.levels?.map((i, index) => <Menu.Item
                key={index + 's'}
                style={[styles.levelSelect_menuItem,{ backgroundColor: level_colors[index + 1].bg }]}
                onPress={() => { setLevelSelect(index + 's'); setUserLevelSelect(false) }}
                title={<Text allowFontScaling={false} style={{ fontSize: 12 * s, ...font(), color: level_colors[index + 1].fg }}>{t('clan:level_n',{level:i.level})} {t('clan:share')}</Text>}
              />)}
            </Menu>
          </View>
          {members?.map(i => <TouchableWithoutFeedback onPress={() => nav.navigate('UserDetails', { username: users.find(u=>u?.user_id.toString()===i.user_id.toString())?.username || i.username })}>
            <View style={{ backgroundColor: level_colors[calculateLevelT(i.user_id)].bg, padding: 4 * s, height: 24 * s, flexDirection: "row", alignItems: "center", justifyContent: "flex-start" }} key={i.name}>
              {(i.leader || i.ghost) && <MaterialCommunityIcons name={i.ghost ? 'ghost' : 'hammer'} color={level_colors[calculateLevelT(i.user_id)].fg} size={12 * s} />}
              <Text allowFontScaling={false} numberOfLines={1} ellipsizeMode="tail" style={{ fontSize: 12 * s, ...font(userBookmarks.includes(Number(i.user_id)) ? "bold" : 400), flexShrink: 1, color: level_colors[calculateLevelT(i.user_id)].fg }}>{users.find(u=>u?.user_id.toString()===i.user_id.toString())?.username || i.username}</Text>
            </View>
          </TouchableWithoutFeedback>)}
          <View style={{ justifyContent: "center", borderTopWidth: 2 * s, borderTopColor: level_colors.border, backgroundColor: level_colors[calculateLevelT(false)].bg, padding: 4 * s, height: 24 * s }}>
            <Text allowFontScaling={false} style={{ fontSize: 12 * s, ...font(), color: level_colors[calculateLevelT(false)].fg }}>{t('clan:group_total')}</Text>
          </View>
          <View style={{ justifyContent: "center", height: 24 * s, backgroundColor: level_colors[levelSelect + 1].bg }}>
            <Menu
              visible={clanLevelSelect}
              onDismiss={() => setClanLevelSelect(false)}
              position="bottom"
              anchor={
                <TouchableRipple style={{ height: 24 * s, justifyContent: "center", paddingHorizontal: 4 * s }} onPress={() => setClanLevelSelect(true)}>
                  <View style={{ flexDirection: "row", alignItems: "center" }}>
                    <Text allowFontScaling={false} style={{ fontSize: 12 * s, flex: 1, color: level_colors[levelSelect + 1].fg, ...font() }}>{t('clan:level_n',{level:data?.levels?.[levelSelect]?.level})} {t('clan:group')}</Text>
                    <MaterialCommunityIcons color={level_colors[levelSelect + 1].fg} name="chevron-down" size={12 * s} />
                  </View>
                </TouchableRipple>
              }
              contentContainerStyle={{ padding: 0 }}
            >
              {data?.levels?.map((i, index) => <Menu.Item
                key={index}
                style={[styles.levelSelect_menuItem,{ backgroundColor: level_colors[index + 1].bg }]}
                onPress={() => { setLevelSelect(index + ((ls || "")?.endsWith?.('s') ? 's' : '')); setClanLevelSelect(false) }}
                title={<Text allowFontScaling={false} style={{ fontSize: 12 * s, ...font(), color: level_colors[index + 1].fg }}>{t('clan:level_n',{level:i.level})}</Text>}
              />)}
            </Menu>
          </View>
        </View>
      </View>
      {clan.details.shadow?.group_admins?.some(i=>logins[i]) && <SyncButton game_id={game_id} group={clan.details.shadow?.group}/>}
    </Card>
  );
}
Example #25
Source File: Type.js    From Legacy with Mozilla Public License 2.0 4 votes vote down vote up
export default function SettingsScreen() {
  var {t} = useTranslation()
  var moment = useMoment();
  var route = useRoute();
  var munzee_icon = route.params.munzee;
  var munzee = getType(munzee_icon);
  var theme = useSelector(i=>i.themes[i.theme]);
  var nav = useNavigation();
  if(!munzee) return null;
  return (
    <ScrollView style={{ backgroundColor: theme.page_content.bg }} contentContainerStyle={{padding:8}}>
      <View style={{alignItems:"center"}}>
        <Image source={getIcon(munzee.icon)} style={{height:48,width:48}} />
        <Text allowFontScaling={false} style={{color: theme.page_content.fg,fontSize:24,...font("bold")}}>{munzee.name}</Text>
        <Text allowFontScaling={false} style={{color: theme.page_content.fg,fontSize:20,...font("bold")}}>{t('db:type.info',{icon: munzee.icon, id: munzee.id})}</Text>
      </View>
      <View style={{flexDirection:"row",flexWrap:"wrap",justifyContent:"center"}}>
        {munzee.state!="bouncer"&&<CustomChip label={`${u(munzee.state)}`}/>}
        {munzee.card&&<CustomChip label={`${u(munzee.card)} Edition`}/>}
        {munzee.bouncer&&<CustomChip label="Bouncer"/>}
        {munzee.host&&<CustomChip label="Bouncer Host"/>}
        {munzee.elemental&&<CustomChip label="Elemental"/>}
        {munzee.event=="custom"&&<CustomChip label="Custom Event"/>}
        {munzee.unique&&<CustomChip label="Unique"/>}
        {munzee.destination?.max_rooms&&<CustomChip label={`${munzee.destination?.max_rooms} Rooms`}/>}
        <CustomChip onPress={()=>nav.navigate('DBCategory',{category:munzee.category})} label={`Category: ${getCategory(munzee.category)}`}/>
        {munzee.virtual_colors?.map(i=><CustomChip label={`Virtual Color: ${u(i)}`}/>)}
      </View>
      {categories.find(i=>i.id==munzee.category)?.seasonal&&<View style={{alignItems:"center"}}>
        <Text allowFontScaling={false} style={{color:theme.page_content.fg}}>{moment(categories.find(i=>i.id==munzee.category).seasonal.starts).format('L LT')} - {moment(categories.find(i=>i.id==munzee.category).seasonal.ends).format('L LT')}</Text>
        <Text allowFontScaling={false} style={{color:theme.page_content.fg}}>{t('bouncers:duration',{duration:moment.duration(moment(categories.find(i=>i.id==munzee.category).seasonal.starts).diff(moment(categories.find(i=>i.id==munzee.category).seasonal.ends))).humanize()})}</Text>
      </View>}

      {/* Points */}
      {munzee.points&&<>
        <View style={{height:1,backgroundColor:theme.page_content.fg,opacity:0.5,margin:8}}></View>
        <View style={{alignItems:"center"}}>
          <Text allowFontScaling={false} style={{color: theme.page_content.fg,fontSize:24,...font("bold")}}>{t('db:type.points')}</Text>
        </View>
        <View style={{flexDirection: "row", flexWrap: "wrap", justifyContent: "center"}}>
          {munzee.points.deploy!==undefined&&<View style={{alignItems:"center",padding:4,width:100}}>
            <MaterialCommunityIcons name="account" size={32} color={theme.page_content.fg} />
            <Text allowFontScaling={false} numberOfLines={1} style={{color: theme.page_content.fg,lineHeight:16,fontSize:16,...font("bold")}}>{munzee.points.deploy}</Text>
            <Text allowFontScaling={false} style={{color: theme.page_content.fg,fontSize:12,...font()}}>{t('db:type.deploy')}</Text>
          </View>}
          {!munzee.points.type&&<>
            <View style={{alignItems:"center",padding:4,width:100}}>
              <MaterialCommunityIcons name="check" size={32} color={theme.page_content.fg} />
              <Text allowFontScaling={false} numberOfLines={1} style={{color: theme.page_content.fg,lineHeight:16,fontSize:16,...font("bold")}}>{munzee.points.capture}</Text>
              <Text allowFontScaling={false} style={{color: theme.page_content.fg,fontSize:12,...font()}}>{t('db:type.capture')}</Text>
            </View>
            <View style={{alignItems:"center",padding:4,width:100}}>
              <MaterialCommunityIcons name="open-in-app" size={32} color={theme.page_content.fg} />
              <Text allowFontScaling={false} numberOfLines={1} style={{color: theme.page_content.fg,lineHeight:16,fontSize:16,...font("bold")}}>{munzee.points.capon}</Text>
              <Text allowFontScaling={false} style={{color: theme.page_content.fg,fontSize:12,...font()}}>{t('db:type.capon')}</Text>
            </View>
          </>}
          {munzee.points.type=="split"&&<View style={{alignItems:"center",padding:4,width:100}}>
            <MaterialCommunityIcons name="call-split" size={32} color={theme.page_content.fg} />
            <Text allowFontScaling={false} numberOfLines={1} style={{color: theme.page_content.fg,lineHeight:16,fontSize:16,...font("bold")}}>{t('db:type.split_val',munzee.points)}</Text>
            <Text allowFontScaling={false} style={{color: theme.page_content.fg,fontSize:12,...font()}}>{t('db:type.split')}</Text>
          </View>}
        </View>
      </>}

      {/* Evo Stages */}
      {munzee.evolution&&<>
        <View style={{height:1,backgroundColor:theme.page_content.fg,opacity:0.5,margin:8}}></View>
        <View style={{alignItems:"center"}}>
          <Text allowFontScaling={false} style={{color: theme.page_content.fg,fontSize:24,...font("bold")}}>{t('db:type.evo')}</Text>
        </View>
        <View style={{flexDirection:"row",flexWrap:"wrap",justifyContent:"center"}}>
          {types.filter(i=>i.evolution?.base===munzee.evolution.base).sort((a,b)=>a.evolution?.stage-b.evolution?.stage).map(i=><TouchableRipple onPress={()=>nav.push('DBType',{munzee:i.icon})}>
            <View style={{alignItems:"center",padding:4,width:100}}>
              <Image source={getIcon(i.icon)} style={{height:32,width:32}} />
              <Text allowFontScaling={false} numberOfLines={1} ellipsizeMode="tail" style={{color: theme.page_content.fg,fontSize:16,...font("bold")}}>{i.name}</Text>
              <Text allowFontScaling={false} style={{color: theme.page_content.fg,fontSize:16,...font()}}>ID: {i.id}</Text>
            </View>
          </TouchableRipple>)}
        </View>
      </>}

      {/* Pouch Creature Stages */}
      {munzee.bouncer?.base&&<>
        <View style={{height:1,backgroundColor:theme.page_content.fg,opacity:0.5,margin:8}}></View>
        <View style={{alignItems:"center"}}>
          <Text allowFontScaling={false} style={{color: theme.page_content.fg,fontSize:24,...font("bold")}}>{t('db:type.pouch')}</Text>
        </View>
        <View style={{flexDirection:"row",flexWrap:"wrap",justifyContent:"center"}}>
          {types.filter(i=>i.bouncer?.base===munzee.bouncer.base).sort((a,b)=>a.bouncer?.stage-b.bouncer?.stage).map(i=><TouchableRipple onPress={()=>nav.push('DBType',{munzee:i.icon})}>
            <View style={{alignItems:"center",padding:4,width:100}}>
              <Image source={getIcon(i.icon)} style={{height:32,width:32}} />
              <Text allowFontScaling={false} numberOfLines={1} ellipsizeMode="tail" style={{color: theme.page_content.fg,fontSize:16,...font("bold")}}>{i.name}</Text>
              <Text allowFontScaling={false} style={{color: theme.page_content.fg,fontSize:16,...font()}}>ID: {i.id}</Text>
            </View>
          </TouchableRipple>)}
        </View>
      </>}

      {/* Can Host */}
      {munzee.can_host?.filter?.(checkCanHost)?.length>0&&<>
        <View style={{height:1,backgroundColor:theme.page_content.fg,opacity:0.5,margin:8}}></View>
        <View style={{alignItems:"center"}}>
          <Text allowFontScaling={false} style={{color: theme.page_content.fg,fontSize:24,...font("bold")}}>{t('db:type.can_host')}</Text>
        </View>
        <View style={{flexDirection:"row",flexWrap:"wrap",justifyContent:"center"}}>
          {munzee.can_host.filter(checkCanHost).map(i=>types.find(x=>x.id==i)).filter(i=>!i.hidden).map(i=><TouchableRipple onPress={()=>nav.push('DBType',{munzee:i.icon})}>
            <View style={{alignItems:"center",padding:4,width:100}}>
              <Image source={getIcon(i.icon)} style={{height:32,width:32}} />
              <Text allowFontScaling={false} numberOfLines={1} ellipsizeMode="tail" style={{color: theme.page_content.fg,fontSize:16,...font("bold")}}>{i.name}</Text>
              <Text allowFontScaling={false} style={{color: theme.page_content.fg,fontSize:16,...font()}}>ID: {i.id}</Text>
            </View>
          </TouchableRipple>)}
        </View>
      </>}

      {/* Lands On */}
      {munzee?.bouncer?.lands_on&&<>
        <View style={{height:1,backgroundColor:theme.page_content.fg,opacity:0.5,margin:8}}></View>
        <View style={{alignItems:"center"}}>
          <Text allowFontScaling={false} style={{color: theme.page_content.fg,fontSize:24,...font("bold")}}>{t('db:type.lands_on')}</Text>
        </View>
        <View style={{flexDirection:"row",flexWrap:"wrap",justifyContent:"center"}}>
          {munzee.bouncer.lands_on.map(i=>types.find(x=>x.id==i)).filter(i=>!i.hidden).map(i=><TouchableRipple onPress={()=>nav.push('DBType',{munzee:i.icon})}>
            <View style={{alignItems:"center",padding:4,width:100}}>
              <Image source={getIcon(i.icon)} style={{height:32,width:32}} />
              <Text allowFontScaling={false} numberOfLines={1} ellipsizeMode="tail" style={{color: theme.page_content.fg,fontSize:16,...font("bold")}}>{i.name}</Text>
              <Text allowFontScaling={false} style={{color: theme.page_content.fg,fontSize:16,...font()}}>ID: {i.id}</Text>
            </View>
          </TouchableRipple>)}
        </View>
      </>}

      {/* Host Types */}
      {types.filter(i=>i.host&&i.host.hosts&&i.host.hosts.includes(munzee.id)).length>0&&<>
        <View style={{height:1,backgroundColor:theme.page_content.fg,opacity:0.5,margin:8}}></View>
        <View style={{alignItems:"center"}}>
          <Text allowFontScaling={false} style={{color: theme.page_content.fg,fontSize:24,...font("bold")}}>{t('db:type.host_types')}</Text>
        </View>
        <View style={{flexDirection:"row",flexWrap:"wrap",justifyContent:"center"}}>
          {types.filter(i=>i.host&&i.host.hosts&&i.host.hosts.includes(munzee.id)).filter(i=>!i.hidden).map(i=><TouchableRipple onPress={()=>nav.push('DBType',{munzee:i.icon})}>
            <View style={{alignItems:"center",padding:4,width:100}}>
              <Image source={getIcon(i.icon)} style={{height:32,width:32}} />
              <Text allowFontScaling={false} numberOfLines={1} ellipsizeMode="tail" style={{color: theme.page_content.fg,fontSize:16,...font("bold")}}>{i.name}</Text>
              <Text allowFontScaling={false} style={{color: theme.page_content.fg,fontSize:16,...font()}}>ID: {i.id}</Text>
            </View>
          </TouchableRipple>)}
        </View>
      </>}

      {/* Hosts */}
      {munzee?.host?.hosts&&<>
        <View style={{height:1,backgroundColor:theme.page_content.fg,opacity:0.5,margin:8}}></View>
        <View style={{alignItems:"center"}}>
          <Text allowFontScaling={false} style={{color: theme.page_content.fg,fontSize:24,...font("bold")}}>{t('db:type.hosts')}</Text>
        </View>
        <View style={{flexDirection:"row",flexWrap:"wrap",justifyContent:"center"}}>
          {munzee.host.hosts.map(i=>types.find(x=>x.id==i)).filter(i=>!i.hidden).map(i=><TouchableRipple onPress={()=>nav.push('DBType',{munzee:i.icon})}>
            <View style={{alignItems:"center",padding:4,width:100}}>
              <Image source={getIcon(i.icon)} style={{height:32,width:32}} />
              <Text allowFontScaling={false} numberOfLines={1} ellipsizeMode="tail" style={{color: theme.page_content.fg,fontSize:16,...font("bold")}}>{i.name}</Text>
              <Text allowFontScaling={false} style={{color: theme.page_content.fg,fontSize:16,...font()}}>ID: {i.id}</Text>
            </View>
          </TouchableRipple>)}
        </View>
      </>}

      {/* Possible Types */}
      {munzee?.host?.hosts&&possibleTypes(munzee?.host?.hosts)&&<>
        <View style={{height:1,backgroundColor:theme.page_content.fg,opacity:0.5,margin:8}}></View>
        <View style={{alignItems:"center"}}>
          <Text allowFontScaling={false} style={{color: theme.page_content.fg,fontSize:24,...font("bold")}}>{t('db:type.possible_types')}</Text>
        </View>
        <View style={{flexDirection:"row",flexWrap:"wrap",justifyContent:"center"}}>
          {possibleTypes(munzee?.host?.hosts).map(i=>types.find(x=>x.id==i)).filter(i=>!i.hidden&&i.state==munzee?.state).map(i=><TouchableRipple onPress={()=>nav.push('DBType',{munzee:i.icon})}>
            <View style={{alignItems:"center",padding:4,width:100}}>
              <Image source={getIcon(i.icon)} style={{height:32,width:32}} />
              <Text allowFontScaling={false} numberOfLines={1} ellipsizeMode="tail" style={{color: theme.page_content.fg,fontSize:16,...font("bold")}}>{i.name}</Text>
              <Text allowFontScaling={false} style={{color: theme.page_content.fg,fontSize:16,...font()}}>ID: {i.id}</Text>
            </View>
          </TouchableRipple>)}
        </View>
      </>}

      {/* Possible Hosts */}
      {munzee?.can_host&&possibleHosts(munzee?.can_host)&&<>
        <View style={{height:1,backgroundColor:theme.page_content.fg,opacity:0.5,margin:8}}></View>
        <View style={{alignItems:"center"}}>
          <Text allowFontScaling={false} style={{color: theme.page_content.fg,fontSize:24,...font("bold")}}>{t('db:type.possible_hosts')}</Text>
        </View>
        <View style={{flexDirection:"row",flexWrap:"wrap",justifyContent:"center"}}>
          {possibleHosts(munzee.can_host).map(i=>types.find(x=>x.id==i)).filter(i=>!i.hidden&&i.state==munzee?.state).map(i=><TouchableRipple onPress={()=>nav.push('DBType',{munzee:i.icon})}>
            <View style={{alignItems:"center",padding:4,width:100}}>
              <Image source={getIcon(i.icon)} style={{height:32,width:32}} />
              <Text allowFontScaling={false} numberOfLines={1} ellipsizeMode="tail" style={{color: theme.page_content.fg,fontSize:16,...font("bold")}}>{i.name}</Text>
              <Text allowFontScaling={false} style={{color: theme.page_content.fg,fontSize:16,...font()}}>ID: {i.id}</Text>
            </View>
          </TouchableRipple>)}
        </View>
      </>}
    </ScrollView>
  );
}
Example #26
Source File: Drawer.js    From Legacy with Mozilla Public License 2.0 4 votes vote down vote up
export default function CustomDrawerContent(props) {
  var [helpOpen, setHelpOpen] = React.useState(false);
  var [donateOpen, setDonateOpen] = React.useState(false);
  var [paypalOpen, setPaypalOpen] = React.useState(false);
  var mini = props.mini;
  var { t } = useTranslation();
  var theme = useSelector(i => i.themes[i.theme]);
  var clanBookmarks = useSelector(i => i.clanBookmarks);
  var userBookmarks = useSelector(i => i.userBookmarks);
  // const { data: zeecretTeams } = useZeecretTeam(null, true);
  var route = useSelector(i => i.route);
  var nav = props.navigation;
  var [showMoreClan, setShowMoreClan] = React.useState(false);
  var [showMoreUser, setShowMoreUser] = React.useState(false);
  var [now, setNow] = React.useState(Date.now());
  React.useEffect(() => {
    var x = setInterval(() => {
      setNow(Date.now());
    }, 1000);
    return () => clearInterval(x);
  })
  var top = [
    // { title: "Camps Leaderboard", icon: "flag", page: "AllCampWeeks" },
  ].filter(i => !i.hide)
  var pages = [
    // { title: t(`common:maps`), icon: "map", page: "Map" },
    { title: t(`common:bouncers`), icon: "map-marker", page: "Bouncers" },
    { title: t(`common:munzee_types`), icon: "database", page: "DBSearch" },
    { title: t(`common:calendar`), icon: "calendar", page: "Calendar" },
    { title: t(`common:evo_planner`), icon: "dna", page: "EvoPlanner" },
    // { title: t(`common:scanner`), icon: "qrcode", page: "Scanner", hide: Platform.OS === "web" },
    { title: t(`common:weekly_challenge`), icon: "calendar", page: "WeeklyWeeks" },
    { title: "Zeecret Agents Competition", icon: "briefcase", page: "CompetitionHome" },
    { title: "Bookmark Manager", icon:"bookmark", page:"Bookmarks" },
  ].filter(i => !i.hide)
  var more = [
    { title: t(`common:notifications`), icon: "bell", page: "Notifications", hide: Platform.OS === "web" },
    { title: t(`common:settings`), icon: "settings", page: "Settings" },
    { title: t(`common:app_info`), icon: "information", page: "Info" },
    { title: `GitHub`, icon: "github-circle", page: "https://github.com/CuppaZee/CuppaZee", link: true }
  ].filter(i => !i.hide)
  var itemProps = {
    side: props.side,
    mini: mini,
    activeBackgroundColor: theme.navigation_selected?.bg ?? theme.navigation.fg,
    activeTintColor: theme.navigation_selected?.fg ?? theme.navigation.bg,
    inactiveTintColor: theme.navigation.fg
  }
  return (
    <DrawerContentScrollView style={{ backgroundColor: theme.navigation.bg, ...(theme.page_content.border ? { borderRightWidth: 1, borderRightColor: "white" } : {}) }} {...props}>
      {/* <View style={{ paddingTop: 8, paddingBottom: 4, paddingLeft: 16 }}>
        <Text allowFontScaling={false} style={{ fontSize: 16, ...font("bold"), color: theme.navigation.fg, opacity: 0.8 }}>Remember this is a{Platform.OS == "android" ? 'n Early Access' : ' Beta'} build</Text>
        <Text allowFontScaling={false} style={{ fontSize: 12, ...font("bold"), color: theme.navigation.fg, opacity: 0.8 }}>Feedback is welcome via Messenger or Email</Text>
      </View> */}
      {Platform.OS == "web" && globalThis?.navigator?.userAgent?.match?.(/Android/) && <View style={{ paddingTop: 8, paddingBottom: 4, paddingLeft: 8 }}>
        <Text allowFontScaling={false} style={{ fontSize: 16, ...font("bold"), color: theme.navigation.fg, opacity: 0.8 }}>The CuppaZee App is now on Google Play</Text>
        <Text allowFontScaling={false} style={{ fontSize: 12, ...font("bold"), color: theme.navigation.fg, opacity: 0.8 }}>Download it now!</Text>
      </View>}
      {Platform.OS == "web" && globalThis?.navigator?.userAgent?.match?.(/iPhone|iPad|iPod/) && <View style={{ paddingTop: 8, paddingBottom: 4, paddingLeft: 8 }}>
        <Text allowFontScaling={false} style={{ fontSize: 16, ...font("bold"), color: theme.navigation.fg, opacity: 0.8 }}>The CuppaZee App is now on the App Store</Text>
        <Text allowFontScaling={false} style={{ fontSize: 12, ...font("bold"), color: theme.navigation.fg, opacity: 0.8 }}>Download it now!</Text>
      </View>}
      {top.map?.(i => <DrawerItem
        key={i.title}
        {...itemProps}
        style={{ marginVertical: 0, opacity: i.disabled ? 0.6 : 1 }}
        focused={route.name == i.page}
        icon={({ focused, color, size }) => <MaterialCommunityIcons name={i.icon} color={color} size={24} style={{ margin: 4 }} />}
        label={i.title}
        onPress={i.disabled ? null : (i.link ? () => Linking.openURL(i.page) : () => nav.reset({
          index: 1,
          routes: [
            { name: '__primary', params: { screen: i.page } },
          ],
        }))
        }
      />)}
      <View style={{ paddingLeft: 8 }}>
        <Text allowFontScaling={false} style={{ fontSize: 16, ...font("bold"), color: theme.navigation.fg, opacity: 0.8 }}>{t(`common:users`)}</Text>
      </View>
      <View style={{ paddingHorizontal: 4, flexDirection: "row", justifyContent: "space-between" }}>
        <IconButton
          style={{
            backgroundColor: route.name == "AllUsers" ? itemProps.activeBackgroundColor : null
          }}
          icon="format-list-bulleted"
          color={itemProps.inactiveTintColor}
          onPress={() => nav.reset({
            index: 1,
            routes: [
              { name: '__primary', params: { screen: "AllUsers" } },
            ],
          })}
        />
        <IconButton
          style={{
            backgroundColor: route.name == "UserSearch" ? itemProps.activeBackgroundColor : null
          }}
          icon="magnify"
          color={itemProps.inactiveTintColor}
          onPress={() => nav.reset({
            index: 1,
            routes: [
              { name: '__primary', params: { screen: "UserSearch" } },
            ],
          })}
        />
        <IconButton
          disabled={true}
          style={{
            backgroundColor: route.name == "UserRankings" ? itemProps.activeBackgroundColor : null
          }}
          icon="trophy-outline"
          color={itemProps.inactiveTintColor}
          onPress={() => nav.reset({
            index: 1,
            routes: [
              { name: '__primary', params: { screen: "UserRankings" } },
            ],
          })}
        />
        {/* <IconButton
          disabled={true}
          style={{
            backgroundColor: route.name == "UserBookmarks" ? itemProps.activeBackgroundColor : null
          }}
          icon="bookmark-outline"
          color={itemProps.inactiveTintColor}
          onPress={() => nav.reset({
            index: 1,
            routes: [
              { name: '__primary', params: { screen: "UserBookmarks" } },
            ],
          })
          }
        /> */}
      </View>
      {userBookmarks?.slice?.(0, showMoreUser ? Infinity : userBookmarks.length > 6 ? 5 : 6)?.filter?.(i => i)?.map?.(i => <DrawerItem
        key={`user_${i.user_id}`}
        {...itemProps}
        style={{ marginVertical: 0 }}
        focused={route.name?.startsWith?.('User') && route.params?.username == i.username}
        icon={({ focused, color, size }) => <Image style={{ height: 32, width: 32, borderRadius: 16 }} source={{ uri: i.logo ?? `https://munzee.global.ssl.fastly.net/images/avatars/ua${Number(i.user_id || 0).toString(36)}.png` }} />}
        label={i.username}
        onPress={() => nav.reset({
          index: 1,
          routes: [
            { name: '__primary', params: { screen: "UserDetails", params: { username: i.username } } },
          ],
        })
        }
        // right={zeecretTeams?.[i.username] ? ({ focused, color, size }) => <MaterialCommunityIcons name={zeecretTeams[i.username].startsWith("pine") ? "pine-tree" : "bomb"} color={zeecretTeams[i.username].endsWith('_false') ? "#ff0000" : color} size={24} style={{ margin: 4 }} /> : null}
      />)}
      {userBookmarks.length > 6 && <DrawerItem
        {...itemProps}
        style={{ marginVertical: 0 }}
        focused={false}
        icon={({ focused, color, size }) => <MaterialCommunityIcons name={showMoreUser ? "chevron-up" : "chevron-down"} color={color} size={24} style={{ margin: 4 }} />}
        label={showMoreUser ? t(`common:show_less`) : t(`common:show_more`)}
        onPress={() => setShowMoreUser(!showMoreUser)}
      />}
      {/* <DrawerItem
        {...itemProps}
        style={{ marginVertical: 0 }}
        focused={route.name == "UserSearch"}
        icon={({ focused, color, size }) => <MaterialCommunityIcons name="magnify" color={color} size={24} style={{ margin: 4 }} />}
        label={t(`common:find_user`)}
        onPress={() => nav.reset({
          index: 1,
          routes: [
            { name: '__primary', params: { screen: "UserSearch" } },
          ],
        })
        }
      /> */}
      <Divider theme={{ dark: theme.id !== "white" }} />
      <View style={{ paddingTop: 8, paddingLeft: 8 }}>
        <Text allowFontScaling={false} style={{ fontSize: 16, ...font("bold"), color: theme.navigation.fg, opacity: 0.8 }}>{t('common:clan', { count: 2 })}</Text>
      </View>
      <View style={{ paddingHorizontal: 4, flexDirection: "row", justifyContent: "space-between" }}>
        <IconButton
          style={{
            backgroundColor: route.name == "AllClans" ? itemProps.activeBackgroundColor : null
          }}
          icon="format-list-bulleted"
          color={itemProps.inactiveTintColor}
          onPress={() => nav.reset({
            index: 1,
            routes: [
              { name: '__primary', params: { screen: "AllClans" } },
            ],
          })}
        />
        <IconButton
          style={{
            backgroundColor: route.name == "ClanSearch" ? itemProps.activeBackgroundColor : null
          }}
          icon="magnify"
          color={itemProps.inactiveTintColor}
          onPress={() => nav.reset({
            index: 1,
            routes: [
              { name: '__primary', params: { screen: "ClanSearch" } },
            ],
          })}
        />
        {/* <IconButton
          disabled={true}
          style={{
            backgroundColor: route.name == "ClanRequirements" && route.params.gameid < 87 ? itemProps.activeBackgroundColor : null
          }}
          icon="history"
          color={itemProps.inactiveTintColor}
          onPress={() => nav.reset({
            index: 1,
            routes: [
              { name: '__primary', params: { screen: "ClanRequirements", params: { gameid: 87 } } },
            ],
          })
          }
        /> */}
        <IconButton
          style={{
            backgroundColor: route.name == "ClanRequirements" && route.params.year == 2020 && route.params.month == 11 ? itemProps.activeBackgroundColor : null
          }}
          icon="playlist-check"
          color={itemProps.inactiveTintColor}
          onPress={() => nav.reset({
            index: 1,
            routes: [
              { name: '__primary', params: { screen: "ClanRequirements", params: { year: 2020, month: 11 } } },
            ],
          })
          }
        />
        <IconButton
          style={{
            backgroundColor: route.name == "ClanRequirements" && route.params.year == 2020 && route.params.month == 12 ? itemProps.activeBackgroundColor : null,
            borderWidth: 1,
            borderColor: theme.navigation.fg
          }}
          icon="star"
          color={itemProps.inactiveTintColor}
          onPress={() => nav.reset({
            index: 1,
            routes: [
              { name: '__primary', params: { screen: "ClanRequirements", params: { year: 2020, month: 12 } } },
            ],
          })
          }
        />
        {/* <IconButton
          style={{
            backgroundColor: route.name == "ClanRequirements" && route.params.gameid == 89 ? itemProps.activeBackgroundColor : null
          }}
          icon="new-box"
          color={itemProps.inactiveTintColor}
          onPress={() => nav.reset({
            index: 1,
            routes: [
              { name: '__primary', params: { screen: "ClanRequirements", params: { gameid: 89 } } },
            ],
          })
          }
        /> */}
        {/* <IconButton
          disabled={true}
          style={{
            backgroundColor: route.name == "ClanBookmarks" ? itemProps.activeBackgroundColor : null
          }}
          icon="bookmark-outline"
          color={itemProps.inactiveTintColor}
          onPress={() => nav.reset({
            index: 1,
            routes: [
              { name: '__primary', params: { screen: "ClanBookmarks" } },
            ],
          })
          }
        /> */}
      </View>
      {clanBookmarks?.slice?.(0, showMoreClan ? Infinity : clanBookmarks.length > 6 ? 5 : 6)?.filter?.(i => i)?.map?.(i => <DrawerItem
        key={`clan_${i.clan_id}`}
        {...itemProps}
        style={{ marginVertical: 0 }}
        focused={route.name == "Clan" && route.params?.clanid == Number(i.clan_id)}
        icon={({ focused, color, size }) => <Image style={{ height: 32, width: 32, borderRadius: 16 }} source={{ uri: i.logo ?? `https://munzee.global.ssl.fastly.net/images/clan_logos/${(i.clan_id || 0).toString(36)}.png` }} />}
        label={i.name}
        onPress={() => nav.reset({
          index: 1,
          routes: [
            { name: '__primary', params: { screen: "Clan", params: { clanid: Number(i.clan_id) } } },
          ],
        })
        }
      />)}
      {clanBookmarks.length > 6 && <DrawerItem
        {...itemProps}
        style={{ marginVertical: 0 }}
        focused={false}
        icon={({ focused, color, size }) => <MaterialCommunityIcons name={showMoreClan ? "chevron-up" : "chevron-down"} color={color} size={24} style={{ margin: 4 }} />}
        label={showMoreClan ? t(`common:show_less`) : t(`common:show_more`)}
        onPress={() => setShowMoreClan(!showMoreClan)}
      />}
      <Divider theme={{ dark: theme.id !== "white" }} />
      <View style={{ paddingTop: 8, paddingBottom: 4, paddingLeft: 8 }}>
        <Text allowFontScaling={false} style={{ fontSize: 16, ...font("bold"), color: theme.navigation.fg, opacity: 0.8 }}>{t('common:tools')}</Text>
      </View>
      {pages.map?.(i => <DrawerItem
        key={i.title}
        {...itemProps}
        style={{ marginVertical: 0 }}
        focused={route.name == i.page}
        icon={({ focused, color, size }) => <MaterialCommunityIcons name={i.icon} color={color} size={24} style={{ margin: 4 }} />}
        label={i.title}
        onPress={() => nav.reset({
          index: 1,
          routes: [
            { name: '__primary', params: { screen: i.page } },
          ],
        })
        }
      />)}
      <Divider theme={{ dark: theme.id !== "white" }} />
      <View style={{ paddingTop: 8, paddingBottom: 4, paddingLeft: 8 }}>
        <Text allowFontScaling={false} style={{ fontSize: 16, ...font("bold"), color: theme.navigation.fg, opacity: 0.8 }}>{t('common:more')}</Text>
      </View>
      {more.map?.(i => <DrawerItem
        key={i.title}
        {...itemProps}
        style={{ marginVertical: 0, opacity: i.disabled ? 0.6 : 1 }}
        focused={route.name == i.page}
        icon={({ focused, color, size }) => <MaterialCommunityIcons name={i.icon} color={color} size={24} style={{ margin: 4 }} />}
        label={i.title}
        onPress={i.disabled ? null : (i.link ? () => Linking.openURL(i.page) : () => nav.reset({
          index: 1,
          routes: [
            { name: '__primary', params: { screen: i.page } },
          ],
        }))
        }
      />)}
      <Menu
        visible={donateOpen}
        onDismiss={() => setDonateOpen(false)}
        anchor={
          <DrawerItem
            {...itemProps}
            style={{ marginVertical: 0 }}
            icon={({ focused, color, size }) => <MaterialCommunityIcons name="coin" color={color} size={24} style={{ margin: 4 }} />}
            label={t('common:donate')}
            onPress={() => setDonateOpen(true)}
          />
        }
        contentStyle={{ backgroundColor: theme.page_content.bg, borderWidth: theme.page_content.border ? 1 : 0, borderColor: theme.page_content.border }}
      >
        <View style={{ paddingHorizontal: 4, alignItems: "stretch" }}>
          <Button style={{ marginHorizontal: 4 }} color="#F96854" mode="contained" onPress={() => Linking.openURL('https://patreon.com/CuppaZee')} icon="patreon">{t('app_info:patreon_donate')}</Button>
          <Button style={{ marginHorizontal: 4, marginTop: 4 }} color="#29abe0" mode="contained" onPress={() => Linking.openURL('https://ko-fi.com/sohcah')} icon="coffee">{t('app_info:kofi_donate')}</Button>
          <Menu
            visible={paypalOpen}
            onDismiss={() => setPaypalOpen(false)}
            anchor={
              <Button style={{ marginHorizontal: 4, marginTop: 4 }} color="#009CDE" mode="contained" onPress={() => setPaypalOpen(true)} icon="paypal">{t('app_info:paypal_donate')}</Button>
            }
          >
            <View style={{ paddingHorizontal: 8 }}>
              <Text>{t('app_info:paypal_donate_desc')}</Text>
            </View>
          </Menu>
        </View>
      </Menu>
      <Menu
        visible={helpOpen}
        onDismiss={() => setHelpOpen(false)}
        anchor={
          <DrawerItem
            {...itemProps}
            style={{ marginVertical: 0 }}
            icon={({ focused, color, size }) => <MaterialCommunityIcons name="help-circle" color={color} size={24} style={{ margin: 4 }} />}
            label={t('common:help')}
            onPress={() => setHelpOpen(true)}
          />
        }
        contentStyle={{ backgroundColor: theme.page_content.bg, borderWidth: theme.page_content.border ? 1 : 0, borderColor: theme.page_content.border }}
      >
        <View style={{ paddingHorizontal: 4, alignItems: "center" }}>
          <View style={{ flexDirection: "row" }}>
            <Text allowFontScaling={false} style={{ color: theme.page_content.fg, fontSize: 16, ...font("bold") }}>{t('common:contact.facebook')} </Text>
            <TouchableRipple onPress={() => Linking.openURL('https://m.me/CuppaZee')}><Text allowFontScaling={false} style={{ color: theme.page_content.fg == "#000000" ? 'blue' : 'lightblue', fontSize: 16, ...font("bold") }}>@CuppaZee</Text></TouchableRipple>
          </View>
          <Text allowFontScaling={false} style={{ color: theme.page_content.fg, fontSize: 16 }}>{t('common:contact.email')}</Text>
        </View>
      </Menu>
    </DrawerContentScrollView>
  );
}
Example #27
Source File: Bookmarks.js    From Legacy with Mozilla Public License 2.0 4 votes vote down vote up
export default function SearchScreen({ navigation }) {
  var { t } = useTranslation()
  var theme = useSelector(i => i.themes[i.theme])
  const dispatch = useDispatch();
  var input = React.useRef();
  var clanBookmarks = useSelector(i => i.clanBookmarks);
  function moveClan(index, direction) {
    const clanB = clanBookmarks.slice()
    const clan = clanB.splice(index, 1);
    clanB.splice(index + (direction === "up" ? -1 : 1), 0, clan[0]);
    dispatch(clanBookmarksR(clanB))
  }
  function removeClan(index) {
    const clanB = clanBookmarks.slice()
    const clan = clanB.splice(index, 1);
    dispatch(clanBookmarksR(clanB))
  }
  var userBookmarks = useSelector(i => i.userBookmarks);
  function moveUser(index, direction) {
    const userB = userBookmarks.slice()
    const user = userB.splice(index, 1);
    userB.splice(index + (direction === "up" ? -1 : 1), 0, user[0]);
    dispatch(userBookmarksR(userB))
  }
  function removeUser(index) {
    const userB = userBookmarks.slice()
    const user = userB.splice(index, 1);
    dispatch(userBookmarksR(userB))
  }
  return (
    <ScrollView
      contentContainerStyle={{ width: 600, maxWidth: "100%", alignItems: "stretch", flexDirection: "column", alignSelf: "center", padding: 4 }}
      style={{ flex: 1, backgroundColor: theme.page.bg }}>
      <View style={{ padding: 4 }}>
        <Card noPad>
          <View style={{ padding: 8, borderTopLeftRadius: 8, borderTopRightRadius: 8, backgroundColor: (theme.clan_header || theme.navigation).bg, flexDirection: "row", alignItems: "center" }}>
            <MaterialCommunityIcons style={{ marginHorizontal: 6 }} name="shield-half-full" size={24} color={(theme.clan_header || theme.navigation).fg} />
            <View style={{ flex: 1, paddingLeft: 4 }}>
              <Text allowFontScaling={false} style={{ ...font("bold"), fontSize: 16, color: (theme.clan_header || theme.navigation).fg }}>Clans</Text>
            </View>
          </View>
          {
            clanBookmarks.map((i, index) => <View style={{ padding: 8, paddingVertical: 4, flexDirection: "row", alignItems: "center" }}>
              <IconButton style={{ margin: 0 }} onPress={() => removeClan(index)} size={24} icon="close" color="#ff2222" />
              <Image style={{ height: 32, width: 32, marginRight: 4, borderRadius: 16 }} source={{ uri: i.logo ?? `https://munzee.global.ssl.fastly.net/images/clan_logos/${(i.clan_id || 0).toString(36)}.png` }} />
              <View style={{ flex: 1 }}>
                <Text allowFontScaling={false} style={{ ...font("bold"), fontSize: 16, color: theme.page_content.fg }}>{i.name}</Text>
                <Text allowFontScaling={false} style={{ ...font("bold"), fontSize: 12, color: theme.page_content.fg }}>#{i.tagline}</Text>
              </View>
              <IconButton style={{ margin: 0 }} disabled={index === 0} onPress={() => moveClan(index, 'up')} size={24} icon="chevron-up" color={theme.page_content.fg} />
              <IconButton style={{ margin: 0 }} disabled={index === clanBookmarks.length - 1} onPress={() => moveClan(index, 'down')} size={24} icon="chevron-down" color={theme.page_content.fg} />
              {/* <IconButton onPressIn={()=>{}} onPressOut={()=>{}} size={24} icon="drag" color={theme.page_content.fg} /> */}
            </View>)
          }
          <TouchableRipple onPress={() => navigation.navigate('ClanSearch')}>
            <View style={{ padding: 8, flexDirection: "row", alignItems: "center" }}>
              <MaterialCommunityIcons style={{ marginHorizontal: 6 }} size={24} name="plus" color={theme.page_content.fg} />
              <View style={{ flex: 1 }}>
                <Text allowFontScaling={false} style={{ ...font("bold"), fontSize: 16, color: theme.page_content.fg }}>Add Clan</Text>
              </View>
            </View>
          </TouchableRipple>
        </Card>
      </View>
      <View style={{ padding: 4 }}>
        <Card noPad>
          <View style={{ padding: 8, borderTopLeftRadius: 8, borderTopRightRadius: 8, backgroundColor: (theme.clan_header || theme.navigation).bg, flexDirection: "row", alignItems: "center" }}>
            <MaterialCommunityIcons style={{ marginHorizontal: 6 }} name="account" size={24} color={(theme.clan_header || theme.navigation).fg} />
            <View style={{ flex: 1, paddingLeft: 4 }}>
              <Text allowFontScaling={false} style={{ ...font("bold"), fontSize: 16, color: (theme.clan_header || theme.navigation).fg }}>Users</Text>
            </View>
          </View>
          {
            userBookmarks.map((i, index) => <View style={{ padding: 8, paddingVertical: 4, flexDirection: "row", alignItems: "center" }}>
              <IconButton style={{ margin: 0 }} onPress={() => removeUser(index)} size={24} icon="close" color="#ff2222" />
              <Image style={{ height: 32, width: 32, marginRight: 4, borderRadius: 16 }} source={{ uri: i.logo ?? `https://munzee.global.ssl.fastly.net/images/avatars/ua${Number(i.user_id || 0).toString(36)}.png` }} />
              <View style={{ flex: 1 }}>
                <Text allowFontScaling={false} style={{ ...font("bold"), fontSize: 16, color: theme.page_content.fg }}>{i.username}</Text>
                <Text allowFontScaling={false} style={{ ...font("bold"), fontSize: 12, color: theme.page_content.fg }}>{i.user_id}</Text>
              </View>
              <IconButton style={{ margin: 0 }} disabled={index === 0} onPress={() => moveUser(index, 'up')} size={24} icon="chevron-up" color={theme.page_content.fg} />
              <IconButton style={{ margin: 0 }} disabled={index === userBookmarks.length - 1} onPress={() => moveUser(index, 'down')} size={24} icon="chevron-down" color={theme.page_content.fg} />
              {/* <IconButton onPressIn={()=>{}} onPressOut={()=>{}} size={24} icon="drag" color={theme.page_content.fg} /> */}
            </View>)
          }
          <TouchableRipple onPress={() => navigation.navigate('UserSearch')}>
            <View style={{ padding: 8, flexDirection: "row", alignItems: "center" }}>
              <MaterialCommunityIcons style={{ marginHorizontal: 6 }} size={24} name="plus" color={theme.page_content.fg} />
              <View style={{ flex: 1 }}>
                <Text allowFontScaling={false} style={{ ...font("bold"), fontSize: 16, color: theme.page_content.fg }}>Add User</Text>
              </View>
            </View>
          </TouchableRipple>
        </Card>
      </View>
    </ScrollView>
  );
}
Example #28
Source File: Info.js    From Legacy with Mozilla Public License 2.0 4 votes vote down vote up
export default function SettingsScreen() {
  var { t } = useTranslation();
  var theme = useSelector(i => i.themes[i.theme]);
  var nav = useNavigation();
  var [open,setOpen] = React.useState(false);
  var [dev,setDev] = React.useState(0);
  var [devData,setDevData] = React.useState("N/A");

  React.useEffect(()=>{
    (async function(){
      switch(dev-5) {
        case 0:
          nav.navigate('Tools');
      }
    })()
  },[dev]);

  return (
    <ScrollView style={{ backgroundColor: theme.page_content.bg }} contentContainerStyle={{ padding: 8 }}>
      <View style={{ alignItems: "center" }}>
        <Image style={{ width: 300, height: 90.78 }} source={{ uri: 'https://server.cuppazee.app/logo.png' }} />
        <TouchableRipple onPress={()=>setDev(i=>i+1)}>
          <Text allowFontScaling={false} style={{ color: theme.page_content.fg, fontSize: 20, ...font("bold") }}>{dev<5?t('app_info:build_n', { build: Math.max(...Object.keys(changelogs).map(Number)) }):dev-4}</Text>
        </TouchableRipple>
        {dev>=5&&<Text allowFontScaling={false} style={{ color: theme.page_content.fg, fontSize: 20, ...font("bold") }}>{devData}</Text>}
      </View>
      <View style={{ height: 1, backgroundColor: theme.page_content.fg, opacity: 0.5, margin: 8 }}></View>
      <View style={{ alignItems: "center" }}>
        <Text allowFontScaling={false} style={{ color: theme.page_content.fg, fontSize: 24, ...font("bold") }}>{t('app_info:credits')}</Text>
      </View>
      <View style={{ flexDirection: "row", flexWrap: "wrap", justifyContent: "center" }}>
        {credits.filter(i => i.type == "dev").map(i => <TouchableRipple onPress={() => nav.navigate('UserDetails', { username: i.username })}>
          <View style={{ alignItems: "center", padding: 4, width: i.large ? 160 : 120 }}>
            <Image source={{ uri: `https://munzee.global.ssl.fastly.net/images/avatars/ua${i.user_id.toString(36)}.png` }} style={{ backgroundColor: "white", height: i.large ? 48 : 36, width: i.large ? 48 : 36, borderRadius: i.large ? 24 : 18 }} />
            <Text allowFontScaling={false} style={{ color: theme.page_content.fg, fontSize: i.large ? 20 : 16, ...font("bold") }}>{i.username}</Text>
            <Text allowFontScaling={false} style={{ color: theme.page_content.fg, fontSize: i.large ? 16 : 12, ...font() }}>{t('app_info:custom_titles.' + i.title)}</Text>
          </View>
        </TouchableRipple>)}
      </View>
      <View style={{ height: 1, backgroundColor: theme.page_content.fg, opacity: 0.5, margin: 8 }}></View>
      <Text allowFontScaling={false} style={{ color: theme.page_content.fg, fontSize: 20, ...font("bold"), textAlign: "center" }}>{t('app_info:translators')}</Text>
      <View style={{ flexDirection: "row", flexWrap: "wrap", justifyContent: "center" }}>
        {credits.filter(i => i.type == "translator").map(i => <TouchableRipple onPress={() => nav.navigate('UserDetails', { username: i.username })}>
          <View style={{ alignItems: "center", padding: 4, width: 120 }}>
            <Image source={{ uri: `https://munzee.global.ssl.fastly.net/images/avatars/ua${i.user_id.toString(36)}.png` }} style={{ backgroundColor: "white", height: 48, width: 48, borderRadius: 24 }} />
            <Text allowFontScaling={false} style={{ color: theme.page_content.fg, fontSize: 16, ...font("bold") }}>{i.username}</Text>
            <Text allowFontScaling={false} style={{ color: theme.page_content.fg, fontSize: 12, ...font() }}>{t('app_info:custom_titles.' + i.title)}</Text>
          </View>
        </TouchableRipple>)}
      </View>
      <View style={{ height: 1, backgroundColor: theme.page_content.fg, opacity: 0.5, margin: 8 }}></View>
      <Text allowFontScaling={false} style={{ color: theme.page_content.fg, fontSize: 20, ...font("bold"), textAlign: "center" }}>{t('app_info:database_contributors')}</Text>
      <View style={{ flexDirection: "row", flexWrap: "wrap", justifyContent: "center" }}>
        {credits.filter(i => i.type == "db").map(i => <TouchableRipple onPress={() => nav.navigate('UserDetails', { username: i.username })}>
          <View style={{ alignItems: "center", padding: 4, width: 100 }}>
            <Image source={{ uri: `https://munzee.global.ssl.fastly.net/images/avatars/ua${i.user_id.toString(36)}.png` }} style={{ backgroundColor: "white", height: 32, width: 32, borderRadius: 16 }} />
            <Text allowFontScaling={false} style={{ color: theme.page_content.fg, fontSize: 16, ...font("bold") }}>{i.username}</Text>
          </View>
        </TouchableRipple>)}
      </View>
      <View style={{ height: 1, backgroundColor: theme.page_content.fg, opacity: 0.5, margin: 8 }}></View>
      <Text allowFontScaling={false} style={{ color: theme.page_content.fg, fontSize: 20, ...font("bold"), textAlign: "center" }}>{t('app_info:patrons_and_supporters')}</Text>
      <View style={{ flexDirection: "row", flexWrap: "wrap", justifyContent: "center" }}>
        <Button style={{ marginHorizontal: 4 }} color="#F96854" mode="contained" onPress={() => Linking.openURL('https://patreon.com/CuppaZee')} icon="patreon">{t('app_info:patreon_donate')}</Button>
        <Button style={{ marginHorizontal: 4 }} color="#29abe0" mode="contained" onPress={() => Linking.openURL('https://ko-fi.com/sohcah')} icon="coffee">{t('app_info:kofi_donate')}</Button>
        <Menu
          visible={open}
          onDismiss={() => setOpen(false)}
          anchor={
            <Button style={{ marginHorizontal: 4 }} color="#009CDE" mode="contained" onPress={() => setOpen(true)} icon="paypal">{t('app_info:paypal_donate')}</Button>
          }
        >
          <View style={{paddingHorizontal:8}}>
            <Text>{t('app_info:paypal_donate_desc')}</Text>
          </View>
        </Menu>
      </View>
      <View style={{ flexDirection: "row", flexWrap: "wrap", justifyContent: "center" }}>
        {credits.filter(i => i.type == "supporter").map(i => <TouchableRipple onPress={() => nav.navigate('UserDetails', { username: i.username })}>
          <View style={{ alignItems: "center", padding: 4, width: 100 }}>
            <Image source={{ uri: `https://munzee.global.ssl.fastly.net/images/avatars/ua${i.user_id.toString(36)}.png` }} style={{ backgroundColor: "white", height: 36, width: 36, borderRadius: 18 }} />
            <Text allowFontScaling={false} numberOfLines={1} ellipsizeMode='head' style={{ color: theme.page_content.fg, fontSize: 12, ...font("bold") }}>{i.username}</Text>
          </View>
        </TouchableRipple>)}
      </View>
    </ScrollView>
  );
}
Example #29
Source File: DatePicker.js    From Legacy with Mozilla Public License 2.0 4 votes vote down vote up
export default function ({ t, noWrap, onChange, onSelect, value }) {
  const moment = useMoment();
  const theme = useSelector(i => i.themes[t || i.theme]);
  const [select, setSelect] = React.useState("date");
  const [date, setDate] = React.useState(value.date());
  const [month, setMonth] = React.useState(value.month());
  const [year, setYear] = React.useState(value.year());
  const [firstLoad, setFirstLoad] = React.useState(true);
  const [shownMonth, setShownMonth] = React.useState(value.month());
  const [shownYear, setShownYear] = React.useState(value.year());

  React.useEffect(() => {
    if (firstLoad) {
      setFirstLoad(false);
    } else {
      onChange(moment({ date, month, year }))
    }
  }, [date, month, year]);

  const monthStart = moment({ date: 1, month: shownMonth, year: shownYear }).day();
  const monthEnd = moment({ date: 1, month: shownMonth, year: shownYear }).add(1, "month").subtract(1, 'day').date();

  var grid = []
  var finishedGrid = false;
  for (var i = -1; !finishedGrid; i++) {
    let row = [];
    for (var j = 1; j <= 7; j++) {
      if ((7 * i) + j < monthStart) row.push(null)
      else if ((7 * i) + j - monthStart >= monthEnd) row.push(null)
      else row.push((7 * i) + j - monthStart + 1)
    }
    if (row.find(i => i)) grid.push(row);
    if ((7 * i) + 8 - monthStart >= monthEnd) finishedGrid = true;
  }

  return (
    <Wrapper t={t} noWrap={noWrap}>
      <TouchableRipple onPress={() => setSelect(select == "month" ? "date" : "month")}>
        <Text allowFontScaling={false} style={{ fontSize: 20, lineHeight: 20, ...font("bold"), color: theme.page_content.fg }}>{value.format('Do MMMM YYYY')}</Text>
      </TouchableRipple>
      <View style={{ flexDirection: "row", width: 400, maxWidth: "100%", alignSelf: "center" }}>
        <View style={{ flex: 6, height: 32, alignItems: "center", flexDirection: "row" }}>
          <IconButton size={16} icon="chevron-left" onPress={()=>{
            if(shownMonth==0) {
              setShownMonth(11);
              setShownYear(shownYear-1);
            } else {
              setShownMonth(shownMonth-1)
            }
          }} />
          <TouchableRipple style={{ flex: 1, alignSelf: "stretch", justifyContent: "center" }} onPress={() => setSelect(select == "month" ? "date" : "month")}>
            <Text allowFontScaling={false} style={{ ...font("bold"), textAlign: "center", opacity: 0.8, color: theme.page_content.fg }}>{moment({ month: shownMonth }).format('MMMM')}</Text>
          </TouchableRipple>
          <IconButton size={16} icon="chevron-right" onPress={()=>{
            if(shownMonth==11) {
              setShownMonth(0);
              setShownYear(shownYear+1);
            } else {
              setShownMonth(shownMonth+1)
            }
          }} />
        </View>
        <View style={{ flex: 4, height: 32, alignItems: "center", flexDirection: "row" }}>
          <IconButton size={16} icon="chevron-left" onPress={()=>setShownYear(shownYear-1)} />
          <TouchableRipple style={{ flex: 1, alignSelf: "stretch", justifyContent: "center" }} onPress={() => setSelect(select == "year" ? "date" : "year")}>
            <Text allowFontScaling={false} style={{ ...font("bold"), textAlign: "center", opacity: 0.8, color: theme.page_content.fg }}>{shownYear}</Text>
          </TouchableRipple>
          <IconButton size={16} icon="chevron-right" onPress={()=>setShownYear(shownYear+1)} />
        </View>
      </View>
      {select == "date" && <View style={{ flexDirection: "row", justifyContent: "space-evenly" }}>
        {["06", "07", "08", "09", "10", "11", "12"].map(i => <View style={{ marginTop: 8, width: 36,flexGrow:1, justifyContent: "center", alignItems: "center" }}>
          <Text allowFontScaling={false} style={{ color: theme.page_content.fg, opacity: 0.8, ...font("bold"), fontSize: 12 }}>{moment('2020-07-' + i).format('ddd')}</Text>
        </View>)}
      </View>}
      {select == "date" && grid.map(row => <View style={{ flexDirection: "row", justifyContent: "space-evenly" }}>
        {row.map(i => <View style={{width:"14%",flexGrow:1,alignItems:"center"}}>
          <TouchableRipple style={{ borderRadius: 18 }} onPress={i ? () => { setDate(i); setYear(shownYear); setMonth(shownMonth) } : null}>
            <View style={{ borderColor: theme.page_content.border, borderWidth: theme.page_content.border && (i == date && month == shownMonth && year == shownYear) ? 2 : 0, height: 36, width: 36, borderRadius: 18, backgroundColor: (i == date && month == shownMonth && year == shownYear) ? theme.navigation.bg : null, justifyContent: "center", alignItems: "center" }}>
              <Text allowFontScaling={false} style={{ color: (i == date && month == shownMonth && year == shownYear) ? theme.navigation.fg : theme.page_content.fg, ...font((i == date && month == shownMonth && year == shownYear) ? "bold" : null), fontSize: (i == date && month == shownMonth && year == shownYear) ? 16 : 14 }}>{i}</Text>
            </View>
          </TouchableRipple>
        </View>)}
      </View>)}
      {select == "year" && <ScrollView style={{ maxHeight: 200 }} contentContainerStyle={{ flexDirection: "row", flexWrap: "wrap", justifyContent: "space-evenly" }}>
        {yearList.map(i => <TouchableRipple style={{ borderRadius: 8 }} onPress={() => { setShownYear(i); setSelect("date") }}>
          <View style={{ borderColor: theme.page_content.border, borderWidth: theme.page_content.border && i == shownYear ? 2 : 0, height: 36, minWidth: 85, flexGrow: 1, borderRadius: 8, backgroundColor: i == shownYear ? theme.navigation.bg : null, justifyContent: "center", alignItems: "center" }}>
            <Text allowFontScaling={false} style={{ color: i == shownYear ? theme.navigation.fg : theme.page_content.fg, ...font(i == shownYear ? "bold" : null), fontSize: i == shownYear ? 16 : 14 }}>{i}</Text>
          </View>
        </TouchableRipple>)}
      </ScrollView>}
      {select == "month" && <ScrollView style={{ maxHeight: 200 }} contentContainerStyle={{ flexDirection: "row", flexWrap: "wrap", justifyContent: "space-evenly" }}>
        {monthList.map(i => <TouchableRipple style={{ borderRadius: 8 }} onPress={() => { setShownMonth(i); setSelect("date") }}>
          <View style={{ borderColor: theme.page_content.border, borderWidth: theme.page_content.border && i == shownMonth ? 2 : 0, height: 36, minWidth: 85, flexGrow: 1, borderRadius: 8, backgroundColor: i == shownMonth ? theme.navigation.bg : null, justifyContent: "center", alignItems: "center" }}>
            <Text allowFontScaling={false} style={{ color: i == shownMonth ? theme.navigation.fg : theme.page_content.fg, ...font(i == shownMonth ? "bold" : null), fontSize: i == shownMonth ? 16 : 14 }}>{moment({ month: i }).format('MMMM')}</Text>
          </View>
        </TouchableRipple>)}
      </ScrollView>}
    </Wrapper>
  );
}