Skip to content

Commit

Permalink
Gate expiry support on the front end (#6599)
Browse files Browse the repository at this point in the history
  • Loading branch information
julianjelfs authored Oct 18, 2024
1 parent 86e4b8e commit 870086b
Show file tree
Hide file tree
Showing 94 changed files with 1,253 additions and 448 deletions.
2 changes: 1 addition & 1 deletion frontend/app/src/components/Hoverable.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@
<style lang="scss">
.noselect {
@include no_user_select();
display: inline-block;
display: inline-flex;
&.fill {
width: 100%;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@
$: currentChatMembers = client.currentChatMembers;
$: currentChatInvited = client.currentChatInvitedUsers;
$: currentChatBlocked = client.currentChatBlockedUsers;
$: currentChatLapsed = client.currentChatLapsedMembers;
$: currentCommunityMembers = client.currentCommunityMembers;
$: currentCommunityInvited = client.currentCommunityInvitedUsers;
$: currentCommunityBlocked = client.currentCommunityBlockedUsers;
$: currentCommunityLapsed = client.currentCommunityLapsedMembers;
$: canInvite =
selectedTab === "community"
? client.canInviteUsers(community.id)
Expand Down Expand Up @@ -103,6 +105,7 @@
invited={$currentCommunityInvited}
members={[...$currentCommunityMembers.values()]}
blocked={$currentCommunityBlocked}
lapsed={$currentCommunityLapsed}
on:close
on:blockUser={onBlockCommunityUser}
on:unblockUser={onUnblockCommunityUser}
Expand All @@ -120,6 +123,7 @@
invited={$currentChatInvited}
members={$currentChatMembers}
blocked={$currentChatBlocked}
lapsed={$currentChatLapsed}
on:close
on:blockUser={onBlockGroupUser}
on:unblockUser={onUnblockGroupUser}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
banner={community.banner}
avatar={community.avatar}
memberCount={community.memberCount}
gate={community.gate}
gateConfig={community.gateConfig}
language={community.primaryLanguage}
flags={0}
channelCount={0}
Expand Down
2 changes: 1 addition & 1 deletion frontend/app/src/components/home/ChatList.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@
beforeUpdate(() => {
if (previousScope === $chatListScope && view !== "chats" && previousView === "chats") {
chatsScrollTop = chatListElement.scrollTop;
chatsScrollTop = chatListElement?.scrollTop;
}
});
Expand Down
4 changes: 3 additions & 1 deletion frontend/app/src/components/home/CurrentChat.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
$: communities = client.communities;
$: canSendAny = client.canSendMessage(chat.id, "message");
$: preview = client.isPreviewing(chat.id);
$: lapsed = client.isLapsed(chat.id);
$: canPin = client.canPinMessages(chat.id);
$: canBlockUsers = client.canBlockUsers(chat.id);
$: canDelete = client.canDeleteOtherUsersMessages(chat.id);
Expand Down Expand Up @@ -130,7 +131,7 @@
}
function getUnreadMessageCount(chat: ChatSummary): number {
if (client.isPreviewing(chat.id)) return 0;
if (client.isPreviewing(chat.id) || client.isLapsed(chat.id)) return 0;
return messagesRead.unreadMessageCount(chat.id, chat.latestMessage?.event.messageIndex);
}
Expand Down Expand Up @@ -410,6 +411,7 @@
mode={"message"}
{joining}
{preview}
{lapsed}
{blocked}
externalContent={externalUrl !== undefined}
on:joinGroup
Expand Down
4 changes: 2 additions & 2 deletions frontend/app/src/components/home/CurrentChatMessages.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,8 @@
$: privateCommunityPreview =
$selectedCommunity !== undefined &&
$selectedCommunity.membership.role === "none" &&
(!$selectedCommunity.public || $selectedCommunity.gate.kind !== "no_gate");
($selectedCommunity.membership.role === "none" || $selectedCommunity.membership.lapsed) &&
(!$selectedCommunity.public || $selectedCommunity.gateConfig.gate.kind !== "no_gate");
$: privatePreview = privateCommunityPreview || privateChatPreview;
$: isEmptyChat = chat.latestEventIndex <= 0 || privatePreview;
Expand Down
47 changes: 35 additions & 12 deletions frontend/app/src/components/home/DurationPicker.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,48 @@
import Select from "../Select.svelte";
import { _ } from "svelte-i18n";
import type { OpenChat } from "openchat-client";
import { msToDays, msToHours, msToMinutes, msToMonths, msToWeeks } from "../../utils/time";
const ONE_MINUTE = 1000 * 60;
const ONE_HOUR = ONE_MINUTE * 60;
const ONE_DAY = ONE_HOUR * 24;
const ONE_WEEK = ONE_DAY * 7;
const ONE_MONTH = ONE_WEEK * 4;
const client = getContext<OpenChat>("client");
type DurationUnit = "minutes" | "hours" | "days" | "weeks" | "months";
export let valid = true;
export let milliseconds: bigint = BigInt(ONE_HOUR);
export let disabled = false;
export let unitFilter = (_: DurationUnit) => true;
let initialised = false;
let amount: string;
let unit: "minutes" | "hours" | "days";
let unit: DurationUnit;
$: allUnits = ["minutes", "hours", "days", "weeks", "months"] as DurationUnit[];
$: supportedDurations = allUnits.filter(unitFilter);
onMount(() => {
const { days, hours, minutes } = client.durationFromMilliseconds(Number(milliseconds));
if (days > 0) {
amount = days.toString();
unit = "days";
const duration = client.durationFromMilliseconds(Number(milliseconds));
const { days, hours, minutes, weeks, months, total } = duration;
if (minutes > 0) {
amount = msToMinutes(total).toString();
unit = "minutes";
} else if (hours > 0) {
amount = hours.toString();
amount = msToHours(total).toString();
unit = "hours";
} else if (minutes > 0) {
amount = minutes.toString();
unit = "minutes";
} else if (days > 0) {
amount = msToDays(total).toString();
unit = "days";
} else if (weeks > 0) {
amount = msToWeeks(total).toString();
unit = "weeks";
} else if (months > 0) {
amount = msToMonths(total).toString();
unit = "months";
}
initialised = true;
});
Expand All @@ -42,6 +59,12 @@
}
valid = true;
switch (unit) {
case "months":
milliseconds = BigInt(ONE_MONTH * ttlNum);
break;
case "weeks":
milliseconds = BigInt(ONE_WEEK * ttlNum);
break;
case "minutes":
milliseconds = BigInt(ONE_MINUTE * ttlNum);
break;
Expand All @@ -66,9 +89,9 @@

<div class="units">
<Select {disabled} margin={false} on:change={() => updateAmount(amount)} bind:value={unit}>
<option value={"minutes"}>{$_("minutes")}</option>
<option value={"hours"}>{$_("hours")}</option>
<option value={"days"}>{$_("days")}</option>
{#each supportedDurations as duration}
<option value={duration}>{$_(duration)}</option>
{/each}
</Select>
</div>
</div>
Expand Down
2 changes: 2 additions & 0 deletions frontend/app/src/components/home/Footer.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
export let blocked: boolean;
export let preview: boolean;
export let lapsed: boolean;
export let joining: MultiUserChat | undefined;
export let chat: ChatSummary;
export let attachment: AttachmentContent | undefined;
Expand Down Expand Up @@ -140,6 +141,7 @@
{externalContent}
{mode}
{preview}
{lapsed}
{blocked}
{joining}
{attachment}
Expand Down
16 changes: 8 additions & 8 deletions frontend/app/src/components/home/Home.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
UpdatedRules,
ResourceKey,
NervousSystemDetails,
AccessGateWithLevel,
EnhancedAccessGate,
GateCheckSucceeded,
} from "openchat-client";
import {
Expand Down Expand Up @@ -156,7 +156,7 @@
| { kind: "no_access" }
| { kind: "new_group"; embeddedContent: boolean; candidate: CandidateGroupChat }
| { kind: "wallet" }
| { kind: "gate_check_failed"; gates: AccessGateWithLevel[] }
| { kind: "gate_check_failed"; gates: EnhancedAccessGate[] }
| { kind: "hall_of_fame" }
| { kind: "edit_community"; community: CommunitySummary; communityRules: Rules }
| { kind: "make_proposal"; chat: MultiUserChat; nervousSystem: NervousSystemDetails }
Expand All @@ -169,7 +169,7 @@
kind: "evaluating_access_gates";
group: MultiUserChat;
select: boolean;
gates: AccessGateWithLevel[];
gates: EnhancedAccessGate[];
level: Level;
};
Expand Down Expand Up @@ -841,7 +841,7 @@
// that we are actually already a member of this group, so we should double check here
// that we actually *need* to join the group
let chat = $chatSummariesStore.get(group.id);
if (chat === undefined || chat.membership.role === "none") {
if (chat === undefined || chat.membership.role === "none" || client.isLapsed(chat.id)) {
doJoinGroup(group, select, undefined);
}
}
Expand Down Expand Up @@ -869,6 +869,7 @@
): Promise<void> {
joining = group;
const credentials = gateCheck?.credentials ?? [];
const paymentApprovals = gateCheck?.paymentApprovals ?? new Map();
if (gateCheck === undefined) {
const gates = client.accessGatesForChat(group, true);
Expand All @@ -893,7 +894,7 @@
}
return client
.joinGroup(group, credentials)
.joinGroup(group, credentials, paymentApprovals)
.then((resp) => {
if (resp.kind === "blocked") {
toastStore.showFailureToast(i18nKey("youreBlocked"));
Expand Down Expand Up @@ -1027,7 +1028,7 @@
threadPermissions: undefined,
},
rules: { ...defaultChatRules(level), newVersion: false },
gate: { kind: "no_gate" },
gateConfig: { gate: { kind: "no_gate" }, expiry: undefined },
level,
membership: {
...nullMembership(),
Expand Down Expand Up @@ -1060,7 +1061,7 @@
blobUrl: chat.blobUrl,
blobData: chat.blobData,
},
gate: chat.gate,
gateConfig: chat.gateConfig,
level,
membership: chat.membership,
eventsTTL: chat.eventsTTL,
Expand Down Expand Up @@ -1292,7 +1293,6 @@
<GateCheckFailed on:close={closeModal} gates={modal.gates} />
{:else if modal.kind === "evaluating_access_gates"}
<AccessGateEvaluator
level={modal.level}
gates={modal.gates}
on:close={closeModal}
on:success={accessGatesEvaluated} />
Expand Down
5 changes: 3 additions & 2 deletions frontend/app/src/components/home/MessageEntry.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
export let chat: ChatSummary;
export let blocked: boolean;
export let preview: boolean;
export let lapsed: boolean;
export let messageAction: MessageAction = undefined;
export let joining: MultiUserChat | undefined;
export let attachment: AttachmentContent | undefined;
Expand Down Expand Up @@ -558,8 +559,8 @@
<div class="blocked">
{$_("userIsBlocked")}
</div>
{:else if preview && chat.kind !== "direct_chat"}
<PreviewFooter {joining} {chat} on:joinGroup on:upgrade />
{:else if (preview || lapsed) && chat.kind !== "direct_chat"}
<PreviewFooter {lapsed} {joining} {chat} on:joinGroup on:upgrade />
{:else if externalContent}
<div class="disclaimer">
<Alert size={$iconSize} color={"var(--warn"} />
Expand Down
7 changes: 4 additions & 3 deletions frontend/app/src/components/home/NoChatSelected.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@
$: chatListScope = client.chatListScope;
$: selectedCommunity = client.selectedCommunity;
$: previewingCommunity = $selectedCommunity?.membership.role === "none";
$: locked = isLocked($selectedCommunity?.gate);
$: previewingCommunity =
$selectedCommunity?.membership.role === "none" || $selectedCommunity?.membership.lapsed;
$: locked = isLocked($selectedCommunity?.gateConfig?.gate);
$: [title, message] = getMessageForScope($chatListScope.kind);
Expand Down Expand Up @@ -54,7 +55,7 @@
language={$selectedCommunity.primaryLanguage}
flags={0}
header
gate={$selectedCommunity.gate}
gateConfig={$selectedCommunity.gateConfig}
avatar={$selectedCommunity.avatar} />
<div class="join">
<Button
Expand Down
25 changes: 20 additions & 5 deletions frontend/app/src/components/home/PreviewFooter.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@
export let chat: MultiUserChat;
export let joining: MultiUserChat | undefined;
export let lapsed: boolean;
$: platformModerator = client.platformModerator;
$: isFrozen = client.isFrozen(chat.id);
$: selectedCommunity = client.selectedCommunity;
$: previewingCommunity = $selectedCommunity?.membership.role === "none";
$: previewingCommunity =
$selectedCommunity?.membership.role === "none" || $selectedCommunity?.membership.lapsed;
$: gates = client.accessGatesForChat(chat);
$: locked = gates.some((g) => isLocked(g));
Expand Down Expand Up @@ -70,6 +72,11 @@
<div class="gate">
<AccessGateIconsForChat {gates} />
</div>
{#if lapsed}
<div class="lapsed">
<Translatable resourceKey={i18nKey("access.lapsed.label")} />
</div>
{/if}
{#if $platformModerator}
{#if isFrozen}
<Button loading={freezingInProgress} secondary small on:click={unfreezeGroup}>
Expand All @@ -81,9 +88,11 @@
</Button>
{/if}
{/if}
<Button secondary small on:click={cancelPreview}>
<Translatable resourceKey={i18nKey("leave")} />
</Button>
{#if !lapsed}
<Button secondary small on:click={cancelPreview}>
<Translatable resourceKey={i18nKey("leave")} />
</Button>
{/if}
<Button
loading={joining !== undefined}
disabled={locked || joining !== undefined}
Expand All @@ -92,7 +101,9 @@
<Translatable
resourceKey={locked
? i18nKey("access.lockedGate", undefined, chat.level, true)
: i18nKey("joinGroup", undefined, chat.level, true)} />
: lapsed
? i18nKey("access.lapsed.rejoin", undefined, chat.level, true)
: i18nKey("joinGroup", undefined, chat.level, true)} />
</Button>
</div>

Expand All @@ -114,4 +125,8 @@
left: 0;
}
}
.lapsed {
@include font(bold, normal, fs-100);
}
</style>
4 changes: 2 additions & 2 deletions frontend/app/src/components/home/RecommendedGroup.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
$: chatListScope = client.chatListScope;
$: chatSummariesStore = client.chatSummariesStore;
$: member = $chatSummariesStore.has(group.id);
$: locked = isLocked(group.gate);
$: locked = isLocked(group.gateConfig.gate);
function dismiss({ id }: GroupChatSummary) {
dispatch("dismissRecommendation", id);
Expand Down Expand Up @@ -84,7 +84,7 @@
</div>
<Footer align="end">
<div class="gate">
<AccessGateIcon clickable level={group.level} gate={group.gate} />
<AccessGateIcon clickable level={group.level} gateConfig={group.gateConfig} />
</div>
{#if member}
<Button tiny on:click={() => leaveGroup(group)}
Expand Down
Loading

0 comments on commit 870086b

Please sign in to comment.