Skip to content
This repository has been archived by the owner on Mar 12, 2020. It is now read-only.

Commit

Permalink
Merge pull request #773 from textileio/andrew/small-group-view-update
Browse files Browse the repository at this point in the history
Small group view update
  • Loading branch information
andrewxhill committed Jan 3, 2019
2 parents 08cd77b + 4e683c3 commit 6fcaa24
Show file tree
Hide file tree
Showing 15 changed files with 209 additions and 240 deletions.
7 changes: 2 additions & 5 deletions App/Components/Avatar.tsx
Expand Up @@ -126,12 +126,9 @@ const mapStateToProps = (state: RootState, ownProps: OwnProps): StateProps => {

let peerColor = 'hsla(200, 60%, 100%, 0.3)'
if (ownProps.peerId) {
const last = ownProps.peerId.length - 1
const h = Math.floor(100 + 120 * ownProps.peerId.charCodeAt(last - 1) / 125)
const l = Math.floor(40 + 40 * ownProps.peerId.charCodeAt(last) / 125)
const lit = l < 100 ? l > 0 ? l : 0 : 100
const h = Math.floor(360 * ownProps.peerId.charCodeAt(ownProps.peerId.length - 1) / 125)
const hue = h < 360 ? h > 0 ? h : 0 : 360
peerColor = `hsla(${hue},60%,${lit}%,0.3)`
peerColor = `hsla(${hue},90%,60%,0.3)`
}

return {
Expand Down
4 changes: 2 additions & 2 deletions App/Components/ContactModal.tsx
Expand Up @@ -56,7 +56,7 @@ class ContactModal extends React.Component<DispatchStateProps & ScreenProps> {
</View>
<ScrollView style={styles.threadsList}>
<Text style={styles.threadsTitle}>
{this.props.threadThumbs.length > 0 ? 'Sharing in Threads:' : 'Not part of any shared threads'}
{this.props.threadThumbs.length > 0 ? 'Sharing in Groups:' : 'Not part of any shared groups'}
</Text>
{this.props.threadThumbs.map((thread, i) => (
<TouchableOpacity key={i} onPress={this.navigate(thread.id, thread.name)}>
Expand All @@ -77,7 +77,7 @@ interface DispatchStateProps {

const mapStateToProps = (state: RootState, ownProps: ScreenProps): DispatchStateProps => {
return {
threadThumbs: getThreadThumbs(state, ownProps.peerId)
threadThumbs: getThreadThumbs(state, ownProps.peerId, 'name')
}
}

Expand Down
76 changes: 76 additions & 0 deletions App/Components/GroupCard/index.tsx
@@ -0,0 +1,76 @@
import React from 'react'
import { View, Text, TouchableOpacity } from 'react-native'
import TextileImage from '../TextileImage'
import Avatar from '../Avatar'
import Icon from '../Icon'
import * as s from '../../Themes/Constants'
import { ThreadFilesInfo } from '../../NativeModules/Textile'

import styles, { cardImageStyle, ICON_WIDTH, ROW_COLUMN } from './statics/styles'

interface ScreenProps {
id: string
name: string
authors: string[]
thumb?: ThreadFilesInfo
onPress: (groupCardProps: any) => void
}

const GroupCard = (props: ScreenProps) => {
const { name, authors, thumb } = props
const getCallback = () => {
return () => {
props.onPress(props)
}
}
const getThumb = (): JSX.Element => {
if (thumb) {
return (
<View style={styles.imageContainer}>
<View style={styles.imageStretch}>
<TextileImage
target={thumb.target}
index={0}
forMinWidth={ICON_WIDTH}
resizeMode={'cover'}
style={{height: ROW_COLUMN}}
/>
</View>
</View>
)
}
return (
<Icon
style={styles.iconStyle}
name={'camera'}
size={ICON_WIDTH}
color={s.COLOR_FONT_DARK_ON_LIGHT_LIGHT}
/>
)
}
return (
<TouchableOpacity
style={styles.groupCard}
activeOpacity={0.95}
// ts-ignore
onPress={getCallback()}
>
<View style={styles.groupLeftColumn}>
{getThumb()}
</View>
<View style={styles.groupMiddleColumn}>
<Text numberOfLines={2} style={styles.groupName}>{name}</Text>
</View>
<View style={styles.groupRightColumn}>
<View style={styles.avatarContainer}>
{ authors.slice(0, 8).map((authorId: string, i: number) => {
const imageStyle = cardImageStyle(authors, i)
return (<Avatar key={authorId} style={imageStyle} peerId={authorId} />)
})}
</View>
</View>
</TouchableOpacity>
)
}

export default GroupCard
97 changes: 97 additions & 0 deletions App/Components/GroupCard/statics/styles.tsx
@@ -0,0 +1,97 @@
import { StyleSheet, ImageStyle } from 'react-native'
import * as s from '../../../Themes/Constants'

export const ROW_HEIGHT = 90
export const ROW_COLUMN = 60

export const ICON_WIDTH = ROW_COLUMN * 0.5

export function cardImageStyle (list: string[], index: number): ImageStyle {
const baseStyle = {
margin: 0,
padding: 0,
borderWidth: 2,
borderColor: s.COLOR_BACKGROUND_PRIMARY
} as ImageStyle

if (index >= 8) {
return {
display: 'none'
}
}

const marginLeft = index === 0 || index === 4 ? 0 : -(0.27 * ROW_COLUMN)
const marginBottom = list.length >= 4 ? -(0.44 * ROW_COLUMN) : 0
const marginTop = 0
return {
...baseStyle,
width: ROW_COLUMN * 0.66,
backgroundColor: 'white', // avoids any transparencies blending
marginBottom,
marginLeft,
marginTop,
alignSelf: list.length >= 4 ? 'flex-start' : 'center'
}
}

export default StyleSheet.create({
groupCard: {
flex: 1,
flexDirection: 'row',
height: ROW_HEIGHT,
marginHorizontal: 22,
alignSelf: 'center',
borderBottomColor: s.COLOR_GREY_LIGHT,
borderBottomWidth: 1
},
groupRightColumn: {
width: ROW_COLUMN * 2,
alignItems: 'center',
justifyContent: 'center',
flexDirection: 'row'
},
avatarContainer: {
width: ROW_COLUMN * 2,
height: ROW_HEIGHT / 2,
flexWrap: 'wrap',
justifyContent: 'flex-end',
flexDirection: 'row',
flex: 1
},
groupMiddleColumn: {
alignItems: 'flex-start',
justifyContent: 'center',
paddingLeft: 18,
flex: 1
},
groupName: {
fontFamily: 'BentonSans',
fontSize: 16,
color: s.COLOR_FONT_DARK_ON_LIGHT_MEDIUM
},
groupLeftColumn: {
alignItems: 'center',
justifyContent: 'center',
width: ICON_WIDTH * 1.5
},
iconStyle: {
margin: 0,
padding: 0,
width: ICON_WIDTH
},
imageContainer: {
overflow: 'hidden',
alignItems: 'center',
justifyContent: 'center',
borderRadius: 2,
width: ROW_COLUMN,
height: ROW_COLUMN
},
imageStretch: {
position: 'absolute',
top: 0,
bottom: 0,
left: 0,
right: 0
}
})
8 changes: 2 additions & 6 deletions App/Components/Styles/ThreadSelectorStyles.js
Expand Up @@ -24,14 +24,10 @@ export default StyleSheet.create({
right: 0
},
createThreadBox: {
borderWidth: 2,
borderColor: '#EEE',
borderStyle: 'dashed',
borderRadius: 10,
marginTop: 27,
marginTop: 12,
marginBottom: 29,
marginHorizontal: 10,
height: 150,
height: 80,
justifyContent: 'center',
alignContent: 'center',
alignItems: 'center'
Expand Down
50 changes: 24 additions & 26 deletions App/Components/ThreadSelector.tsx
Expand Up @@ -10,7 +10,7 @@ import { getThreads } from '../Redux/PhotoViewingSelectors'
import TextileNodeActions from '../Redux/TextileNodeRedux'
import UIActions from '../Redux/UIRedux'

import ThreadCard from '../SB/components/ThreadListCard'
import GroupCard from './GroupCard'
import styles from './Styles/ThreadSelectorStyles'
import { ThreadFilesInfo } from '../NativeModules/Textile'

Expand All @@ -26,9 +26,9 @@ class ThreadSelector extends React.Component<ScreenProps & StateProps & Dispatch
}

_renderItem = (rowData: any) => {
const item: ThreadPreview = rowData.item
const item: GroupAuthors = rowData.item
return (
<ThreadCard id={item.id} {...item} onPress={this._onPressItem} />
<GroupCard id={item.id} {...item} onPress={this._onPressItem} />
)
}

Expand All @@ -48,7 +48,7 @@ class ThreadSelector extends React.Component<ScreenProps & StateProps & Dispatch
this.props.refreshMessages()
}

_keyExtractor = (item: ThreadPreview) => item.id
_keyExtractor = (item: GroupAuthors) => item.id

render () {
return (
Expand All @@ -67,38 +67,36 @@ class ThreadSelector extends React.Component<ScreenProps & StateProps & Dispatch
}
}

interface ThreadPreview {
interface GroupAuthors {
readonly id: string
readonly name: string
readonly size: number
readonly photos: ReadonlyArray<ThreadFilesInfo>
readonly userCount: number
readonly updated: number
readonly latestPeerId?: string
readonly authors: string[]
readonly thumb?: ThreadFilesInfo
}

interface StateProps {
threads: ReadonlyArray<ThreadPreview>
threads: ReadonlyArray<GroupAuthors>
}

const mapStateToProps = (state: RootState): StateProps => {
const ownId = state.account.peerId.value
const threads = getThreads(state, 'date')
.map((thread) => {
return {
id: thread.id,
name: thread.name,
// total number of images in the thread
size: thread.photos.length,
// just keep the top 2
photos: thread.photos.slice(0, 3),
// get a rough count of distinct users
userCount: thread.photos.length > 0 ? [...new Set(thread.photos.map((photo) => photo.author_id))].length : 1,
// latest update based on the latest item
updated: thread.photos.length > 0 && thread.photos[0].date ? Date.parse(thread.photos[0].date) : 0,
// latest peer to push to the thread
latestPeerId: thread.photos.length > 0 && thread.photos[0].author_id ? thread.photos[0].author_id : undefined
}
})
.map((thread) => {
const authors: string[] = [...new Set(thread.photos.map((photo) => photo.author_id))].filter((id) => id !== ownId)
if (ownId && authors.length === 0) {
authors.unshift(ownId)
}
const thumb = thread.photos.length ? thread.photos[thread.photos.length - 1] : undefined
return {
id: thread.id,
name: thread.name,
// total number of images in the thread
size: thread.photos.length,
authors,
thumb
}
})
return {
threads
}
Expand Down
7 changes: 3 additions & 4 deletions App/Redux/PhotoViewingSelectors.ts
Expand Up @@ -116,14 +116,13 @@ export function getSharedPhotos (state: RootState): ReadonlyArray<SharedPhoto> {
})
}

export function getThreadThumbs (state: RootState, byPeerId: string): ReadonlyArray<ThreadThumbs> {
return Object.keys(state.photoViewing.threads)
.map((key) => state.photoViewing.threads[key]!)
export function getThreadThumbs (state: RootState, byPeerId: string, sortBy?: 'name' | 'date'): ReadonlyArray<ThreadThumbs> {
return getThreads(state, sortBy)
.filter((thread) => thread.photos.some((p) => p.author_id === byPeerId))
.map((thread) => {
return {
id: thread.id,
thumb: thread.photos.length > 0 ? thread.photos[0] : undefined,
thumb: thread.photos.length > 0 ? thread.photos[thread.photos.length - 1] : undefined,
name: thread.name
}
})
Expand Down
3 changes: 1 addition & 2 deletions App/SB/components/FeedItem/index.js
@@ -1,7 +1,6 @@
import React from 'react'
import moment from 'moment'
import { View, Text, TouchableOpacity } from 'react-native'
import ImageSc from 'react-native-scalable-image'
import * as NotificationServices from '../../../Services/Notifications'
import Avatar from '../../../Components/Avatar'
import TextileImage from '../../../Components/TextileImage'
Expand All @@ -28,7 +27,7 @@ const FeedItem = props => {
height: 29,
borderRadius: 16,
borderWidth: 2,
borderColor: '#dbc5d2'
borderColor: 'rgba(255, 28, 63, 0.2)'
}

const leftSource = (
Expand Down

0 comments on commit 6fcaa24

Please sign in to comment.