117 lines
4.2 KiB
Plaintext
117 lines
4.2 KiB
Plaintext
@inherits LocalizableComponentBase
|
|||
|
|
|
||
|
|
@* How the current persona reads what others post: Mastodon's reading preferences (reading:expand:media and
|
||
|
|
reading:expand:spoilers), which Mastodon's API only reads (/api/v1/preferences). PrivaPub keeps them for each persona
|
||
|
|
and sets them through /clientapi/avatar/private/preferences, so other apps signed in as the persona read them too. The
|
||
|
|
cards here follow them as soon as they are saved (CascadingState.Preferences): which media wait behind a button, and
|
||
|
|
whether a content warning starts open. *@
|
||
|
|
<div class="flex flex-col gap-4 w-full" data-reading-preferences>
|
||
|
|
@if (IsLoading)
|
||
|
|
{
|
||
|
|
<p class="flex w-full items-center justify-center gap-2">
|
||
|
|
<DLoading Variant="DLoadingVariant.Dots" LabelText="@Localizer["loading"]" />
|
||
|
|
@Localizer["loading"]
|
||
|
|
</p>
|
||
|
|
}
|
||
|
|
else if (CascadingState.PersonaId is null)
|
||
|
|
{
|
||
|
|
<p class="w-full text-center"><i class="ion-ios-remove-circle-outline"></i> @Localizer["No persona"]</p>
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
<label class="flex flex-col gap-1 max-w-md">
|
||
|
|
<span class="text-sm">@Localizer["Pictures, videos and sounds"]</span>
|
||
|
|
<DSelect TValue="ExpandMedia" class="w-full" @bind-Value="expandMedia" data-preference-expand-media>
|
||
|
|
<option value="@ExpandMedia.Default">@Localizer["Hide those marked sensitive"]</option>
|
||
|
|
<option value="@ExpandMedia.ShowAll">@Localizer["Show all of them"]</option>
|
||
|
|
<option value="@ExpandMedia.HideAll">@Localizer["Hide all of them"]</option>
|
||
|
|
</DSelect>
|
||
|
|
</label>
|
||
|
|
<DToggle LabelText="@Localizer["Open content warnings"]" @bind-Value="expandSpoilers" data-preference-expand-spoilers />
|
||
|
|
<p class="text-xs opacity-70">@Localizer["Kept for this persona on the server: other apps signed in as it read them too."]</p>
|
||
|
|
<div class="flex flex-wrap gap-2 pointer-coarse:gap-2 justify-end">
|
||
|
|
<DButton Size="DSize.Sm" OnClick="Reset" Disabled="@(IsDefaultDisabled || isSaving || !IsChanged)" data-preferences-reset>@Localizer["Reset"]</DButton>
|
||
|
|
<DButton Size="DSize.Sm" Color="DColor.Primary" OnClick="Save" Disabled="@(IsDefaultDisabled || isSaving || !IsChanged)" data-preferences-save>
|
||
|
|
@if (isSaving)
|
||
|
|
{
|
||
|
|
<DLoading Size="DSize.Xs" LabelText="@Localizer["loading"]" />
|
||
|
|
}
|
||
|
|
<i class="ion-md-checkmark" aria-hidden="true"></i><span>@Localizer["Save"]</span>
|
||
|
|
</DButton>
|
||
|
|
</div>
|
||
|
|
}
|
||
|
|
</div>
|
||
|
|
|
||
|
|
@code {
|
||
|
|
[Inject] AuthService AuthService { get; set; }
|
||
|
|
|
||
|
|
// what PrivaPub keeps, and the choices being made
|
||
|
|
ViewPersonaPreferences saved = new();
|
||
|
|
ExpandMedia expandMedia = ExpandMedia.Default;
|
||
|
|
bool expandSpoilers;
|
||
|
|
bool isSaving;
|
||
|
|
string loadedPersonaId;
|
||
|
|
|
||
|
|
bool IsChanged => expandMedia != ExpandMediaModes.Of(saved.ExpandMedia) || expandSpoilers != saved.ExpandSpoilers;
|
||
|
|
|
||
|
|
protected override async Task OnParametersSetAsync()
|
||
|
|
{
|
||
|
|
if (CascadingState.PersonaId == loadedPersonaId)
|
||
|
|
return;
|
||
|
|
loadedPersonaId = CascadingState.PersonaId;
|
||
|
|
|
||
|
|
if (CascadingState.IsOffline)
|
||
|
|
{
|
||
|
|
saved = CascadingState.Preferences;
|
||
|
|
Reset();
|
||
|
|
WhenOnline(LoadData);
|
||
|
|
StartOnlinePolling();
|
||
|
|
IsLoading = false;
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
await LoadData();
|
||
|
|
IsLoading = false;
|
||
|
|
}
|
||
|
|
|
||
|
|
// read again: another device may have changed them since the persona was chosen here
|
||
|
|
async Task LoadData()
|
||
|
|
{
|
||
|
|
if (CascadingState.PersonaId is null)
|
||
|
|
return;
|
||
|
|
|
||
|
|
var read = await AuthService.PersonaPreferences(CascadingState.PersonaId);
|
||
|
|
saved = read ?? CascadingState.Preferences;
|
||
|
|
if (read is not null && (read.ExpandMedia != CascadingState.Preferences.ExpandMedia || read.ExpandSpoilers != CascadingState.Preferences.ExpandSpoilers))
|
||
|
|
CascadingState.PreferencesChanged(read);
|
||
|
|
Reset();
|
||
|
|
}
|
||
|
|
|
||
|
|
void Reset()
|
||
|
|
{
|
||
|
|
expandMedia = ExpandMediaModes.Of(saved.ExpandMedia);
|
||
|
|
expandSpoilers = saved.ExpandSpoilers;
|
||
|
|
}
|
||
|
|
|
||
|
|
async Task Save()
|
||
|
|
{
|
||
|
|
isSaving = true;
|
||
|
|
var result = await AuthService.SavePersonaPreferences(new PersonaPreferencesForm
|
||
|
|
{
|
||
|
|
AvatarId = CascadingState.PersonaId,
|
||
|
|
ExpandMedia = ExpandMediaModes.Name(expandMedia),
|
||
|
|
ExpandSpoilers = expandSpoilers
|
||
|
|
});
|
||
|
|
isSaving = false;
|
||
|
|
if (result.IsInvalid)
|
||
|
|
{
|
||
|
|
Toast.AddResponseError(result);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
saved = (ViewPersonaPreferences)result.Data ?? saved;
|
||
|
|
CascadingState.PreferencesChanged(saved);
|
||
|
|
Reset();
|
||
|
|
Toast.AddResponseSuccess(Localizer["Reading preferences saved."]);
|
||
|
|
}
|
||
|
|
}
|