-
Notifications
You must be signed in to change notification settings - Fork 106
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[#163591901,#163591918,#163591935] Messages Inbox/Deadlines/Archive Tabs (v2) #823
Changes from 2 commits
c11a1e7
c9de91c
22200e4
9b266d9
c054f16
f2fbc7b
978573a
101dcb3
0e253ee
0e0f7ec
e0ca3e0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,6 +8,7 @@ import { | |
StyleSheet | ||
} from "react-native"; | ||
|
||
import I18n from "../../i18n"; | ||
import customVariables from "../../theme/variables"; | ||
import { MessageWithContentAndDueDatePO } from "../../types/MessageWithContentAndDueDatePO"; | ||
import H5 from "../ui/H5"; | ||
|
@@ -38,7 +39,7 @@ type Props = { | |
// typescript definition. | ||
// tslint:disable-next-line:readonly-array | ||
sections: MessageAgendaSection[]; | ||
refreshing: boolean; | ||
isRefreshing: boolean; | ||
onRefresh: () => void; | ||
onPressItem: (id: string) => void; | ||
}; | ||
|
@@ -48,15 +49,15 @@ type Props = { | |
*/ | ||
class MessageAgenda extends React.PureComponent<Props> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The reference @matteodesanti gave me was the Agenda view of the Android Calendar app and is called "Agenda" also in the english version: |
||
public render() { | ||
const { sections, refreshing, onRefresh } = this.props; | ||
const { sections, isRefreshing, onRefresh } = this.props; | ||
return ( | ||
<SectionList | ||
sections={sections} | ||
keyExtractor={keyExtractor} | ||
stickySectionHeadersEnabled={true} | ||
alwaysBounceVertical={false} | ||
ItemSeparatorComponent={ItemSeparatorComponent} | ||
refreshing={refreshing} | ||
refreshing={isRefreshing} | ||
onRefresh={onRefresh} | ||
renderSectionHeader={this.renderSectionHeader} | ||
renderItem={this.renderItem} | ||
|
@@ -67,7 +68,10 @@ class MessageAgenda extends React.PureComponent<Props> { | |
private renderSectionHeader = (info: { section: MessageAgendaSection }) => { | ||
return ( | ||
<H5 style={styles.sectionHeader}> | ||
{format(info.section.title, "dddd D MMMM").toUpperCase()} | ||
{format( | ||
info.section.title, | ||
I18n.t("messages.agenda.sectionDate") | ||
).toUpperCase()} | ||
</H5> | ||
); | ||
}; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -26,6 +26,10 @@ type Props = { | |
onPress: (id: string) => void; | ||
}; | ||
|
||
/** | ||
* A component to render a single Agenda item. | ||
* Extends PureComponent to avoid unnecessary re-renders. | ||
*/ | ||
class MessageAgendaItem extends React.PureComponent<Props> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. add comment There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this could be an SFC There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It must be a PureComponent to avoid unnecessary rerender. |
||
public render() { | ||
const { subject, due_date } = this.props; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,7 +4,7 @@ import React, { ComponentProps } from "react"; | |
import { StyleSheet } from "react-native"; | ||
|
||
import I18n from "../../i18n"; | ||
import { lexicallyOrderedMessagesStateInfoSelector } from "../../store/reducers/entities/messages"; | ||
import { lexicallyOrderedMessagesStateSelector } from "../../store/reducers/entities/messages"; | ||
import { MessageState } from "../../store/reducers/entities/messages/messagesById"; | ||
import { | ||
InjectedWithMessagesSelectionProps, | ||
|
@@ -35,9 +35,7 @@ const styles = StyleSheet.create({ | |
}); | ||
|
||
type OwnProps = { | ||
messagesStateInfo: ReturnType< | ||
typeof lexicallyOrderedMessagesStateInfoSelector | ||
>; | ||
messagesState: ReturnType<typeof lexicallyOrderedMessagesStateSelector>; | ||
navigateToMessageDetail: (id: string) => void; | ||
setMessagesArchivedState: ( | ||
ids: ReadonlyArray<string>, | ||
|
@@ -53,14 +51,14 @@ type Props = Pick< | |
InjectedWithMessagesSelectionProps; | ||
|
||
type State = { | ||
lastMessageStatesUpdate: number; | ||
filteredMessageStates: ReturnType<typeof generateFilteredMessagesState>; | ||
lastMessagesState: ReturnType<typeof lexicallyOrderedMessagesStateSelector>; | ||
filteredMessageStates: ReturnType<typeof generateMessagesStateArchivedArray>; | ||
}; | ||
|
||
/** | ||
* Filter only the messages that are not archived. | ||
* Filter only the messages that are archived. | ||
*/ | ||
const generateFilteredMessagesState = ( | ||
const generateMessagesStateArchivedArray = ( | ||
potMessagesState: pot.Pot<ReadonlyArray<MessageState>, string> | ||
): ReadonlyArray<MessageState> => | ||
pot.getOrElse( | ||
|
@@ -77,22 +75,22 @@ const generateFilteredMessagesState = ( | |
*/ | ||
class MessagesArchive extends React.PureComponent<Props, State> { | ||
/** | ||
* The function is used to update the filteredMessageStates only when necessary. | ||
* Updates the filteredMessageStates only when necessary. | ||
*/ | ||
public static getDerivedStateFromProps( | ||
nextProps: Props, | ||
prevState: State | ||
): Partial<State> | null { | ||
const { lastMessageStatesUpdate } = prevState; | ||
const { lastMessagesState } = prevState; | ||
|
||
if (lastMessageStatesUpdate !== nextProps.messagesStateInfo.lastUpdate) { | ||
if (lastMessagesState !== nextProps.messagesState) { | ||
// The list was updated, we need to re-apply the filter and | ||
// save the result in the state. | ||
return { | ||
filteredMessageStates: generateFilteredMessagesState( | ||
nextProps.messagesStateInfo.potMessagesState | ||
filteredMessageStates: generateMessagesStateArchivedArray( | ||
nextProps.messagesState | ||
), | ||
lastMessageStatesUpdate: nextProps.messagesStateInfo.lastUpdate | ||
lastMessagesState: nextProps.messagesState | ||
}; | ||
} | ||
|
||
|
@@ -103,15 +101,13 @@ class MessagesArchive extends React.PureComponent<Props, State> { | |
constructor(props: Props) { | ||
super(props); | ||
this.state = { | ||
lastMessageStatesUpdate: 0, | ||
lastMessagesState: pot.none, | ||
filteredMessageStates: [] | ||
}; | ||
} | ||
|
||
public render() { | ||
const isLoading = pot.isLoading( | ||
this.props.messagesStateInfo.potMessagesState | ||
); | ||
const isLoading = pot.isLoading(this.props.messagesState); | ||
const { selectedMessageIds, resetSelection } = this.props; | ||
|
||
return ( | ||
|
@@ -144,6 +140,8 @@ class MessagesArchive extends React.PureComponent<Props, State> { | |
|
||
private handleOnPressItem = (id: string) => { | ||
if (this.props.selectedMessageIds.isSome()) { | ||
// Is the selection mode is active a simple "press" must act as | ||
// a "longPress" (select the item). | ||
this.handleOnLongPressItem(id); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. shouldn't this be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have to add a comment here. If we are in selection mode a "press" need act like the "longPress" (select the item). |
||
} else { | ||
this.props.navigateToMessageDetail(id); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this date format is not specific of the agenda view, it should be under the global namespace