Skip to content

Commit

Permalink
Implement editing channel subscription settings
Browse files Browse the repository at this point in the history
  • Loading branch information
vicr123 committed Feb 4, 2024
1 parent 9177012 commit 78025fa
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 28 deletions.
83 changes: 83 additions & 0 deletions Parlance.ClientApp/src/pages/Account/Notifications/Channel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import {SubscriptionChannelName} from "@/interfaces/unsubscribe";
import ListPageBlock from "@/components/ListPageBlock";
import {VerticalLayout} from "@/components/Layouts";
import PageHeading from "@/components/PageHeading";
import React, {Dispatch} from "react";
import {useTranslation} from "react-i18next";
import {notificationChannelText, NotificationChannelType} from "@/components/notifications/Events";
import SelectableList from "@/components/SelectableList";
import Fetch from "@/helpers/Fetch";
import Modal from "@/components/Modal";
import ErrorModal from "@/components/modals/ErrorModal";


export interface ChannelSubscriptionState {
channel: SubscriptionChannelName;
subscriptionData: string;
enabled: boolean;
}

interface ChannelSubscriptionsInitAction {
action: "init"
data: ChannelSubscriptionState[]
}

interface ChannelSubscriptionsSetAction {
action: "set"
channel: string
subscriptionData: string
enabled: boolean
}

export type ChannelSubscriptionsActions = ChannelSubscriptionsInitAction | ChannelSubscriptionsSetAction;

export function Channel({channel, channels, dispatchChannels}: {
channel: SubscriptionChannelName,
channels: ChannelSubscriptionState[],
dispatchChannels: Dispatch<ChannelSubscriptionsActions>
}) {
const {t} = useTranslation();

const updateChannel = async (subscriptionData: string, enabled: boolean) => {
dispatchChannels({
action: "set",
channel: channel,
subscriptionData: subscriptionData,
enabled: enabled
});

try {
await Fetch.post("/api/notifications/channels", {
channel: channel,
subscriptionData: subscriptionData,
enabled: enabled
});
} catch (e) {
Modal.mount(<ErrorModal error={e} onContinue={() => window.location.reload()} okButtonText={t("RELOAD")} />)
}
}

return <div>
<ListPageBlock>
<VerticalLayout>
<PageHeading level={3}>{t(notificationChannelText(channel, NotificationChannelType.Name))}</PageHeading>
<SelectableList items={channels.filter(x => x.channel == channel).map(x => {
return {
contents: StateContents(x),
on: x.enabled,
onClick: () => updateChannel(x.subscriptionData, !x.enabled)
}
})} />
</VerticalLayout>
</ListPageBlock>
</div>
}

function StateContents(subscription: ChannelSubscriptionState) {
const data = JSON.parse(subscription.subscriptionData);

switch (subscription.channel) {
case "TranslationFreeze":
return data.Project;
}
}
40 changes: 12 additions & 28 deletions Parlance.ClientApp/src/pages/Account/Notifications/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,41 +10,21 @@ import Spinner from "@/components/Spinner";
import {SubscriptionChannelName} from "@/interfaces/unsubscribe";
import Fetch from "@/helpers/Fetch";
import {notificationChannelText, NotificationChannelType} from "@/components/notifications/Events";

interface ChannelSubscriptionState {
channel: SubscriptionChannelName;
subscriptionData: string;
subscribed: boolean;
}

interface SubscriptionsInitAction {
action: "init"
data: ChannelSubscriptionState[]
}

interface SubscriptionsSetAction {
action: "set"
channel: string
subscriptionData: string
subscribed: boolean
}

type SubscriptionsActions = SubscriptionsInitAction | SubscriptionsSetAction;

import {Channel, ChannelSubscriptionsActions, ChannelSubscriptionState} from "@/pages/Account/Notifications/Channel";

export function NotificationsSettings() {
const [ready, setReady] = useState(false);
const {t} = useTranslation();
const navigate = useNavigate();

const [channels, dispatchChannels] = useReducer((state: ChannelSubscriptionState[], action: SubscriptionsActions) => {
const [channels, dispatchChannels] = useReducer((state: ChannelSubscriptionState[], action: ChannelSubscriptionsActions) => {
switch (action.action) {
case "init":
return action.data;
case "set":
return state.map(item => {
if (item.channel == action.channel && item.subscriptionData == action.subscriptionData) {
item.subscribed = action.subscribed;
item.enabled = action.enabled;
}
return item;
});
Expand Down Expand Up @@ -90,11 +70,15 @@ export function NotificationsSettings() {
render: <AutomaticSubscriptions />
},
t("NOTIFICATIONS_CHANNELS"),
...Object.keys(groups).map(group => ({
slug: group,
name: t(notificationChannelText(group as SubscriptionChannelName, NotificationChannelType.Name)),
render: <></>
}))
...Object.keys(groups).map(groupString => {
const group = groupString as SubscriptionChannelName;

return {
slug: group,
name: t(notificationChannelText(group, NotificationChannelType.Name)),
render: <Channel channel={group} channels={channels} dispatchChannels={dispatchChannels} />
};
})
]} />
</Container>
</div>
Expand Down
29 changes: 29 additions & 0 deletions Parlance/Controllers/NotificationsController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,26 @@ public async Task<IActionResult> GetChannels()
}).ToListAsync());
}

[HttpPost]
[Authorize]
[Route("channels")]
public async Task<IActionResult> SetChannelSubscription([FromBody] SetChannelSubscriptionRequestData data)
{
var userId = ulong.Parse(HttpContext.User.Claims.First(claim => claim.Type == Claims.UserId).Value);

try
{
var preference = await notificationService.SavedSubscriptionPreferences(userId).SingleAsync(x =>
x.Channel == data.Channel && x.GetSubscriptionData() == data.SubscriptionData);
await notificationService.UpsertSubscriptionPreference(preference, data.Enabled);
return NoContent();
}
catch (InvalidOperationException)
{
return BadRequest();
}
}

public class SetUnsubscriptionStateRequestData
{
public required bool Unsubscribed { get; set; }
Expand All @@ -104,4 +124,13 @@ public class SetAutoSubscriptionRequestData

public required bool Subscribed { get; set; }
}

public class SetChannelSubscriptionRequestData
{
public required string Channel { get; set; }

public required string SubscriptionData { get; set; }

public required bool Enabled { get; set; }
}
}

0 comments on commit 78025fa

Please sign in to comment.