WIP scene UIs
parent
1ab8285ad3
commit
eceef67d46
|
@ -15,7 +15,7 @@ export interface ProfileUiParams {
|
|||
|
||||
export class ProfileUiModel {
|
||||
// constants
|
||||
static SELECTOR_ITEMS = ['Posts', 'Badges']
|
||||
static SELECTOR_ITEMS = ['Posts', 'Scenes']
|
||||
|
||||
// data
|
||||
profile: ProfileViewModel
|
||||
|
|
|
@ -86,14 +86,16 @@ export const ProfileHeader = observer(function ProfileHeader({
|
|||
<View style={[styles.displayNameLine]}>
|
||||
<Text style={styles.displayName}>{view.displayName}</Text>
|
||||
</View>
|
||||
<View style={styles.badgesLine}>
|
||||
{
|
||||
undefined /*<View style={styles.badgesLine}>
|
||||
<FontAwesomeIcon icon="shield" style={s.mr5} size={12} />
|
||||
<Link href="/" title="Badge TODO">
|
||||
<Text style={[s.f12, s.bold]}>
|
||||
Employee <Text style={[s.blue3]}>@blueskyweb.xyz</Text>
|
||||
</Text>
|
||||
</Link>
|
||||
</View>
|
||||
</View>*/
|
||||
}
|
||||
<View style={[styles.buttonsLine]}>
|
||||
{isMe ? (
|
||||
<TouchableOpacity
|
||||
|
|
|
@ -12,6 +12,8 @@ interface Layout {
|
|||
width: number
|
||||
}
|
||||
|
||||
const DEFAULT_SWIPE_GESTURE_INTERP = {value: 0}
|
||||
|
||||
export function Selector({
|
||||
selectedIndex,
|
||||
items,
|
||||
|
@ -20,7 +22,7 @@ export function Selector({
|
|||
}: {
|
||||
selectedIndex: number
|
||||
items: string[]
|
||||
swipeGestureInterp: SharedValue<number>
|
||||
swipeGestureInterp?: SharedValue<number>
|
||||
onSelect?: (index: number) => void
|
||||
}) {
|
||||
const [itemLayouts, setItemLayouts] = useState<undefined | Layout[]>(
|
||||
|
@ -41,26 +43,27 @@ export function Selector({
|
|||
return [left, middle, right]
|
||||
}, [selectedIndex, itemLayouts])
|
||||
|
||||
const interp = swipeGestureInterp || DEFAULT_SWIPE_GESTURE_INTERP
|
||||
const underlinePos = useAnimatedStyle(() => {
|
||||
const other =
|
||||
swipeGestureInterp.value === 0
|
||||
interp.value === 0
|
||||
? currentLayouts[1]
|
||||
: swipeGestureInterp.value < 0
|
||||
: interp.value < 0
|
||||
? currentLayouts[0]
|
||||
: currentLayouts[2]
|
||||
return {
|
||||
left: interpolate(
|
||||
Math.abs(swipeGestureInterp.value),
|
||||
Math.abs(interp.value),
|
||||
[0, 1],
|
||||
[currentLayouts[1].x, other.x],
|
||||
),
|
||||
width: interpolate(
|
||||
Math.abs(swipeGestureInterp.value),
|
||||
Math.abs(interp.value),
|
||||
[0, 1],
|
||||
[currentLayouts[1].width, other.width],
|
||||
),
|
||||
}
|
||||
}, [currentLayouts, swipeGestureInterp])
|
||||
}, [currentLayouts, interp])
|
||||
|
||||
const onLayout = () => {
|
||||
const promises = []
|
||||
|
@ -112,7 +115,7 @@ const styles = StyleSheet.create({
|
|||
backgroundColor: colors.white,
|
||||
},
|
||||
item: {
|
||||
marginRight: 20,
|
||||
marginRight: 14,
|
||||
paddingHorizontal: 10,
|
||||
},
|
||||
itemLabel: {
|
||||
|
|
|
@ -19,6 +19,7 @@ import {faCheck} from '@fortawesome/free-solid-svg-icons/faCheck'
|
|||
import {faCircleUser} from '@fortawesome/free-regular-svg-icons/faCircleUser'
|
||||
import {faClone} from '@fortawesome/free-regular-svg-icons/faClone'
|
||||
import {faComment} from '@fortawesome/free-regular-svg-icons/faComment'
|
||||
import {faCompass} from '@fortawesome/free-regular-svg-icons/faCompass'
|
||||
import {faEllipsis} from '@fortawesome/free-solid-svg-icons/faEllipsis'
|
||||
import {faEnvelope} from '@fortawesome/free-solid-svg-icons/faEnvelope'
|
||||
import {faExclamation} from '@fortawesome/free-solid-svg-icons/faExclamation'
|
||||
|
@ -69,6 +70,7 @@ export function setup() {
|
|||
faCircleUser,
|
||||
faClone,
|
||||
faComment,
|
||||
faCompass,
|
||||
faEllipsis,
|
||||
faEnvelope,
|
||||
faExclamation,
|
||||
|
|
|
@ -33,12 +33,37 @@ export function GridIcon({style}: {style?: StyleProp<ViewStyle>}) {
|
|||
|
||||
export function HomeIcon({style}: {style?: StyleProp<ViewStyle>}) {
|
||||
return (
|
||||
<Svg viewBox="0 0 48 48" width="24" height="24" style={style}>
|
||||
<Svg
|
||||
viewBox="0 0 48 48"
|
||||
width="24"
|
||||
height="24"
|
||||
stroke="currentColor"
|
||||
style={style}>
|
||||
<Path
|
||||
strokeWidth={4}
|
||||
stroke="#000"
|
||||
d="M 23.951 2 C 23.631 2.011 23.323 2.124 23.072 2.322 L 8.859 13.52 C 7.055 14.941 6 17.114 6 19.41 L 6 38.5 C 6 39.864 7.136 41 8.5 41 L 18.5 41 C 19.864 41 21 39.864 21 38.5 L 21 28.5 C 21 28.205 21.205 28 21.5 28 L 26.5 28 C 26.795 28 27 28.205 27 28.5 L 27 38.5 C 27 39.864 28.136 41 29.5 41 L 39.5 41 C 40.864 41 42 39.864 42 38.5 L 42 19.41 C 42 17.114 40.945 14.941 39.141 13.52 L 24.928 2.322 C 24.65 2.103 24.304 1.989 23.951 2 Z"
|
||||
/>
|
||||
</Svg>
|
||||
)
|
||||
}
|
||||
|
||||
// Copyright (c) 2020 Refactoring UI Inc.
|
||||
// https://github.com/tailwindlabs/heroicons/blob/master/LICENSE
|
||||
export function UserGroupIcon({style}: {style?: StyleProp<ViewStyle>}) {
|
||||
return (
|
||||
<Svg
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
width="32"
|
||||
height="32"
|
||||
strokeWidth={1.5}
|
||||
stroke="currentColor"
|
||||
style={style}>
|
||||
<Path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
d="M18 18.72a9.094 9.094 0 003.741-.479 3 3 0 00-4.682-2.72m.94 3.198l.001.031c0 .225-.012.447-.037.666A11.944 11.944 0 0112 21c-2.17 0-4.207-.576-5.963-1.584A6.062 6.062 0 016 18.719m12 0a5.971 5.971 0 00-.941-3.197m0 0A5.995 5.995 0 0012 12.75a5.995 5.995 0 00-5.058 2.772m0 0a3 3 0 00-4.681 2.72 8.986 8.986 0 003.74.477m.94-3.197a5.971 5.971 0 00-.94 3.197M15 6.75a3 3 0 11-6 0 3 3 0 016 0zm6 3a2.25 2.25 0 11-4.5 0 2.25 2.25 0 014.5 0zm-13.5 0a2.25 2.25 0 11-4.5 0 2.25 2.25 0 014.5 0z"
|
||||
/>
|
||||
</Svg>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ export const Contacts = ({visible, params}: ScreenParams) => {
|
|||
</View>
|
||||
</View>
|
||||
<Selector
|
||||
items={['All', 'Following']}
|
||||
items={['All', 'Following', 'Scenes']}
|
||||
selectedIndex={0}
|
||||
swipeGestureInterp={selectorInterp}
|
||||
/>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import React, {useState, useEffect} from 'react'
|
||||
import {View} from 'react-native'
|
||||
import {StyleSheet, Text, View} from 'react-native'
|
||||
import {Feed} from '../com/notifications/Feed'
|
||||
import {colors} from '../lib/styles'
|
||||
import {useStores} from '../../state'
|
||||
import {NotificationsViewModel} from '../../state/models/notifications-view'
|
||||
import {ScreenParams} from '../routes'
|
||||
|
@ -35,5 +36,24 @@ export const Notifications = ({visible}: ScreenParams) => {
|
|||
}
|
||||
}, [visible, store])
|
||||
|
||||
return <View>{notesView && <Feed view={notesView} />}</View>
|
||||
return (
|
||||
<View>
|
||||
<View style={styles.header}>
|
||||
<Text style={styles.title}>Notifications</Text>
|
||||
</View>
|
||||
{notesView && <Feed view={notesView} />}
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
header: {
|
||||
backgroundColor: colors.white,
|
||||
},
|
||||
title: {
|
||||
fontSize: 30,
|
||||
fontWeight: 'bold',
|
||||
paddingHorizontal: 12,
|
||||
paddingVertical: 6,
|
||||
},
|
||||
})
|
||||
|
|
|
@ -2,6 +2,7 @@ import React, {useEffect} from 'react'
|
|||
import {observer} from 'mobx-react-lite'
|
||||
import {
|
||||
Image,
|
||||
ImageSourcePropType,
|
||||
StyleSheet,
|
||||
SafeAreaView,
|
||||
Text,
|
||||
|
@ -17,7 +18,7 @@ import Animated, {
|
|||
} from 'react-native-reanimated'
|
||||
import {IconProp} from '@fortawesome/fontawesome-svg-core'
|
||||
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
|
||||
import {HomeIcon} from '../../lib/icons'
|
||||
import {HomeIcon, UserGroupIcon} from '../../lib/icons'
|
||||
import {useStores} from '../../../state'
|
||||
import {s, colors} from '../../lib/styles'
|
||||
import {DEF_AVATER} from '../../lib/assets'
|
||||
|
@ -68,7 +69,9 @@ export const MainMenu = observer(
|
|||
onPress={() => onNavigate(url)}>
|
||||
<View style={[styles.menuItemIconWrapper]}>
|
||||
{icon === 'home' ? (
|
||||
<HomeIcon style={styles.menuItemIcon} size={24} />
|
||||
<HomeIcon style={styles.menuItemIcon} />
|
||||
) : icon === 'user-group' ? (
|
||||
<UserGroupIcon style={styles.menuItemIcon} />
|
||||
) : (
|
||||
<FontAwesomeIcon
|
||||
icon={icon}
|
||||
|
@ -87,6 +90,32 @@ export const MainMenu = observer(
|
|||
</Text>
|
||||
</TouchableOpacity>
|
||||
)
|
||||
const MenuItemImage = ({
|
||||
img,
|
||||
label,
|
||||
url,
|
||||
count,
|
||||
}: {
|
||||
img: ImageSourcePropType
|
||||
label: string
|
||||
url: string
|
||||
count?: number
|
||||
}) => (
|
||||
<TouchableOpacity
|
||||
style={[styles.menuItem, styles.menuItemMargin]}
|
||||
onPress={() => onNavigate(url)}>
|
||||
<Image style={styles.menuItemImg} source={img} />
|
||||
{count ? (
|
||||
<View style={styles.menuItemCount}>
|
||||
<Text style={styles.menuItemCountLabel}>{count}</Text>
|
||||
</View>
|
||||
) : undefined}
|
||||
<Text style={styles.menuItemLabel} numberOfLines={1}>
|
||||
{label}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
)
|
||||
|
||||
if (!active) {
|
||||
return <View />
|
||||
}
|
||||
|
@ -118,22 +147,41 @@ export const MainMenu = observer(
|
|||
/>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
<View style={[styles.section]}>
|
||||
<Animated.View style={[styles.menuItems, menuItemsAnimStyle]}>
|
||||
<Animated.View style={[styles.section, menuItemsAnimStyle]}>
|
||||
<View style={[styles.menuItems]}>
|
||||
<MenuItem icon="home" label="Home" url="/" />
|
||||
<MenuItem
|
||||
icon={['far', 'circle-user']}
|
||||
label="Contacts"
|
||||
url="/contacts"
|
||||
/>
|
||||
<MenuItem
|
||||
icon={['far', 'bell']}
|
||||
label="Notifications"
|
||||
url="/notifications"
|
||||
count={store.me.notificationCount}
|
||||
/>
|
||||
</Animated.View>
|
||||
</View>
|
||||
|
||||
<Text style={styles.heading}>Scenes</Text>
|
||||
<View style={[styles.menuItems]}>
|
||||
<MenuItem icon={['far', 'compass']} label="Discover" url="/" />
|
||||
<MenuItem
|
||||
icon={'user-group'}
|
||||
label="Create Scene"
|
||||
url="/contacts"
|
||||
/>
|
||||
<MenuItemImage img={DEF_AVATER} label="Galaxy Brain" url="/" />
|
||||
<MenuItemImage
|
||||
img={DEF_AVATER}
|
||||
label="Paul's Friends"
|
||||
url="/"
|
||||
/>
|
||||
</View>
|
||||
<View style={[styles.menuItems]}>
|
||||
<MenuItemImage
|
||||
img={DEF_AVATER}
|
||||
label="Cool People Only"
|
||||
url="/"
|
||||
/>
|
||||
<MenuItemImage img={DEF_AVATER} label="Techsky" url="/" />
|
||||
</View>
|
||||
</Animated.View>
|
||||
</SafeAreaView>
|
||||
</Animated.View>
|
||||
</>
|
||||
|
@ -168,6 +216,13 @@ const styles = StyleSheet.create({
|
|||
section: {
|
||||
paddingHorizontal: 10,
|
||||
},
|
||||
heading: {
|
||||
fontSize: 21,
|
||||
fontWeight: 'bold',
|
||||
paddingHorizontal: 10,
|
||||
paddingTop: 6,
|
||||
paddingBottom: 12,
|
||||
},
|
||||
|
||||
profile: {
|
||||
paddingVertical: 10,
|
||||
|
@ -194,16 +249,20 @@ const styles = StyleSheet.create({
|
|||
|
||||
menuItems: {
|
||||
flexDirection: 'row',
|
||||
marginTop: 10,
|
||||
marginBottom: 10,
|
||||
marginBottom: 20,
|
||||
},
|
||||
menuItem: {
|
||||
width: 80,
|
||||
width: 82,
|
||||
alignItems: 'center',
|
||||
marginRight: 6,
|
||||
},
|
||||
menuItemMargin: {
|
||||
marginRight: 14,
|
||||
marginRight: 10,
|
||||
},
|
||||
menuItemImg: {
|
||||
borderRadius: 30,
|
||||
width: 60,
|
||||
height: 60,
|
||||
marginBottom: 5,
|
||||
},
|
||||
menuItemIconWrapper: {
|
||||
borderRadius: 6,
|
||||
|
@ -219,6 +278,7 @@ const styles = StyleSheet.create({
|
|||
},
|
||||
menuItemLabel: {
|
||||
fontSize: 13,
|
||||
textAlign: 'center',
|
||||
},
|
||||
menuItemCount: {
|
||||
position: 'absolute',
|
||||
|
|
|
@ -388,6 +388,7 @@ const styles = StyleSheet.create({
|
|||
color: colors.white,
|
||||
},
|
||||
ctrlIcon: {
|
||||
color: colors.black,
|
||||
marginLeft: 'auto',
|
||||
marginRight: 'auto',
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue