cinera_search_pre.js: Default to the List View

Also fix the 𝑛-ary Grid traversal PrevAscends case when the search page
contains only one project at the top-level.
This commit is contained in:
Matt Mascarenhas 2021-04-12 17:56:30 +01:00
parent 828fff7a7a
commit 9512df0be0
2 changed files with 105 additions and 68 deletions

View File

@ -23,7 +23,7 @@ typedef struct
version CINERA_APP_VERSION = { version CINERA_APP_VERSION = {
.Major = 0, .Major = 0,
.Minor = 8, .Minor = 8,
.Patch = 10 .Patch = 11
}; };
#include <stdarg.h> // NOTE(matt): varargs #include <stdarg.h> // NOTE(matt): varargs
@ -13308,7 +13308,7 @@ SearchToBuffer(buffers *CollationBuffers, db_header_project *StoredP, project *P
OpenNodeNewLine(B, &IndentationLevel, NODE_DIV, 0); OpenNodeNewLine(B, &IndentationLevel, NODE_DIV, 0);
AppendStringToBuffer(B, Wrap0(" class=\"cineraMenuItem view\">")); AppendStringToBuffer(B, Wrap0(" class=\"cineraMenuItem view\">"));
AppendStringToBuffer(B, Wrap0("View: Grid")); AppendStringToBuffer(B, Wrap0("View: List"));
CloseNode(B, &IndentationLevel, NODE_DIV); CloseNode(B, &IndentationLevel, NODE_DIV);
OpenNodeNewLine(B, &IndentationLevel, NODE_DIV, 0); OpenNodeNewLine(B, &IndentationLevel, NODE_DIV, 0);

View File

@ -673,7 +673,7 @@ var Nav = {
GridRowGap: null, GridRowGap: null,
SortChronological: true, SortChronological: true,
ViewType: view_type.GRID, ViewType: view_type.LIST,
List: null, List: null,
Grid: null, Grid: null,
@ -921,6 +921,25 @@ InitHelpKeys(HelpDocumentation)
Nav.Controls.HelpKeys = Paragraph.querySelectorAll(".help_key"); Nav.Controls.HelpKeys = Paragraph.querySelectorAll(".help_key");
} }
function
InitView()
{
// NOTE(matt): Nav.ViewType is initialised to view_type.LIST and InitNexus() leaves the List View visible
if(!StateBitIsSet(state_bit.VIEW_LIST))
{
if(GridSizeIsSupported(Nav.GridSize))
{
PickGridView();
}
else
{
// NOTE(matt): Silently swap the state bits, leaving the default List View visible
ClearStateBit(state_bit.VIEW_GRID);
SetStateBit(state_bit.VIEW_LIST);
}
}
}
function function
SyncNavState() SyncNavState()
{ {
@ -931,31 +950,27 @@ SyncNavState()
{ {
if(StateBitIsSet(state_bit.DISABLE_ANIMATIONS)) { ToggleAnimations(); } if(StateBitIsSet(state_bit.DISABLE_ANIMATIONS)) { ToggleAnimations(); }
if(StateBitIsSet(state_bit.SORT_REVERSED)) { Sort(true); } if(StateBitIsSet(state_bit.SORT_REVERSED)) { Sort(true); }
InitView();
// Nav.ViewType is initialised to view_type.GRID, so we needn't do anything if the Nav.State is also on Grid
if(StateBitIsSet(state_bit.VIEW_LIST) || !GridSizeIsSupported(Nav.GridSize))
{
ToggleView();
}
} }
else else
{ {
Nav.Controls.Save.textContent = "Save Settings: ✘"; Nav.Controls.Save.textContent = "Save Settings: ✘";
// Nav.ViewType was initialised to view_type.GRID // Nav.ViewType was initialised to view_type.LIST
if(!GridSizeIsSupported(Nav.GridSize)) if(Nav.ViewType == view_type.GRID && GridSizeIsSupported(Nav.GridSize))
{ {
ToggleView(); PickGridView();
} }
} }
} }
else else
{ {
Nav.State = 0; Nav.State = 0;
SetStateBit(state_bit.VIEW_GRID); // NOTE(matt): Nav.ViewType was initialised to view_type.GRID switch(Nav.ViewType)
if(!GridSizeIsSupported(Nav.GridSize))
{ {
ToggleView(); case view_type.LIST: SetStateBit(state_bit.VIEW_LIST); break
case view_type.GRID: SetStateBit(state_bit.VIEW_GRID); break
} }
InitView();
} }
} }
@ -976,7 +991,11 @@ InitTraversalStack()
if(Projects.length === 1) if(Projects.length === 1)
{ {
// NOTE(matt): Automatically descend into the lone project // NOTE(matt): Automatically descend into the lone project
Level.Projects = Projects[0].querySelectorAll(":scope > .cineraIndexProject"); var QueriedProjects = Projects[0].querySelectorAll(":scope > .cineraIndexProject");
if(QueriedProjects.length > 0)
{
Level.Projects = QueriedProjects;
}
Level.Entries = Projects[0].querySelectorAll(":scope > .cineraIndexEntries > div"); Level.Entries = Projects[0].querySelectorAll(":scope > .cineraIndexEntries > div");
} }
else else
@ -2861,13 +2880,18 @@ InitNexus()
// NOTE(matt): We ResetButtonsContainerClone() anyway, but without cycling this classList Safari seems to do transitions // NOTE(matt): We ResetButtonsContainerClone() anyway, but without cycling this classList Safari seems to do transitions
// based on the wrong size grid // based on the wrong size grid
Nav.GridContainer.classList.add("hidden"); Nav.GridContainer.classList.add("hidden");
ResetButtonsContainerClone(); ResetButtonsContainerClone();
Nav.GridContainer.classList.remove("hidden");
switch(Nav.ViewType)
{
case view_type.LIST: { Nav.List.classList.remove("hidden"); ScrollCondition = false; } break;
case view_type.GRID: { Nav.Grid.classList.remove("hidden"); ScrollCondition = true; } break;
}
Nav.Nexus.classList.add("anim"); Nav.Nexus.classList.add("anim");
ScrollCondition = true; // NOTE(matt): Variable in cinera_pre.js, we init with the Grid which is the view we want to auto-scroll
if(CineraProps.IsMobile) if(CineraProps.IsMobile)
{ {
CineraProps.Orientation = GetRealOrientation(orientations.LANDSCAPE_LEFT, CineraProps.IsMobile); CineraProps.Orientation = GetRealOrientation(orientations.LANDSCAPE_LEFT, CineraProps.IsMobile);
@ -3412,76 +3436,89 @@ ScrollToWithOffset(Element, Offset)
} }
function function
ToggleView() PickGridView()
{ {
// NOTE(matt): While we only have two views, a toggle will suffice if(GridSizeIsSupported(Nav.GridSize))
clearTimeout(ScrollerFunction);
ScrollTicking = false;
if(Nav.ViewType == view_type.GRID)
{ {
Nav.Controls.View.textContent = "View: List"; Nav.Controls.View.textContent = "View: 𝑛-ary Grid";
Nav.ViewType = view_type.LIST; Nav.ViewType = view_type.GRID;
if(MaintainingState()) if(MaintainingState())
{ {
ClearStateBit(state_bit.VIEW_GRID); ClearStateBit(state_bit.VIEW_LIST);
SetStateBit(state_bit.VIEW_LIST); SetStateBit(state_bit.VIEW_GRID);
} }
if(!IsQuery()) if(!IsQuery())
{ {
Nav.List.classList.remove("hidden"); var TargetLevel = ComputeTargetLevelForViewport();
Nav.GridContainer.classList.add("hidden"); EmptyTraversalStack();
var LevelBundle = GetTraversalLevelBundle(); if(TargetLevel.Projects || TargetLevel.Entries)
if(LevelBundle.Generation > 1)
{ {
var Element; var ProjectsStack = BuildProjectsStack(TargetLevel);
if(LevelBundle.This.Entries !== null) DeriveTraversalStack(ProjectsStack, TargetLevel);
{
Element = GetScrollToElement(LevelBundle.This.Entries, Nav.SortChronological ? LevelBundle.This.HeadIndex : LevelBundle.This.TailIndex);
}
else if(LevelBundle.This.Projects !== null)
{
Element = GetScrollToElement(LevelBundle.This.Projects, Nav.SortChronological ? LevelBundle.This.HeadIndex : LevelBundle.This.TailIndex);
}
ScrollToWithOffset(Element, Nav.Controls.Header.offsetHeight);
} }
Nav.List.classList.add("hidden");
Nav.GridContainer.classList.remove("hidden");
UpdateButtons();
ScrollToWithOffset(Nav.Controls.GridTraversal.Header, Nav.Controls.Header.offsetHeight);
} }
ScrollCondition = true;
} }
else else
{ {
if(GridSizeIsSupported(Nav.GridSize)) // TODO(matt): Inform user that grid view is unavailable
}
}
function
PickListView()
{
Nav.Controls.View.textContent = "View: List";
Nav.ViewType = view_type.LIST;
if(MaintainingState())
{
ClearStateBit(state_bit.VIEW_GRID);
SetStateBit(state_bit.VIEW_LIST);
}
if(!IsQuery())
{
Nav.List.classList.remove("hidden");
Nav.GridContainer.classList.add("hidden");
var LevelBundle = GetTraversalLevelBundle();
if(LevelBundle.Generation > 1)
{ {
Nav.Controls.View.textContent = "View: Grid"; var Element;
Nav.ViewType = view_type.GRID; if(LevelBundle.This.Entries !== null)
if(MaintainingState())
{ {
ClearStateBit(state_bit.VIEW_LIST); Element = GetScrollToElement(LevelBundle.This.Entries, Nav.SortChronological ? LevelBundle.This.HeadIndex : LevelBundle.This.TailIndex);
SetStateBit(state_bit.VIEW_GRID);
} }
else if(LevelBundle.This.Projects !== null)
if(!IsQuery())
{ {
var TargetLevel = ComputeTargetLevelForViewport(); Element = GetScrollToElement(LevelBundle.This.Projects, Nav.SortChronological ? LevelBundle.This.HeadIndex : LevelBundle.This.TailIndex);
EmptyTraversalStack();
if(TargetLevel.Projects || TargetLevel.Entries)
{
var ProjectsStack = BuildProjectsStack(TargetLevel);
DeriveTraversalStack(ProjectsStack, TargetLevel);
}
Nav.List.classList.add("hidden");
Nav.GridContainer.classList.remove("hidden");
UpdateButtons();
ScrollToWithOffset(Nav.Controls.GridTraversal.Header, Nav.Controls.Header.offsetHeight);
} }
} ScrollToWithOffset(Element, Nav.Controls.Header.offsetHeight);
else
{
// TODO(matt): Inform user that grid view is unavailable
} }
} }
ScrollCondition = Nav.ViewType == view_type.GRID; ScrollCondition = false;
}
function
ToggleView()
{
// NOTE(matt): While we only have two views, a toggle will suffice.
clearTimeout(ScrollerFunction);
ScrollTicking = false;
if(Nav.ViewType == view_type.GRID)
{
PickListView();
}
else
{
PickGridView();
}
} }
function function
@ -3804,7 +3841,7 @@ ResizeFunction()
} }
else if(Nav.ViewType == view_type.GRID) else if(Nav.ViewType == view_type.GRID)
{ {
ToggleView(); PickListView();
// TODO(matt): Inform user that we've switched to the list view // TODO(matt): Inform user that we've switched to the list view
} }
ScrollToWithOffset(Nav.Nexus, 0); ScrollToWithOffset(Nav.Nexus, 0);