20 changed files with 538 additions and 65 deletions
@ -0,0 +1,122 @@ |
|||||||
|
<div class="formContainer"> |
||||||
|
<div class="formTextContainer"> |
||||||
|
<div class="formLabel"> |
||||||
|
@Label: |
||||||
|
</div> |
||||||
|
<label class="switch"> |
||||||
|
<input readonly="@ReadOnly" |
||||||
|
type="checkbox" |
||||||
|
id="@labelId" |
||||||
|
checked="@Value" |
||||||
|
@oninput="OnChange"/> |
||||||
|
|
||||||
|
<span class="slider"></span> |
||||||
|
</label> |
||||||
|
</div> |
||||||
|
@if (Info != "") |
||||||
|
{ |
||||||
|
<div class="formInfo"> |
||||||
|
@Info |
||||||
|
</div> |
||||||
|
} |
||||||
|
</div> |
||||||
|
<style> |
||||||
|
.formContainer { |
||||||
|
display: flex; |
||||||
|
flex-direction: column; |
||||||
|
gap: 6px; |
||||||
|
width: 100%; |
||||||
|
} |
||||||
|
|
||||||
|
.formTextContainer { |
||||||
|
display: flex; |
||||||
|
flex-direction: row; |
||||||
|
gap: 8px; |
||||||
|
align-items: center; |
||||||
|
} |
||||||
|
|
||||||
|
.formLabel { |
||||||
|
font-weight: 800; |
||||||
|
} |
||||||
|
|
||||||
|
.formInfo { |
||||||
|
font-size: 0.8rem; |
||||||
|
font-style: italic; |
||||||
|
} |
||||||
|
|
||||||
|
.switch { |
||||||
|
position: relative; |
||||||
|
width: 60px; |
||||||
|
height: 34px; |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
top: 4px; |
||||||
|
} |
||||||
|
|
||||||
|
.switch input { |
||||||
|
opacity: 0; |
||||||
|
} |
||||||
|
|
||||||
|
.slider { |
||||||
|
position: absolute; |
||||||
|
cursor: pointer; |
||||||
|
top: 0; |
||||||
|
left: 0; |
||||||
|
right: 0; |
||||||
|
bottom: 0; |
||||||
|
background-color: var(--paper-border); |
||||||
|
-webkit-transition: .4s; |
||||||
|
transition: .4s; |
||||||
|
border-radius: 34px; |
||||||
|
} |
||||||
|
|
||||||
|
.slider:before { |
||||||
|
position: absolute; |
||||||
|
content: ""; |
||||||
|
height: 26px; |
||||||
|
width: 26px; |
||||||
|
left: 4px; |
||||||
|
bottom: 4px; |
||||||
|
background-color: white; |
||||||
|
-webkit-transition: .4s; |
||||||
|
transition: .4s; |
||||||
|
border-radius: 50%; |
||||||
|
} |
||||||
|
|
||||||
|
input:checked + .slider { |
||||||
|
background-color: #7838df; |
||||||
|
} |
||||||
|
|
||||||
|
input:checked + .slider:before { |
||||||
|
-webkit-transform: translateX(26px); |
||||||
|
-ms-transform: translateX(26px); |
||||||
|
transform: translateX(26px); |
||||||
|
} |
||||||
|
|
||||||
|
</style> |
||||||
|
|
||||||
|
@code { |
||||||
|
|
||||||
|
[Parameter] |
||||||
|
public string Label { get; set; } = ""; |
||||||
|
|
||||||
|
[Parameter] |
||||||
|
public string Info { get; set; } = ""; |
||||||
|
|
||||||
|
[Parameter] |
||||||
|
public EventCallback<ChangeEventArgs> OnChange { get; set; } |
||||||
|
|
||||||
|
[Parameter] |
||||||
|
public bool ReadOnly { get; set; } |
||||||
|
|
||||||
|
[Parameter] |
||||||
|
public bool Value { get; set; } |
||||||
|
|
||||||
|
private string labelId = ""; |
||||||
|
|
||||||
|
protected override void OnInitialized() |
||||||
|
{ |
||||||
|
labelId = Label.ToLower().Replace(" ", "_"); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
Binary file not shown.
@ -1,4 +1,4 @@ |
|||||||
@page "/analytics" |
@page "/data-collection" |
||||||
|
|
||||||
@layout PageLayout |
@layout PageLayout |
||||||
|
|
||||||
@ -1,20 +1,68 @@ |
|||||||
@page "/storage" |
@page "/storage" |
||||||
|
|
||||||
|
@inject IStorageService StorageService |
||||||
|
|
||||||
|
@using Services.Website |
||||||
|
@implements IDisposable |
||||||
@layout PageLayout |
@layout PageLayout |
||||||
|
|
||||||
<LayoutMediumContentComponent> |
<LayoutMediumContentComponent> |
||||||
<AlertComponent> |
|
||||||
<Title>Not Implemented</Title> |
|
||||||
<Message></Message> |
|
||||||
</AlertComponent> |
|
||||||
|
|
||||||
<PaperComponent> |
@if (!_enabledPermissions) |
||||||
TODO |
{ |
||||||
</PaperComponent> |
<AlertComponent Type="@SeverityType.Error"> |
||||||
|
<Title>Storage Disabled</Title> |
||||||
|
<Message>Enable Storage on the Permissions Page.</Message> |
||||||
|
</AlertComponent> |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
<PaperComponent> |
||||||
|
<FormLayoutComponent> |
||||||
|
<FormToggleComponent |
||||||
|
Label="Is Plain View" |
||||||
|
Value="@_isEntityPlainView" |
||||||
|
OnChange="EntityViewChanged"/> |
||||||
|
</FormLayoutComponent> |
||||||
|
</PaperComponent> |
||||||
|
} |
||||||
|
|
||||||
<ContentDividerComponent/> |
<ContentDividerComponent/> |
||||||
|
|
||||||
<PaperComponent> |
<PaperComponent> |
||||||
|
|
||||||
</PaperComponent> |
</PaperComponent> |
||||||
</LayoutMediumContentComponent> |
</LayoutMediumContentComponent> |
||||||
|
|
||||||
|
@code { |
||||||
|
bool _enabledPermissions; |
||||||
|
|
||||||
|
protected override void OnInitialized() |
||||||
|
{ |
||||||
|
_enabledPermissions = StorageService.GetValue<bool>(StorageKeys.EnabledStorage); |
||||||
|
|
||||||
|
Update(); |
||||||
|
|
||||||
|
StorageService.Subscribe(Update); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public void Dispose() |
||||||
|
{ |
||||||
|
StorageService.Unsubscribe(Update); |
||||||
|
} |
||||||
|
|
||||||
|
void Update() |
||||||
|
{ |
||||||
|
_isEntityPlainView = StorageService.GetValue<bool>(StorageKeys.IsPlainView); |
||||||
|
|
||||||
|
StateHasChanged(); |
||||||
|
} |
||||||
|
|
||||||
|
private bool _isEntityPlainView; |
||||||
|
|
||||||
|
private void EntityViewChanged(ChangeEventArgs obj) |
||||||
|
{ |
||||||
|
StorageService.SetValue(StorageKeys.IsPlainView, obj.Value); |
||||||
|
} |
||||||
|
} |
||||||
File diff suppressed because one or more lines are too long
@ -1 +1 @@ |
|||||||
[{"Id":1,"WebSectionModelId":2,"Name":"Database","Description":"Database of game information","Href":"database","IsPrivate":"False"},{"Id":2,"WebSectionModelId":1,"Name":"Build Calculator","Description":"Build order calculator for determining army timings","Href":"build-calculator","IsPrivate":"False"},{"Id":3,"WebSectionModelId":1,"Name":"Harass Calculator","Description":"Alloy harassment calculator","Href":"harass-calculator","IsPrivate":"False"},{"Id":4,"WebSectionModelId":1,"Name":"Memory Tester","Description":"Testing memory","Href":"memory-tester","IsPrivate":"False"},{"Id":5,"WebSectionModelId":1,"Name":"Comparion Charts","Description":"Ecnomy charts to compare build orders","Href":"comparison-charts","IsPrivate":"True"},{"Id":6,"WebSectionModelId":2,"Name":"Notes","Description":"General player notes","Href":"notes","IsPrivate":"False"},{"Id":7,"WebSectionModelId":2,"Name":"Key Mapping","Description":"General key mapping info","Href":"keymapping","IsPrivate":"True"},{"Id":8,"WebSectionModelId":4,"Name":"Road Map","Description":"Plans for this website","Href":"roadmap","IsPrivate":"False"},{"Id":9,"WebSectionModelId":4,"Name":"Change Log","Description":"Past updates to the website","Href":"changelog","IsPrivate":"False"},{"Id":10,"WebSectionModelId":4,"Name":"Agile","Description":"Showing agile view of this website","Href":"agile","IsPrivate":"False"},{"Id":11,"WebSectionModelId":4,"Name":"Making Of","Description":"Explaining development details of this website","Href":"makingof","IsPrivate":"False"},{"Id":12,"WebSectionModelId":2,"Name":"Documentation","Description":"Explaining how to use this website","Href":"documentation","IsPrivate":"True"},{"Id":13,"WebSectionModelId":3,"Name":"About","Description":"Answering general questions on the website","Href":"about","IsPrivate":"False"},{"Id":14,"WebSectionModelId":3,"Name":"Contact","Description":"My contact info","Href":"contact","IsPrivate":"False"},{"Id":15,"WebSectionModelId":3,"Name":"Streams","Description":"Stream info","Href":"streams","IsPrivate":"False"},{"Id":16,"WebSectionModelId":4,"Name":"Documentation","Description":"Development information","Href":"docs","IsPrivate":"False"},{"Id":17,"WebSectionModelId":5,"Name":"Permissions","Description":"Permission Settings","Href":"permissions","IsPrivate":"False"},{"Id":18,"WebSectionModelId":5,"Name":"Analytics","Description":"Analytics Settings","Href":"analytics","IsPrivate":"False"},{"Id":19,"WebSectionModelId":5,"Name":"Storage","Description":"Storage Settings","Href":"storage","IsPrivate":"False"},{"Id":20,"WebSectionModelId":1,"Name":"Economy Comparison","Description":"Compare economies","Href":"economy-comparison","IsPrivate":"False"}] |
[{"Id":1,"WebSectionModelId":2,"Name":"Database","Description":"Database of game information","Href":"database","IsPrivate":"False"},{"Id":2,"WebSectionModelId":1,"Name":"Build Calculator","Description":"Build order calculator for determining army timings","Href":"build-calculator","IsPrivate":"False"},{"Id":3,"WebSectionModelId":1,"Name":"Harass Calculator","Description":"Alloy harassment calculator","Href":"harass-calculator","IsPrivate":"False"},{"Id":4,"WebSectionModelId":1,"Name":"Memory Tester","Description":"Testing memory","Href":"memory-tester","IsPrivate":"False"},{"Id":5,"WebSectionModelId":1,"Name":"Comparion Charts","Description":"Ecnomy charts to compare build orders","Href":"comparison-charts","IsPrivate":"True"},{"Id":6,"WebSectionModelId":2,"Name":"Notes","Description":"General player notes","Href":"notes","IsPrivate":"False"},{"Id":7,"WebSectionModelId":2,"Name":"Key Mapping","Description":"General key mapping info","Href":"keymapping","IsPrivate":"True"},{"Id":8,"WebSectionModelId":4,"Name":"Road Map","Description":"Plans for this website","Href":"roadmap","IsPrivate":"False"},{"Id":9,"WebSectionModelId":4,"Name":"Change Log","Description":"Past updates to the website","Href":"changelog","IsPrivate":"False"},{"Id":10,"WebSectionModelId":4,"Name":"Agile","Description":"Showing agile view of this website","Href":"agile","IsPrivate":"False"},{"Id":11,"WebSectionModelId":4,"Name":"Making Of","Description":"Explaining development details of this website","Href":"makingof","IsPrivate":"False"},{"Id":12,"WebSectionModelId":2,"Name":"Documentation","Description":"Explaining how to use this website","Href":"documentation","IsPrivate":"True"},{"Id":13,"WebSectionModelId":3,"Name":"About","Description":"Answering general questions on the website","Href":"about","IsPrivate":"False"},{"Id":14,"WebSectionModelId":3,"Name":"Contact","Description":"My contact info","Href":"contact","IsPrivate":"False"},{"Id":15,"WebSectionModelId":3,"Name":"Streams","Description":"Stream info","Href":"streams","IsPrivate":"False"},{"Id":16,"WebSectionModelId":4,"Name":"Documentation","Description":"Development information","Href":"docs","IsPrivate":"False"},{"Id":17,"WebSectionModelId":5,"Name":"Permissions","Description":"Permission Settings","Href":"permissions","IsPrivate":"False"},{"Id":18,"WebSectionModelId":5,"Name":"Data Collection","Description":"Data Collection Settings","Href":"data-collection","IsPrivate":"False"},{"Id":19,"WebSectionModelId":5,"Name":"Storage","Description":"Storage Settings","Href":"storage","IsPrivate":"False"},{"Id":20,"WebSectionModelId":1,"Name":"Economy Comparison","Description":"Compare economies","Href":"economy-comparison","IsPrivate":"False"}] |
||||||
@ -0,0 +1,64 @@ |
|||||||
|
using Blazored.LocalStorage; |
||||||
|
using Microsoft.JSInterop; |
||||||
|
|
||||||
|
namespace Services.Website; |
||||||
|
|
||||||
|
public class PermissionService : IPermissionService |
||||||
|
{ |
||||||
|
private bool isLoaded; |
||||||
|
|
||||||
|
|
||||||
|
private IJSRuntime _jsRuntime; |
||||||
|
private bool isStorageEnabled = false; |
||||||
|
private IToastService _toastService; |
||||||
|
private IStorageService _storageService; |
||||||
|
|
||||||
|
public PermissionService(IJSRuntime jsRuntime, IToastService toastService, IStorageService storageService) |
||||||
|
{ |
||||||
|
_jsRuntime = jsRuntime; |
||||||
|
_toastService = toastService; |
||||||
|
_storageService = storageService; |
||||||
|
} |
||||||
|
|
||||||
|
public void Subscribe(Action action) |
||||||
|
{ |
||||||
|
OnChange += action; |
||||||
|
} |
||||||
|
|
||||||
|
public void Unsubscribe(Action action) |
||||||
|
{ |
||||||
|
OnChange += action; |
||||||
|
} |
||||||
|
|
||||||
|
public bool GetIsStorageEnabled() |
||||||
|
{ |
||||||
|
return _storageService.GetValue<bool>(StorageKeys.EnabledStorage); |
||||||
|
} |
||||||
|
|
||||||
|
public bool GetIsDataCollectionEnabled() |
||||||
|
{ |
||||||
|
return _storageService.GetValue<bool>(StorageKeys.EnabledDataCollection); |
||||||
|
} |
||||||
|
|
||||||
|
public void SetIsStorageEnabled(bool isEnabled) |
||||||
|
{ |
||||||
|
_storageService.SetValue(StorageKeys.EnabledStorage, isEnabled); |
||||||
|
} |
||||||
|
|
||||||
|
public void SetIsDataCollectionEnabled(bool isEnabled) |
||||||
|
{ |
||||||
|
_storageService.SetValue(StorageKeys.EnabledDataCollection, isEnabled); |
||||||
|
} |
||||||
|
|
||||||
|
public Task Load() |
||||||
|
{ |
||||||
|
throw new NotImplementedException(); |
||||||
|
} |
||||||
|
|
||||||
|
private event Action OnChange = null!; |
||||||
|
|
||||||
|
private void NotifyDataChanged() |
||||||
|
{ |
||||||
|
OnChange(); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,106 @@ |
|||||||
|
using Blazored.LocalStorage; |
||||||
|
using Microsoft.JSInterop; |
||||||
|
using Model.Feedback; |
||||||
|
|
||||||
|
namespace Services.Website; |
||||||
|
|
||||||
|
public class StorageKeys |
||||||
|
{ |
||||||
|
public static string EnabledStorage = "StorageEnabled"; |
||||||
|
public static string EnabledDataCollection = "StorageDataCollection"; |
||||||
|
public static string IsPlainView { get; set; } = "IsPlainView"; |
||||||
|
} |
||||||
|
|
||||||
|
public class StorageService : IStorageService |
||||||
|
{ |
||||||
|
private readonly ISyncLocalStorageService _localStorageService; |
||||||
|
private IJSRuntime _jsRuntime; |
||||||
|
private readonly IToastService _toastService; |
||||||
|
private bool isLoaded; |
||||||
|
private bool isStorageEnabled; |
||||||
|
|
||||||
|
|
||||||
|
public StorageService(IJSRuntime jsRuntime, IToastService toastService, |
||||||
|
ISyncLocalStorageService localStorageService) |
||||||
|
{ |
||||||
|
_jsRuntime = jsRuntime; |
||||||
|
_toastService = toastService; |
||||||
|
_localStorageService = localStorageService; |
||||||
|
} |
||||||
|
|
||||||
|
private string enabledKey => StorageKeys.EnabledStorage; |
||||||
|
|
||||||
|
public void Subscribe(Action action) |
||||||
|
{ |
||||||
|
OnChange += action; |
||||||
|
} |
||||||
|
|
||||||
|
public void Unsubscribe(Action action) |
||||||
|
{ |
||||||
|
OnChange += action; |
||||||
|
} |
||||||
|
|
||||||
|
public T GetValue<T>(string forKey) |
||||||
|
{ |
||||||
|
return _localStorageService.GetItem<T>(forKey); |
||||||
|
} |
||||||
|
|
||||||
|
public void SetValue<T>(string key, T value) |
||||||
|
{ |
||||||
|
if (key.Equals(StorageKeys.EnabledStorage) && value.Equals(true)) |
||||||
|
{ |
||||||
|
_localStorageService.SetItem(key, value); |
||||||
|
NotifyDataChanged(); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
if (key.Equals(StorageKeys.EnabledStorage)) |
||||||
|
{ |
||||||
|
_localStorageService.Clear(); |
||||||
|
NotifyDataChanged(); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
var isEnabled = GetValue<bool>(StorageKeys.EnabledStorage); |
||||||
|
if (!isEnabled) |
||||||
|
{ |
||||||
|
_toastService.AddToast(new ToastModel |
||||||
|
{ |
||||||
|
Title = "Permission Error", |
||||||
|
SeverityType = SeverityType.Error, |
||||||
|
Message = "Storage must be enabled before Storage can be used." |
||||||
|
}); |
||||||
|
NotifyDataChanged(); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
_localStorageService.SetItem(key, value); |
||||||
|
NotifyDataChanged(); |
||||||
|
} |
||||||
|
|
||||||
|
public async Task Load() |
||||||
|
{ |
||||||
|
if (!isLoaded) return; |
||||||
|
|
||||||
|
|
||||||
|
isLoaded = true; |
||||||
|
|
||||||
|
isStorageEnabled = GetValue<bool>(enabledKey); |
||||||
|
|
||||||
|
NotifyDataChanged(); |
||||||
|
} |
||||||
|
|
||||||
|
private event Action OnChange = null!; |
||||||
|
|
||||||
|
private void NotifyDataChanged() |
||||||
|
{ |
||||||
|
try |
||||||
|
{ |
||||||
|
|
||||||
|
OnChange(); |
||||||
|
} |
||||||
|
catch (Exception e) |
||||||
|
{ |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
Loading…
Reference in new issue