Switch to temporary 'fixed tabs' model for default and notifications

zio/stable
Paul Frazee 2022-12-08 14:21:28 -06:00
parent 539bf5d350
commit 53b8f0d040
3 changed files with 91 additions and 17 deletions

View File

@ -6,6 +6,20 @@ function genId() {
return ++__id
}
// NOTE
// this model was originally built for a freeform "tabs" concept like a browser
// we've since decided to pause that idea and do something more traditional
// until we're fully sure what that is, the tabs are being repurposed into a fixed topology
// - Tab 0: The "Default" tab
// - Tab 1: The "Notifications" tab
// These tabs always retain the first 2 items in their history.
// The default tab is used for basically everything except notifications.
// -prf
export enum TabPurpose {
Default = 0,
Notifs = 1,
}
interface HistoryItem {
url: string
ts: number
@ -17,14 +31,22 @@ export type HistoryPtr = [number, number]
export class NavigationTabModel {
id = genId()
history: HistoryItem[] = [
{url: '/menu', ts: Date.now(), id: genId()},
{url: '/', ts: Date.now(), id: genId()},
]
history: HistoryItem[]
index = 1
isNewTab = false
constructor() {
constructor(public fixedTabPurpose: TabPurpose) {
if (fixedTabPurpose === TabPurpose.Notifs) {
this.history = [
{url: '/menu', ts: Date.now(), id: genId()},
{url: '/notifications', ts: Date.now(), id: genId()},
]
} else {
this.history = [
{url: '/menu', ts: Date.now(), id: genId()},
{url: '/', ts: Date.now(), id: genId()},
]
}
makeAutoObservable(this, {
serialize: false,
hydrate: false,
@ -86,6 +108,12 @@ export class NavigationTabModel {
if (this.index < this.history.length - 1) {
this.history.length = this.index + 1
}
// TEMP ensure the tab has its purpose's main view -prf
if (this.history.length < 2) {
const fixedUrl =
this.fixedTabPurpose === TabPurpose.Notifs ? '/notifications' : '/'
this.history.push({url: fixedUrl, ts: Date.now(), id: genId()})
}
this.history.push({url, title, ts: Date.now(), id: genId()})
this.index = this.history.length - 1
}
@ -110,14 +138,19 @@ export class NavigationTabModel {
}
}
resetTo(path: string) {
if (this.index >= 1 && this.history[1]?.url === path) {
// fall back in history to target
// TEMP
// a helper to bring the tab back to its base state
// -prf
fixedTabReset() {
if (this.index >= 1) {
// fall back in history to "main" view
if (this.index > 1) {
this.index = 1
}
} else {
this.history = [this.history[0], {url: path, ts: Date.now(), id: genId()}]
const url =
this.fixedTabPurpose === TabPurpose.Notifs ? '/notifications' : '/'
this.history = [this.history[0], {url, ts: Date.now(), id: genId()}]
this.index = 1
}
}
@ -192,7 +225,10 @@ export class NavigationTabModel {
}
export class NavigationModel {
tabs: NavigationTabModel[] = [new NavigationTabModel()]
tabs: NavigationTabModel[] = [
new NavigationTabModel(TabPurpose.Default),
new NavigationTabModel(TabPurpose.Notifs),
]
tabIndex = 0
constructor() {
@ -203,7 +239,10 @@ export class NavigationModel {
}
clear() {
this.tabs = [new NavigationTabModel()]
this.tabs = [
new NavigationTabModel(TabPurpose.Default),
new NavigationTabModel(TabPurpose.Notifs),
]
this.tabIndex = 0
}
@ -258,11 +297,25 @@ export class NavigationModel {
// tab management
// =
// TEMP
// fixed tab helper function
// -prf
switchTo(purpose: TabPurpose, reset: boolean) {
if (purpose === TabPurpose.Notifs) {
this.tabIndex = 1
} else {
this.tabIndex = 0
}
if (reset) {
this.tab.fixedTabReset()
}
}
newTab(url: string, title?: string) {
if (!TABS_ENABLED) {
return this.navigate(url)
}
const tab = new NavigationTabModel()
const tab = new NavigationTabModel(TabPurpose.Default)
tab.navigate(url, title)
tab.isNewTab = true
this.tabs.push(tab)

View File

@ -37,7 +37,12 @@ export const Menu = ({navIdx, visible}: ScreenParams) => {
// =
const onNavigate = (url: string) => {
store.nav.navigate(url)
if (url === '/notifications') {
store.nav.switchTo(1, true)
} else {
store.nav.switchTo(0, true)
store.nav.navigate(url)
}
}
const onPressCreateScene = () => {
store.shell.openModal(new CreateSceneModel())

View File

@ -121,13 +121,29 @@ export const MobileShell: React.FC = observer(() => {
const screenRenderDesc = constructScreenRenderDesc(store.nav)
const onPressHome = () => {
if (store.nav.tab.current.url === '/') {
scrollElRef.current?.scrollToOffset({offset: 0})
if (store.nav.tab.fixedTabPurpose === 0) {
if (store.nav.tab.current.url === '/') {
scrollElRef.current?.scrollToOffset({offset: 0})
} else {
store.nav.tab.fixedTabReset()
}
} else {
store.nav.tab.resetTo('/')
store.nav.switchTo(0, false)
if (store.nav.tab.index === 0) {
store.nav.tab.fixedTabReset()
}
}
}
const onPressNotifications = () => {
if (store.nav.tab.fixedTabPurpose === 1) {
store.nav.tab.fixedTabReset()
} else {
store.nav.switchTo(1, false)
if (store.nav.tab.index === 0) {
store.nav.tab.fixedTabReset()
}
}
}
const onPressNotifications = () => store.nav.tab.resetTo('/notifications')
const onPressTabs = () => toggleTabsMenu(!isTabsSelectorActive)
const doNewTab = (url: string) => () => store.nav.newTab(url)