WIP scene UIs
parent
1ab8285ad3
commit
eceef67d46
|
@ -15,7 +15,7 @@ export interface ProfileUiParams {
|
||||||
|
|
||||||
export class ProfileUiModel {
|
export class ProfileUiModel {
|
||||||
// constants
|
// constants
|
||||||
static SELECTOR_ITEMS = ['Posts', 'Badges']
|
static SELECTOR_ITEMS = ['Posts', 'Scenes']
|
||||||
|
|
||||||
// data
|
// data
|
||||||
profile: ProfileViewModel
|
profile: ProfileViewModel
|
||||||
|
|
|
@ -86,14 +86,16 @@ export const ProfileHeader = observer(function ProfileHeader({
|
||||||
<View style={[styles.displayNameLine]}>
|
<View style={[styles.displayNameLine]}>
|
||||||
<Text style={styles.displayName}>{view.displayName}</Text>
|
<Text style={styles.displayName}>{view.displayName}</Text>
|
||||||
</View>
|
</View>
|
||||||
<View style={styles.badgesLine}>
|
{
|
||||||
|
undefined /*<View style={styles.badgesLine}>
|
||||||
<FontAwesomeIcon icon="shield" style={s.mr5} size={12} />
|
<FontAwesomeIcon icon="shield" style={s.mr5} size={12} />
|
||||||
<Link href="/" title="Badge TODO">
|
<Link href="/" title="Badge TODO">
|
||||||
<Text style={[s.f12, s.bold]}>
|
<Text style={[s.f12, s.bold]}>
|
||||||
Employee <Text style={[s.blue3]}>@blueskyweb.xyz</Text>
|
Employee <Text style={[s.blue3]}>@blueskyweb.xyz</Text>
|
||||||
</Text>
|
</Text>
|
||||||
</Link>
|
</Link>
|
||||||
</View>
|
</View>*/
|
||||||
|
}
|
||||||
<View style={[styles.buttonsLine]}>
|
<View style={[styles.buttonsLine]}>
|
||||||
{isMe ? (
|
{isMe ? (
|
||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
|
|
|
@ -12,6 +12,8 @@ interface Layout {
|
||||||
width: number
|
width: number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const DEFAULT_SWIPE_GESTURE_INTERP = {value: 0}
|
||||||
|
|
||||||
export function Selector({
|
export function Selector({
|
||||||
selectedIndex,
|
selectedIndex,
|
||||||
items,
|
items,
|
||||||
|
@ -20,7 +22,7 @@ export function Selector({
|
||||||
}: {
|
}: {
|
||||||
selectedIndex: number
|
selectedIndex: number
|
||||||
items: string[]
|
items: string[]
|
||||||
swipeGestureInterp: SharedValue<number>
|
swipeGestureInterp?: SharedValue<number>
|
||||||
onSelect?: (index: number) => void
|
onSelect?: (index: number) => void
|
||||||
}) {
|
}) {
|
||||||
const [itemLayouts, setItemLayouts] = useState<undefined | Layout[]>(
|
const [itemLayouts, setItemLayouts] = useState<undefined | Layout[]>(
|
||||||
|
@ -41,26 +43,27 @@ export function Selector({
|
||||||
return [left, middle, right]
|
return [left, middle, right]
|
||||||
}, [selectedIndex, itemLayouts])
|
}, [selectedIndex, itemLayouts])
|
||||||
|
|
||||||
|
const interp = swipeGestureInterp || DEFAULT_SWIPE_GESTURE_INTERP
|
||||||
const underlinePos = useAnimatedStyle(() => {
|
const underlinePos = useAnimatedStyle(() => {
|
||||||
const other =
|
const other =
|
||||||
swipeGestureInterp.value === 0
|
interp.value === 0
|
||||||
? currentLayouts[1]
|
? currentLayouts[1]
|
||||||
: swipeGestureInterp.value < 0
|
: interp.value < 0
|
||||||
? currentLayouts[0]
|
? currentLayouts[0]
|
||||||
: currentLayouts[2]
|
: currentLayouts[2]
|
||||||
return {
|
return {
|
||||||
left: interpolate(
|
left: interpolate(
|
||||||
Math.abs(swipeGestureInterp.value),
|
Math.abs(interp.value),
|
||||||
[0, 1],
|
[0, 1],
|
||||||
[currentLayouts[1].x, other.x],
|
[currentLayouts[1].x, other.x],
|
||||||
),
|
),
|
||||||
width: interpolate(
|
width: interpolate(
|
||||||
Math.abs(swipeGestureInterp.value),
|
Math.abs(interp.value),
|
||||||
[0, 1],
|
[0, 1],
|
||||||
[currentLayouts[1].width, other.width],
|
[currentLayouts[1].width, other.width],
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}, [currentLayouts, swipeGestureInterp])
|
}, [currentLayouts, interp])
|
||||||
|
|
||||||
const onLayout = () => {
|
const onLayout = () => {
|
||||||
const promises = []
|
const promises = []
|
||||||
|
@ -112,7 +115,7 @@ const styles = StyleSheet.create({
|
||||||
backgroundColor: colors.white,
|
backgroundColor: colors.white,
|
||||||
},
|
},
|
||||||
item: {
|
item: {
|
||||||
marginRight: 20,
|
marginRight: 14,
|
||||||
paddingHorizontal: 10,
|
paddingHorizontal: 10,
|
||||||
},
|
},
|
||||||
itemLabel: {
|
itemLabel: {
|
||||||
|
|
|
@ -19,6 +19,7 @@ import {faCheck} from '@fortawesome/free-solid-svg-icons/faCheck'
|
||||||
import {faCircleUser} from '@fortawesome/free-regular-svg-icons/faCircleUser'
|
import {faCircleUser} from '@fortawesome/free-regular-svg-icons/faCircleUser'
|
||||||
import {faClone} from '@fortawesome/free-regular-svg-icons/faClone'
|
import {faClone} from '@fortawesome/free-regular-svg-icons/faClone'
|
||||||
import {faComment} from '@fortawesome/free-regular-svg-icons/faComment'
|
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 {faEllipsis} from '@fortawesome/free-solid-svg-icons/faEllipsis'
|
||||||
import {faEnvelope} from '@fortawesome/free-solid-svg-icons/faEnvelope'
|
import {faEnvelope} from '@fortawesome/free-solid-svg-icons/faEnvelope'
|
||||||
import {faExclamation} from '@fortawesome/free-solid-svg-icons/faExclamation'
|
import {faExclamation} from '@fortawesome/free-solid-svg-icons/faExclamation'
|
||||||
|
@ -69,6 +70,7 @@ export function setup() {
|
||||||
faCircleUser,
|
faCircleUser,
|
||||||
faClone,
|
faClone,
|
||||||
faComment,
|
faComment,
|
||||||
|
faCompass,
|
||||||
faEllipsis,
|
faEllipsis,
|
||||||
faEnvelope,
|
faEnvelope,
|
||||||
faExclamation,
|
faExclamation,
|
||||||
|
|
|
@ -33,12 +33,37 @@ export function GridIcon({style}: {style?: StyleProp<ViewStyle>}) {
|
||||||
|
|
||||||
export function HomeIcon({style}: {style?: StyleProp<ViewStyle>}) {
|
export function HomeIcon({style}: {style?: StyleProp<ViewStyle>}) {
|
||||||
return (
|
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
|
<Path
|
||||||
strokeWidth={4}
|
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"
|
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>
|
</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>
|
||||||
</View>
|
</View>
|
||||||
<Selector
|
<Selector
|
||||||
items={['All', 'Following']}
|
items={['All', 'Following', 'Scenes']}
|
||||||
selectedIndex={0}
|
selectedIndex={0}
|
||||||
swipeGestureInterp={selectorInterp}
|
swipeGestureInterp={selectorInterp}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import React, {useState, useEffect} from 'react'
|
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 {Feed} from '../com/notifications/Feed'
|
||||||
|
import {colors} from '../lib/styles'
|
||||||
import {useStores} from '../../state'
|
import {useStores} from '../../state'
|
||||||
import {NotificationsViewModel} from '../../state/models/notifications-view'
|
import {NotificationsViewModel} from '../../state/models/notifications-view'
|
||||||
import {ScreenParams} from '../routes'
|
import {ScreenParams} from '../routes'
|
||||||
|
@ -35,5 +36,24 @@ export const Notifications = ({visible}: ScreenParams) => {
|
||||||
}
|
}
|
||||||
}, [visible, store])
|
}, [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 {observer} from 'mobx-react-lite'
|
||||||
import {
|
import {
|
||||||
Image,
|
Image,
|
||||||
|
ImageSourcePropType,
|
||||||
StyleSheet,
|
StyleSheet,
|
||||||
SafeAreaView,
|
SafeAreaView,
|
||||||
Text,
|
Text,
|
||||||
|
@ -17,7 +18,7 @@ import Animated, {
|
||||||
} from 'react-native-reanimated'
|
} from 'react-native-reanimated'
|
||||||
import {IconProp} from '@fortawesome/fontawesome-svg-core'
|
import {IconProp} from '@fortawesome/fontawesome-svg-core'
|
||||||
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
|
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
|
||||||
import {HomeIcon} from '../../lib/icons'
|
import {HomeIcon, UserGroupIcon} from '../../lib/icons'
|
||||||
import {useStores} from '../../../state'
|
import {useStores} from '../../../state'
|
||||||
import {s, colors} from '../../lib/styles'
|
import {s, colors} from '../../lib/styles'
|
||||||
import {DEF_AVATER} from '../../lib/assets'
|
import {DEF_AVATER} from '../../lib/assets'
|
||||||
|
@ -68,7 +69,9 @@ export const MainMenu = observer(
|
||||||
onPress={() => onNavigate(url)}>
|
onPress={() => onNavigate(url)}>
|
||||||
<View style={[styles.menuItemIconWrapper]}>
|
<View style={[styles.menuItemIconWrapper]}>
|
||||||
{icon === 'home' ? (
|
{icon === 'home' ? (
|
||||||
<HomeIcon style={styles.menuItemIcon} size={24} />
|
<HomeIcon style={styles.menuItemIcon} />
|
||||||
|
) : icon === 'user-group' ? (
|
||||||
|
<UserGroupIcon style={styles.menuItemIcon} />
|
||||||
) : (
|
) : (
|
||||||
<FontAwesomeIcon
|
<FontAwesomeIcon
|
||||||
icon={icon}
|
icon={icon}
|
||||||
|
@ -87,6 +90,32 @@ export const MainMenu = observer(
|
||||||
</Text>
|
</Text>
|
||||||
</TouchableOpacity>
|
</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) {
|
if (!active) {
|
||||||
return <View />
|
return <View />
|
||||||
}
|
}
|
||||||
|
@ -118,22 +147,41 @@ export const MainMenu = observer(
|
||||||
/>
|
/>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
</View>
|
</View>
|
||||||
<View style={[styles.section]}>
|
<Animated.View style={[styles.section, menuItemsAnimStyle]}>
|
||||||
<Animated.View style={[styles.menuItems, menuItemsAnimStyle]}>
|
<View style={[styles.menuItems]}>
|
||||||
<MenuItem icon="home" label="Home" url="/" />
|
<MenuItem icon="home" label="Home" url="/" />
|
||||||
<MenuItem
|
|
||||||
icon={['far', 'circle-user']}
|
|
||||||
label="Contacts"
|
|
||||||
url="/contacts"
|
|
||||||
/>
|
|
||||||
<MenuItem
|
<MenuItem
|
||||||
icon={['far', 'bell']}
|
icon={['far', 'bell']}
|
||||||
label="Notifications"
|
label="Notifications"
|
||||||
url="/notifications"
|
url="/notifications"
|
||||||
count={store.me.notificationCount}
|
count={store.me.notificationCount}
|
||||||
/>
|
/>
|
||||||
</Animated.View>
|
</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>
|
</SafeAreaView>
|
||||||
</Animated.View>
|
</Animated.View>
|
||||||
</>
|
</>
|
||||||
|
@ -168,6 +216,13 @@ const styles = StyleSheet.create({
|
||||||
section: {
|
section: {
|
||||||
paddingHorizontal: 10,
|
paddingHorizontal: 10,
|
||||||
},
|
},
|
||||||
|
heading: {
|
||||||
|
fontSize: 21,
|
||||||
|
fontWeight: 'bold',
|
||||||
|
paddingHorizontal: 10,
|
||||||
|
paddingTop: 6,
|
||||||
|
paddingBottom: 12,
|
||||||
|
},
|
||||||
|
|
||||||
profile: {
|
profile: {
|
||||||
paddingVertical: 10,
|
paddingVertical: 10,
|
||||||
|
@ -194,16 +249,20 @@ const styles = StyleSheet.create({
|
||||||
|
|
||||||
menuItems: {
|
menuItems: {
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
marginTop: 10,
|
marginBottom: 20,
|
||||||
marginBottom: 10,
|
|
||||||
},
|
},
|
||||||
menuItem: {
|
menuItem: {
|
||||||
width: 80,
|
width: 82,
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
marginRight: 6,
|
|
||||||
},
|
},
|
||||||
menuItemMargin: {
|
menuItemMargin: {
|
||||||
marginRight: 14,
|
marginRight: 10,
|
||||||
|
},
|
||||||
|
menuItemImg: {
|
||||||
|
borderRadius: 30,
|
||||||
|
width: 60,
|
||||||
|
height: 60,
|
||||||
|
marginBottom: 5,
|
||||||
},
|
},
|
||||||
menuItemIconWrapper: {
|
menuItemIconWrapper: {
|
||||||
borderRadius: 6,
|
borderRadius: 6,
|
||||||
|
@ -219,6 +278,7 @@ const styles = StyleSheet.create({
|
||||||
},
|
},
|
||||||
menuItemLabel: {
|
menuItemLabel: {
|
||||||
fontSize: 13,
|
fontSize: 13,
|
||||||
|
textAlign: 'center',
|
||||||
},
|
},
|
||||||
menuItemCount: {
|
menuItemCount: {
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
|
|
|
@ -388,6 +388,7 @@ const styles = StyleSheet.create({
|
||||||
color: colors.white,
|
color: colors.white,
|
||||||
},
|
},
|
||||||
ctrlIcon: {
|
ctrlIcon: {
|
||||||
|
color: colors.black,
|
||||||
marginLeft: 'auto',
|
marginLeft: 'auto',
|
||||||
marginRight: 'auto',
|
marginRight: 'auto',
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue