-
Notifications
You must be signed in to change notification settings - Fork 635
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* init browser state * get tab index * rm
- Loading branch information
1 parent
c0f41c7
commit d6e35e4
Showing
2 changed files
with
162 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
import { useBrowserStateStore } from '.'; | ||
|
||
describe('BrowserStateStore', () => { | ||
beforeEach(() => { | ||
// Reset the store to its initial state before each test | ||
useBrowserStateStore.setState( | ||
{ | ||
tabs: [], | ||
}, | ||
true | ||
); // The second argument 'true' is to replace the state instead of merging | ||
}); | ||
|
||
test('should be able to add a tab', () => { | ||
const { addTab, tabs } = useBrowserStateStore.getState(); | ||
expect(tabs.length).toBe(0); | ||
addTab({ | ||
name: 'Test Tab', | ||
isActive: true, | ||
screenshot: 'test_screenshot.png', | ||
history: [ | ||
{ | ||
name: 'Test Site', | ||
url: 'https://test.com', | ||
image: 'test_image.png', | ||
timestamp: Date.now(), | ||
}, | ||
], | ||
}); | ||
expect(useBrowserStateStore.getState().tabs.length).toBe(1); | ||
}); | ||
|
||
test('should place new tabs at the end', () => { | ||
const { addTab } = useBrowserStateStore.getState(); | ||
addTab({ name: 'First Tab', screenshot: '', history: [], isActive: false }); | ||
addTab({ name: 'Second Tab', screenshot: '', history: [], isActive: false }); | ||
const tabs = useBrowserStateStore.getState().tabs; | ||
expect(tabs[tabs.length - 1].name).toBe('Second Tab'); | ||
}); | ||
|
||
test('should be able to delete a tab', () => { | ||
const { addTab, deleteTab, tabs } = useBrowserStateStore.getState(); | ||
addTab({ name: 'Tab to Delete', screenshot: '', history: [], isActive: false }); | ||
expect(tabs.length).toBe(1); | ||
deleteTab(0); | ||
expect(useBrowserStateStore.getState().tabs.length).toBe(0); | ||
}); | ||
|
||
test('should handle deleting the active tab', () => { | ||
const { addTab, deleteTab, setActiveTab, getActiveTab } = useBrowserStateStore.getState(); | ||
addTab({ name: 'Active Tab', screenshot: '', history: [], isActive: false }); | ||
addTab({ name: 'Next Tab', screenshot: '', history: [], isActive: false }); | ||
setActiveTab(0); | ||
expect(getActiveTab()?.name).toBe('Active Tab'); | ||
deleteTab(0); | ||
expect(getActiveTab()?.name).toBe('Next Tab'); | ||
}); | ||
|
||
test('should be able to edit a tab', () => { | ||
const { addTab, editTab, tabs } = useBrowserStateStore.getState(); | ||
addTab({ name: 'Tab to Edit', screenshot: '', history: [], isActive: false }); | ||
editTab(0, { name: 'Edited Tab' }); | ||
expect(tabs[0].name).toBe('Edited Tab'); | ||
}); | ||
|
||
test('editing a non-existent tab should do nothing', () => { | ||
const { editTab, tabs } = useBrowserStateStore.getState(); | ||
editTab(999, { name: 'Ghost Tab' }); // Assuming there's no tab at index 999 | ||
expect(tabs.length).toBe(0); // No tabs should have been added or modified | ||
}); | ||
|
||
test('should be able to set and get the active tab', () => { | ||
const { addTab, setActiveTab, getActiveTab } = useBrowserStateStore.getState(); | ||
addTab({ name: 'First Tab', screenshot: '', history: [], isActive: false }); | ||
addTab({ name: 'Second Tab', screenshot: '', history: [], isActive: false }); | ||
setActiveTab(1); | ||
expect(getActiveTab()?.name).toBe('Second Tab'); | ||
}); | ||
|
||
test('setting an active tab should deactivate others', () => { | ||
const { addTab, setActiveTab, tabs } = useBrowserStateStore.getState(); | ||
addTab({ name: 'First Tab', screenshot: '', history: [], isActive: true }); | ||
addTab({ name: 'Second Tab', screenshot: '', history: [], isActive: false }); | ||
setActiveTab(1); | ||
expect(tabs[0].isActive).toBe(false); | ||
expect(tabs[1].isActive).toBe(true); | ||
}); | ||
|
||
test('deleting the only tab should result in no active tabs', () => { | ||
const { addTab, deleteTab, tabs } = useBrowserStateStore.getState(); | ||
addTab({ name: 'Lonely Tab', screenshot: '', history: [], isActive: true }); | ||
deleteTab(0); | ||
expect(tabs.find(tab => tab.isActive)).toBe(undefined); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import create from 'zustand'; | ||
|
||
export interface Site { | ||
name: string; | ||
url: string; | ||
image: string; | ||
timestamp: number; // Assuming timestamp is a Unix timestamp for simplicity | ||
} | ||
|
||
export interface Tab { | ||
history: Site[]; | ||
name: string; | ||
screenshot: string; // Assuming this is a URL or base64 encoded image | ||
isActive: boolean; | ||
} | ||
|
||
interface BrowserState { | ||
tabs: Tab[]; | ||
addTab: (tab: Tab) => void; | ||
deleteTab: (tabIndex: number) => void; | ||
editTab: (tabIndex: number, newTabData: Partial<Tab>) => void; | ||
setActiveTab: (tabIndex: number) => void; | ||
getActiveTab: () => Tab | undefined; | ||
getActiveTabIndex: () => number; | ||
} | ||
|
||
export const useBrowserStateStore = create<BrowserState>((set, get) => ({ | ||
tabs: [], // Initial state of tabs is an empty array for now | ||
|
||
addTab: tab => | ||
set(state => ({ | ||
tabs: [...state.tabs, { ...tab, isActive: false }], | ||
})), | ||
|
||
deleteTab: tabIndex => | ||
set(state => { | ||
const newTabs = state.tabs.filter((_, index) => index !== tabIndex); | ||
// If the deleted tab was active, set the next tab as active, or the previous one if it was the last tab | ||
if (state.tabs[tabIndex].isActive) { | ||
if (newTabs.length > 0) { | ||
if (tabIndex === 0 || tabIndex < newTabs.length) { | ||
newTabs[tabIndex].isActive = true; | ||
} else { | ||
newTabs[tabIndex - 1].isActive = true; | ||
} | ||
} | ||
} | ||
return { tabs: newTabs }; | ||
}), | ||
|
||
editTab: (tabIndex, newTabData) => { | ||
set(state => ({ | ||
tabs: state.tabs.map((tab, index) => (index === tabIndex ? { ...tab, ...newTabData, timestamp: Date.now() } : tab)), | ||
})); | ||
}, | ||
|
||
setActiveTab: tabIndex => | ||
set(state => ({ | ||
tabs: state.tabs.map((tab, index) => ({ | ||
...tab, | ||
isActive: index === tabIndex, | ||
})), | ||
})), | ||
|
||
getActiveTab: () => get().tabs.find(tab => tab.isActive), | ||
getActiveTabIndex: () => get().tabs.findIndex(tab => tab.isActive), | ||
})); |