react-native-paper#Menu JavaScript Examples

The following examples show how to use react-native-paper#Menu. 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: 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 #2
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 #3
Source File: SHCPro.js    From Legacy with Mozilla Public License 2.0 6 votes vote down vote up
function DateSwitcher({ dateString }) {
  var moment = useMoment();
  const nav = useNavigation();
  const theme = useSelector(i=>i.themes[i.theme]);
  const [datePickerOpen,setDatePickerOpen] = React.useState(false);
  return <View style={{ padding: 4, width: 400, maxWidth: "100%", alignSelf: "center" }}>
    <Card cardStyle={{ backgroundColor: (theme.clanCardHeader || theme.navigation).bg }} noPad>
      <View style={{ flexDirection: "row", alignItems: "center" }}>
        <Menu
          visible={datePickerOpen}
          onDismiss={() => setDatePickerOpen(false)}
          anchor={
            <IconButton icon="calendar" color={(theme.clanCardHeader || theme.navigation).fg} onPress={() => setDatePickerOpen(true)} />
          }
          contentStyle={{ padding: 0, backgroundColor: theme.page_content.bg, borderWidth: theme.page_content.border ? 1 : 0, borderColor: theme.page_content.border, width: 300 }}
        >
          <DatePicker noWrap value={moment({
            year: Number(dateString.split('-')[0]),
            month: Number(dateString.split('-')[1]) - 1,
            date: Number(dateString.split('-')[2]),
          })} onChange={(date) => {
            nav.setParams({
              date: `${date.year()}-${(date.month() + 1).toString().padStart(2, '0')}-${(date.date()).toString().padStart(2, '0')}`
            })
          }} />
        </Menu>

        <Text allowFontScaling={false} style={{ flex: 1, ...font("bold"), fontSize: 16, color: (theme.clanCardHeader || theme.navigation).fg }}>{moment({
          year: Number(dateString.split('-')[0]),
          month: Number(dateString.split('-')[1]) - 1,
          date: Number(dateString.split('-')[2]),
        }).format('L')}</Text>
      </View>
    </Card>
  </View>
}
Example #4
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 #5
Source File: SHCLite.js    From Legacy with Mozilla Public License 2.0 6 votes vote down vote up
function DateSwitcher({ dateString }) {
  var moment = useMoment();
  const nav = useNavigation();
  const theme = useSelector(i=>i.themes[i.theme]);
  const [datePickerOpen,setDatePickerOpen] = React.useState(false);
  return <View style={{ padding: 4, width: 400, maxWidth: "100%", alignSelf: "center" }}>
    <Card cardStyle={{ backgroundColor: (theme.clanCardHeader || theme.navigation).bg }} noPad>
      <View style={{ flexDirection: "row", alignItems: "center" }}>
        <Menu
          visible={datePickerOpen}
          onDismiss={() => setDatePickerOpen(false)}
          anchor={
            <IconButton icon="calendar" color={(theme.clanCardHeader || theme.navigation).fg} onPress={() => setDatePickerOpen(true)} />
          }
          contentStyle={{ padding: 0, backgroundColor: theme.page_content.bg, borderWidth: theme.page_content.border ? 1 : 0, borderColor: theme.page_content.border, width: 300 }}
        >
          <DatePicker noWrap value={moment({
            year: Number(dateString.split('-')[0]),
            month: Number(dateString.split('-')[1]) - 1,
            date: Number(dateString.split('-')[2]),
          })} onChange={(date) => {
            nav.setParams({
              date: `${date.year()}-${(date.month() + 1).toString().padStart(2, '0')}-${(date.date()).toString().padStart(2, '0')}`
            })
          }} />
        </Menu>

        <Text allowFontScaling={false} style={{ flex: 1, ...font("bold"), fontSize: 16, color: (theme.clanCardHeader || theme.navigation).fg }}>{moment({
          year: Number(dateString.split('-')[0]),
          month: Number(dateString.split('-')[1]) - 1,
          date: Number(dateString.split('-')[2]),
        }).format('L')}</Text>
      </View>
    </Card>
  </View>
}
Example #6
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 #7
Source File: POI.js    From Legacy with Mozilla Public License 2.0 6 votes vote down vote up
function DateSwitcher({ dateString }) {
  var moment = useMoment();
  const nav = useNavigation();
  const theme = useSelector(i=>i.themes[i.theme]);
  const [datePickerOpen,setDatePickerOpen] = React.useState(false);
  return <View style={{ padding: 4, width: 400, maxWidth: "100%", alignSelf: "center" }}>
    <Card cardStyle={{ backgroundColor: (theme.clanCardHeader || theme.navigation).bg }} noPad>
      <View style={{ flexDirection: "row", alignItems: "center" }}>
        <Menu
          visible={datePickerOpen}
          onDismiss={() => setDatePickerOpen(false)}
          anchor={
            <IconButton icon="calendar" color={(theme.clanCardHeader || theme.navigation).fg} onPress={() => setDatePickerOpen(true)} />
          }
          contentStyle={{ padding: 0, backgroundColor: theme.page_content.bg, borderWidth: theme.page_content.border ? 1 : 0, borderColor: theme.page_content.border, width: 300 }}
        >
          <DatePicker noWrap value={moment({
            year: Number(dateString.split('-')[0]),
            month: Number(dateString.split('-')[1]) - 1,
            date: Number(dateString.split('-')[2]),
          })} onChange={(date) => {
            nav.setParams({
              date: `${date.year()}-${(date.month() + 1).toString().padStart(2, '0')}-${(date.date()).toString().padStart(2, '0')}`
            })
          }} />
        </Menu>

        <Text allowFontScaling={false} style={{ flex: 1, ...font("bold"), fontSize: 16, color: (theme.clanCardHeader || theme.navigation).fg }}>{moment({
          year: Number(dateString.split('-')[0]),
          month: Number(dateString.split('-')[1]) - 1,
          date: Number(dateString.split('-')[2]),
        }).format('L')}</Text>
      </View>
    </Card>
  </View>
}
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: Colour.js    From Legacy with Mozilla Public License 2.0 6 votes vote down vote up
function DateSwitcher({ dateString }) {
  var moment = useMoment();
  const nav = useNavigation();
  const theme = useSelector(i=>i.themes[i.theme]);
  const [datePickerOpen,setDatePickerOpen] = React.useState(false);
  return <View style={{ padding: 4, width: 400, maxWidth: "100%", alignSelf: "center" }}>
    <Card cardStyle={{ backgroundColor: (theme.clanCardHeader || theme.navigation).bg }} noPad>
      <View style={{ flexDirection: "row", alignItems: "center" }}>
        <Menu
          visible={datePickerOpen}
          onDismiss={() => setDatePickerOpen(false)}
          anchor={
            <IconButton icon="calendar" color={(theme.clanCardHeader || theme.navigation).fg} onPress={() => setDatePickerOpen(true)} />
          }
          contentStyle={{ padding: 0, backgroundColor: theme.page_content.bg, borderWidth: theme.page_content.border ? 1 : 0, borderColor: theme.page_content.border, width: 300 }}
        >
          <DatePicker noWrap value={moment({
            year: Number(dateString.split('-')[0]),
            month: Number(dateString.split('-')[1]) - 1,
            date: Number(dateString.split('-')[2]),
          })} onChange={(date) => {
            nav.setParams({
              date: `${date.year()}-${(date.month() + 1).toString().padStart(2, '0')}-${(date.date()).toString().padStart(2, '0')}`
            })
          }} />
        </Menu>

        <Text allowFontScaling={false} style={{ flex: 1, ...font("bold"), fontSize: 16, color: (theme.clanCardHeader || theme.navigation).fg }}>{moment({
          year: Number(dateString.split('-')[0]),
          month: Number(dateString.split('-')[1]) - 1,
          date: Number(dateString.split('-')[2]),
        }).format('L')}</Text>
      </View>
    </Card>
  </View>
}
Example #10
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 #11
Source File: Page.js    From Legacy with Mozilla Public License 2.0 6 votes vote down vote up
function DateSwitcher({ dateString, toggleDrawer }) {
  var moment = useMoment();
  const nav = useNavigation();
  const theme = useSelector(i => i.themes[i.theme]);
  const [datePickerOpen, setDatePickerOpen] = React.useState(false);
  return <View style={{ ...(theme.page_content.border ? { borderBottomWidth: 1, borderBottomColor: theme.page_content.border } : {}), borderTopLeftRadius: 8, borderTopRightRadius: 8, backgroundColor: (theme.clanCardHeader || theme.navigation).bg }}>
    <View style={{ flexDirection: "row", alignItems: "center" }}>
      <Menu
        visible={datePickerOpen}
        onDismiss={() => setDatePickerOpen(false)}
        anchor={
          <IconButton icon="calendar" color={(theme.clanCardHeader || theme.navigation).fg} onPress={() => setDatePickerOpen(true)} />
        }
        contentStyle={{ padding: 0, backgroundColor: theme.page_content.bg, borderWidth: theme.page_content.border ? 1 : 0, borderColor: theme.page_content.border, width: 300 }}
      >
        <DatePicker noWrap value={moment({
          year: Number(dateString.split('-')[0]),
          month: Number(dateString.split('-')[1]) - 1,
          date: Number(dateString.split('-')[2]),
        })} onChange={(date) => {
          nav.setParams({
            date: `${date.year()}-${(date.month() + 1).toString().padStart(2, '0')}-${(date.date()).toString().padStart(2, '0')}`
          })
        }} />
      </Menu>

      <Text allowFontScaling={false} style={{ flex: 1, ...font("bold"), fontSize: 16, color: (theme.clanCardHeader || theme.navigation).fg }}>{moment({
        year: Number(dateString.split('-')[0]),
        month: Number(dateString.split('-')[1]) - 1,
        date: Number(dateString.split('-')[2]),
      }).format('L')}</Text>
      {toggleDrawer && <IconButton icon="filter" color={(theme.clanCardHeader || theme.navigation).fg} onPress={() => toggleDrawer()} />}
    </View>
  </View>
}
Example #12
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 #13
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 #14
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 #15
Source File: Dropdown.js    From Legacy with Mozilla Public License 2.0 5 votes vote down vote up
export function Dropdown({
  onValueChange,
  selectedValue,
  style,
  testID,
  enabled,
  mode,
  itemStyle,
  children,
  ...rest
}) {
  const [open, setOpen] = React.useState(false);
  const [size, onLayout] = useComponentSize();
  return (
    <Menu
      visible={open}
      onDismiss={() => setOpen(false)}
      anchor={
        <TextInput
          style={style}
          right={
            <TextInput.Icon onPress={() => setOpen(true)} name="chevron-down" />
          }
          mode={mode}
          value={
            [].concat(children).find((i) => i.props.value === selectedValue)
              ?.props.label ?? selectedValue
          }
          disabled={enabled === false}
          editable={false}
          onLayout={onLayout}
          render={({ style, value, onLayout }) => (
            <TouchableWithoutFeedback
              onPress={enabled === false ? undefined : () => setOpen(true)}
            >
              <View
                style={{ paddingLeft: 14, display: "flex", flexDirection: "row", alignSelf: "stretch", flex: 1, alignItems: "center" }}
                onLayout={onLayout}
              >
                <Text style={{fontSize:16}}>{value}</Text>
              </View>
            </TouchableWithoutFeedback>
          )}
          {...rest}
        />
      }
      style={{
        marginTop: size?.height,
        width: size?.width,
      }}
    >
      <ScrollView style={{ maxHeight: 400 }}>
        {[].concat(children).map((item) => (
          <Menu.Item
            style={itemStyle}
            disabled={item.props.value === selectedValue}
            onPress={() => {
              onValueChange(item.props.value);
              setOpen(false);
            }}
            title={item.props.label}
          />
        ))}
      </ScrollView>
    </Menu>
  );
}
Example #16
Source File: RtdUriWriter.js    From react-native-nfc-rewriter with MIT License 5 votes vote down vote up
function RtdUriWriter(props, ref) {
  const [value, setValue] = React.useState(props.value?.value || '');
  const [prefix, setPrefix] = React.useState(props.value?.prefix || 'https://');
  const [showMenu, setShowMenu] = React.useState(false);
  const inputRef = React.useRef();

  if (ref) {
    ref.current = {
      getValue: () => ({value, prefix}),
    };
  }

  const writeNdef = async () => {
    inputRef.current && inputRef.current.blur();

    if (!value) {
      return;
    }

    let url = value;
    if (prefix !== '---') {
      url = prefix + value;
    }

    await NfcProxy.writeNdef({type: 'URI', value: url});
  };

  return (
    <View>
      <View style={{flexDirection: 'row', marginBottom: 10}}>
        <Menu
          visible={showMenu}
          onDismiss={() => setShowMenu(false)}
          anchor={
            <Button mode="outlined" onPress={() => setShowMenu(true)}>
              {prefix}
            </Button>
          }>
          {['https://', 'http://', '---'].map((type) => (
            <Menu.Item
              key={type}
              onPress={() => {
                setPrefix(type);
                setShowMenu(false);
              }}
              title={type}
            />
          ))}
        </Menu>
        <View style={{flex: 1}} />
      </View>

      <TextInput
        ref={inputRef}
        mode="outlined"
        label="URI"
        multiline={true}
        value={value}
        autoCapitalize={false}
        onChangeText={setValue}
        style={{marginBottom: 20}}
      />

      <Button mode="contained" labelStyle={{fontSize: 20}} onPress={writeNdef}>
        WRITE
      </Button>
    </View>
  );
}
Example #17
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 #18
Source File: tab-bar.js    From MediBuddy with MIT License 4 votes vote down vote up
function TabBar({
  state,
  descriptors,
  navigation,
  navigationState,
  position,
  theme,
}) {
  const { colors } = theme;
  const [visible, setvisible] = React.useState(false);
  /** Indicator transition */
  const indicatorTranslateX = Animated.interpolate(position, {
    inputRange: [0, 1, 2, 3],
    outputRange: [110, 2 * width + 24, 3 * width + 24, 4 * width + 48],
  });
  const indicatorWidth = Animated.interpolate(position, {
    inputRange: [0, 1, 2, 3],
    outputRange: [140, 100, 140, 100],
  });

  const TabIcon = ({ route, index }) => {
    const { options } = descriptors[route.key];
    const label =
      options.tabBarLabel !== undefined
        ? options.tabBarLabel
        : options.title !== undefined
        ? options.title
        : route.name;

    const isFocused = state.index === index;

    const onPress = () => {
      const event = navigation.emit({
        type: 'tabPress',
        target: route.key,
        canPreventDefault: true,
      });

      if (!isFocused && !event.defaultPrevented) {
        navigation.navigate(route.name);
      }
    };

    return (
      <TouchableOpacity key={index} style={styles.tab} onPress={onPress}>
        <Text
          style={
            (styles.tabTxt,
            {
              color:
                index === navigationState.index ? colors.accent : '#bdc3c7',
            })
          }>
          {label}
        </Text>
      </TouchableOpacity>
    );
  };

  return (
    <View>
      <GeneralStatusBar backgroundColor="#ffff" />
      <View style={styles.tabView}>
        <Avatar.Image
          size={50}
          style={styles.icon}
          source={{
            uri: 'https://i.ya-webdesign.com/images/male-avatar-icon-png-7.png',
          }}
        />

        {state.routes.map((route, index) => {
          return <TabIcon route={route} index={index} />;
        })}

        <View style={styles.sideMenu}>
          <Menu
            visible={visible}
            onDismiss={() => setvisible(false)}
            anchor={
              <TouchableOpacity onPress={() => setvisible(true)}>
                <View style={styles.dropView}>
                  <Text style={styles.name}>Dr. Christian Wade</Text>
                  <Icon name="keyboard-arrow-down" size={24} color="#bdc3c7" />
                </View>
              </TouchableOpacity>
            }>
            <Menu.Item onPress={() => {}} title="Request Leave" />
            <Menu.Item onPress={() => {}} title="Provide Feeback" />

            <Divider />
            <Menu.Item onPress={() => {}} title="Check for Updates" />
            <Menu.Item onPress={() => {}} title="Logout " />
          </Menu>

          <Avatar.Image
            size={50}
            style={styles.avatar}
            source={{
              uri:
                'https://i.ya-webdesign.com/images/male-avatar-icon-png-7.png',
            }}
          />
          <CustomIcon name="bell" />
          <CustomIcon name="settings" />
          <CustomIcon name="magnify" />
        </View>
      </View>
      <Animated.View
        style={[
          styles.indicator,
          {
            left: indicatorTranslateX,
            backgroundColor: colors.accent,
            width: indicatorWidth,
          },
        ]}
      />
    </View>
  );
}
Example #19
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 #20
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 #21
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>
  );
}