Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Framework/TimerSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ public class TimerSettings

public bool DisplayTrending { get; set; } = true;

public bool UseScrollableSplitPanelGrid { get; set; } = false;

public Decimal TrendingSplitDistance { get; set; } = 400;
public Decimal TrendingTotalDistance { get; set; } = 1600;

Expand Down
147 changes: 72 additions & 75 deletions Pages/Home.razor
Original file line number Diff line number Diff line change
Expand Up @@ -8,76 +8,71 @@
@inject TimerStateService timerState

<PageTitle>RunXC Splits</PageTitle>
<div class="minimalPadding timers_@(timers.Count)" style="@(editMode ? "display:none;":"")">
<div style="padding-top:10px; min-height: 75vh;">
<FluentGrid Spacing="1" Justify="JustifyContent.FlexStart">
@foreach (var timer in timers)
{
<FluentGridItem xs="timers.Count == 1 ? 12 : 6">
<FluentCard MinimalStyle="true" Class="take-split">
<div @ontouchstart="() => TryTakeSplit(timer)">
<h6 style="text-align: center; margin-bottom:2px">@timer.Name</h6>
<div class="flexCont" style="justify-content:space-between;">
<div style="min-width:100px; font-size:26px;">@timer.Stopwatch.Elapsed.ToString(timeFormat)</div>
</div>
<hr style="margin:4px 2px;" />
<div class="splitCont">
<div class="flexCont currentSplit">
<div class="num">@DisplayTimerNum(timer.Splits.Count + 1)</div>
<div class="column">@timer.ElapsedSinceLast.ToString(timeFormat)</div>
<div class="column"></div>
</div>
@if (settings.DisplayTrending && timer.Splits != null && timer.Splits.Any())
{
<div class="flexCont">
<div class="num"></div>
<div class="column">Trending</div>
<div class="column">@settings.GetTrending(timer.Splits.Count, timer.Splits.Last().Ellapsed, timer.Splits.Last().SplitTime).ToString(timeFormat)</div>
</div>
}
@for (var s = timer.Splits.Count; s > 0; s--)
{
var split = timer.Splits[s - 1];
<div class="flexCont">
<div class="num">@DisplayTimerNum(s)</div>
<div class="column">@split.SplitTime.ToString(timeFormat)</div>
<div class="column">@split.Ellapsed.ToString(timeFormat)</div>
</div>
}

</div>
<div class="minimalPadding home-page timers_@(timers.Count) @(settings.UseScrollableSplitPanelGrid ? "fill-page-timer-grid" : "")" style="@(editMode ? "display:none;":"")">
<div class="timer-grid" style="@TimerGridStyle">
@foreach (var timer in timers)
{
<FluentCard MinimalStyle="true" Class="take-split">
<div class="timer-card-content" @ontouchstart="() => TryTakeSplit(timer)">
<h6 style="text-align: center; margin-bottom:2px">@timer.Name</h6>
<div class="flexCont" style="justify-content:space-between;">
<div style="min-width:100px; font-size:26px;">@timer.Stopwatch.Elapsed.ToString(timeFormat)</div>
</div>
<hr style="margin:4px 2px;" />
<div class="splitCont">
<div class="flexCont currentSplit">
<div class="num">@DisplayTimerNum(timer.Splits.Count + 1)</div>
<div class="column">@timer.ElapsedSinceLast.ToString(timeFormat)</div>
<div class="column"></div>
</div>

<hr style="margin:4px; 2px;" />
<div class="flexCont ind-buttons" style="justify-content:space-between;">
<div>
@if (@timer.Stopwatch.IsRunning)
{
<FluentButton Class="access" @onclick="timer.Stopwatch.Stop" IconEnd="new Icons.Regular.Size24.Stop()"></FluentButton>
}
else
{
<FluentButton Appearance="Appearance.Accent" @onclick="timer.Stopwatch.Start" IconEnd="new Icons.Regular.Size24.PlayCircle()"></FluentButton>
}
@if (settings.DisplayTrending && timer.Splits != null && timer.Splits.Any())
{
<div class="flexCont">
<div class="num"></div>
<div class="column">Trending</div>
<div class="column">@settings.GetTrending(timer.Splits.Count, timer.Splits.Last().Ellapsed, timer.Splits.Last().SplitTime).ToString(timeFormat)</div>
</div>
<div>
}
@for (var s = timer.Splits.Count; s > 0; s--)
{
var split = timer.Splits[s - 1];
<div class="flexCont">
<div class="num">@DisplayTimerNum(s)</div>
<div class="column">@split.SplitTime.ToString(timeFormat)</div>
<div class="column">@split.Ellapsed.ToString(timeFormat)</div>
</div>
<div>
@if (@timer.Stopwatch.IsRunning)
{
<FluentButton Appearance="Appearance.Accent" @onclick="timer.TakeSplit">Lap</FluentButton>
}
else
{
<FluentButton Appearance="Appearance.Accent" @onclick="timer.Reset" IconEnd="new Icons.Regular.Size24.ArrowReset()"></FluentButton>
}
</div>
</div>
</FluentCard>
</FluentGridItem>
}
</FluentGrid>
}

</div>
</div>

<hr style="margin:4px; 2px;" />
<div class="flexCont ind-buttons" style="justify-content:space-between;">
<div>
@if (@timer.Stopwatch.IsRunning)
{
<FluentButton Class="access" @onclick="timer.Stopwatch.Stop" IconEnd="new Icons.Regular.Size24.Stop()"></FluentButton>
}
else
{
<FluentButton Appearance="Appearance.Accent" @onclick="timer.Stopwatch.Start" IconEnd="new Icons.Regular.Size24.PlayCircle()"></FluentButton>
}
</div>
<div>
</div>
<div>
@if (@timer.Stopwatch.IsRunning)
{
<FluentButton Appearance="Appearance.Accent" @onclick="timer.TakeSplit">Lap</FluentButton>
}
else
{
<FluentButton Appearance="Appearance.Accent" @onclick="timer.Reset" IconEnd="new Icons.Regular.Size24.ArrowReset()"></FluentButton>
}
</div>
</div>
</FluentCard>
}
</div>

<div class="flexCont" style="gap:9px; justify-content:space-between">
Expand All @@ -93,6 +88,9 @@
</div>
<FluentButton Style="width:50px;" Class="bottom-button" Appearance="Appearance.Accent" @onclick="switchEditMode" IconEnd="new Icons.Regular.Size24.LauncherSettings()"></FluentButton>
</div>
<div style="align-self: end; padding-right: 10px;">
Version: @version
</div>
</div>

<div style="@(editMode ? "": "display:none;")">
Expand All @@ -112,6 +110,9 @@
<div>
<FluentCheckbox Label="Interval Mode" @bind-Value=settings.IntervalMode></FluentCheckbox>
</div>
<div>
<FluentCheckbox Label="Make timer grid fill the page and scroll splits on overflow" @bind-Value=settings.UseScrollableSplitPanelGrid></FluentCheckbox>
</div>
@if (settings.DisplayTrending)
{
<div class="flexCont" style="gap:5px;">
Expand Down Expand Up @@ -145,20 +146,11 @@
</FluentCard>

</div>
<div style="float: right; padding: 10px; 5px">
Version: @version
</div>

<style>
div.minimalPadding div.fluent-card-minimal-style {
padding: 2px 5px 2px 5px;
}

div.minimalPadding div.fluent-card-minimal-style {
padding: 2px 5px 2px 5px;
}


.column {
flex: 0 0 calc(50% - 10px);
align-self: flex-start;
Expand All @@ -177,6 +169,11 @@
private TimerSettings settings => timerState.Settings;
Icon playIcon = new Icons.Regular.Size24.PlayCircle();
Icon stopIcon = new Icons.Regular.Size24.Stop();
int TimerGridColumnCount => timers.Count <= 1 ? 1 : 2;
int TimerGridRowCount => Math.Max(1, (int)Math.Ceiling(Math.Max(timers.Count, 1) / (double)TimerGridColumnCount));
string TimerGridStyle => settings.UseScrollableSplitPanelGrid
? $"grid-template-columns: repeat({TimerGridColumnCount}, minmax(0, 1fr)); grid-template-rows: repeat({TimerGridRowCount}, minmax(0, 1fr));"
: $"grid-template-columns: repeat({TimerGridColumnCount}, minmax(0, 1fr));";
string DisplayTimerNum(int timerNum)
{
if (!settings.IntervalMode)
Expand Down
53 changes: 51 additions & 2 deletions wwwroot/css/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,17 @@ div.splitCont .flexCont:nth-child(odd) {
flex-wrap: nowrap;
align-content: flex-start;
}
.home-page {
display: flex;
flex-direction: column;
gap: 10px;
}
.timer-grid {
padding-top: 10px;
min-height: 75vh;
display: grid;
gap: 0.25rem;
}
div.take-split {
border: 1px solid var(--accent-fill-rest);
}
Expand All @@ -94,6 +105,37 @@ div.splitCont {
div.splitCont > *{
padding-left: 3px;
}
.fill-page-timer-grid {
flex: 1 1 auto;
height: 100%;
min-height: 0;
overflow: hidden;
}
.fill-page-timer-grid .timer-grid {
flex: 1 1 auto;
min-height: 0;
min-width: 0;
}
.fill-page-timer-grid .take-split {
height: 100%;
width: 100%;
display: flex;
flex-direction: column;
min-height: 0;
overflow: hidden;
}
.fill-page-timer-grid .timer-card-content {
flex: 1 1 auto;
min-height: 0;
display: flex;
flex-direction: column;
}
.fill-page-timer-grid .splitCont {
flex: 1 1 auto;
min-height: 0;
overflow-y: auto;
margin: 0 -3px;
}
.bottom-button {
height: 50px;
font-size: 18px
Expand All @@ -106,7 +148,7 @@ header.header {
}

.main {
min-height: calc(100dvh - 86px);
height: calc(100dvh - 40px);
color: var(--neutral-foreground-rest);
align-items: stretch !important;
}
Expand All @@ -115,12 +157,19 @@ header.header {
align-self: stretch;
height: unset !important;
display: flex;
flex: 1 1 auto;
min-height: 0;
min-width: 0;
}

.content {
padding: 0.5rem 1.5rem;
align-self: stretch !important;
flex: 0 0 100%;
flex: 1 1 auto;
display: flex;
flex-direction: column;
min-height: 0;
min-width: 0;
}

footer {
Expand Down