This commit is contained in:
janisslsm committed 2026-11-01 12:12:55 +02:00
1 parent 1781d25a15
commit 732c0ad767
33051 files changed
+2591613 -3019689

No files matched your search

@@ -0,0 +1,18 @@
// Metro module 9556 (f9557).
import { createApexExperiment } from "../experiments/apex/index";
const apexExperiment = createApexExperiment({
name: "2026-03-message-bookmarks",
kind: "user",
defaultConfig: {
enabled: false
},
variations: {
1: {
enabled: true
},
2: {
enabled: true
}
}
});
export default apexExperiment;
@@ -0,0 +1,130 @@
// Metro module 9933 (f9934).
import SavedMessagesStore from "./SavedMessagesStore";
import { AbortCodes } from "../../Constants";
import { SAVED_MESSAGES_MAX } from "../../_bundle/Module9934";
import hasForLaterPremiumType from "./hasForLaterPremiumType";
import openPremiumUpsellActionSheet from "../premium/roadblocks/native/utils/openPremiumUpsellActionSheet";
import { EntitlementFeatureNames } from "../../_bundle/Module6201";
import { upsertSavedMessage, deleteSavedMessage } from "./SavedMessagesActions";
import AlertActionCreators from "../../actions/AlertActionCreators";
import { intl, t } from "../../intl/index.native";
import { showForLaterModal } from "./native/showForLaterModal";
import { SavedMessageSortTypes } from "./SavedMessagesTypes";
import ToastActionCreators from "../toast/native/ToastActionCreators";
import { CircleErrorIcon } from "../../design/components/Icon/native/redesign/generated/CircleErrorIcon";
import { ClockIcon } from "../../design/components/Icon/native/redesign/generated/ClockIcon";
import { BookmarkIcon } from "../../design/components/Icon/native/redesign/generated/BookmarkIcon";
function $mk115571($env) {
return (a0) => {
const r4 = a0 == null ? void 0 : a0.body?.code;
if (r4 === AbortCodes.TOO_MANY_SAVED_MESSAGES) {
const r35 = $env;
AlertActionCreators.show({
title: intl.string(t.mlbiZW),
body: intl.formatToPlainString(t["1zVbEG"], {
max: SAVED_MESSAGES_MAX
}),
confirmText: intl.string(t.BddRzS),
cancelText: intl.string(t.ZGbTcy),
onCancel: $mk118143(r35)
});
} else {
let content = a0 == null ? void 0 : a0.body?.message;
if (content == null) {
content = intl.string(t.R0RpRX);
}
ToastActionCreators.open({
key: "SAVED_MESSAGE_CREATE_ERROR",
IconComponent: CircleErrorIcon,
content
});
}
return null;
};
}
function $mk115572($env) {
return (a0) => {
let content = a0 == null ? void 0 : a0.body?.message;
if (content == null) {
content = intl.string(t.R0RpRX);
}
ToastActionCreators.open({
key: "SAVED_MESSAGE_REMOVE_ERROR",
IconComponent: CircleErrorIcon,
content
});
return null;
};
}
function $mk118143($env) {
return () => showForLaterModal($env[1].dueAt != null ? SavedMessageSortTypes.REMINDER : SavedMessageSortTypes.BOOKMARK);
}
let env6599 = {};
export async function addOrUpdateSavedMessage(c26564_0) {
let c26564_1, c26564_2;
L13: {
let env30158;
const r29 = env6599;
c26564_2 = r29;
const r10 = env30158 = {
$parent: r29
};
c26564_1 = r10;
env30158[0] = void 0;
env30158[1] = void 0;
env30158[0] = c26564_0.displayToast;
const { displayToast, ...rest } = c26564_0;
env30158[1] = rest;
env30158[2] = void 0;
env30158[3] = void 0;
await void 0;
if (SavedMessagesStore.getSavedMessage(env30158[1].channelId, env30158[1].messageId) == null) {
if (!hasForLaterPremiumType()) {
openPremiumUpsellActionSheet(EntitlementFeatureNames.SAVED_MESSAGES);
break L13;
}
}
const r55 = c26564_1;
if (await upsertSavedMessage(env30158[1]).catch($mk115571(r55)) != null) {
if (env30158[0]) {
env30158[2] = env30158[1].dueAt != null ? intl.string(t.i1IsOy) : intl.string(t.DQjes4);
env30158[3] = env30158[1].dueAt != null ? ClockIcon : BookmarkIcon;
ToastActionCreators.open({
key: "SAVED_MESSAGE_CREATE_SUCCESS",
IconComponent: env30158[3],
content: env30158[2]
});
}
}
}
}
export async function removeSavedMessage(c26565_0) {
let env30159;
const r29 = env6599;
let c26565_2 = r29;
const r10 = env30159 = {
$parent: r29
};
let c26565_1 = r10;
env30159[0] = void 0;
env30159[1] = void 0;
env30159[2] = void 0;
env30159[0] = c26565_0.displayToast;
env30159[1] = c26565_0.isReminder;
const { displayToast, isReminder, ...rest } = c26565_0;
env30159[2] = rest;
env30159[3] = void 0;
env30159[4] = void 0;
await void 0;
if (await deleteSavedMessage(env30159[2]).catch($mk115572(env6599)) != null) {
if (env30159[0]) {
env30159[3] = env30159[2].dueAt == null && !env30159[1] ? intl.string(t["5KOMiV"]) : intl.string(t.D0tS02);
env30159[4] = env30159[2].dueAt == null && !env30159[1] ? BookmarkIcon : ClockIcon;
ToastActionCreators.open({
key: "SAVED_MESSAGE_REMOVE_SUCCESS",
IconComponent: env30159[4],
content: env30159[3]
});
}
}
}
@@ -0,0 +1,124 @@
// Metro module 9942 (f9943).
import { useMemo } from "react";
import { UnknownChannelRecord } from "../../records/ChannelRecord";
import ChannelStore from "../../stores/ChannelStore";
import { ChannelTypes, Routes } from "../../Constants";
import { t, intl } from "../../intl/index.native";
import Module3771 from "../../_bundle/Module3771";
import { useStateFromStores } from "../../_bundle/Module589";
import ChannelActionCreators from "../../actions/ChannelActionCreators";
import safeTransitionTo_native from "../links/safeTransitionTo.native";
let c6607_9 = {
LONG: 0,
0: "LONG",
SHORT: 1,
1: "SHORT"
};
export { c6607_9 as DueInStringTypes };
export function useDueInString({ dueAt, now, type }) {
if (dueAt == null) {
return {
string: "",
isOverdue: false
};
}
let r6 = type === c6607_9.LONG ? t.TjNWNF : t.H4gnX9;
const r29 = type === c6607_9.LONG ? t.haia16 : t["Uq7Y+7"];
const isOverdue = now > dueAt;
if (isOverdue) {
r6 = r29;
}
return {
dueInText: intl.formatToPlainString(r6, {
duration: Module3771.duration(dueAt.getTime() - now.getTime(), "millisecond").humanize()
}),
isOverdue
};
}
export function useSavedMessageChannel(a0) {
const stateFromStores = useStateFromStores([ChannelStore], () => ChannelStore.getChannel(a0.saveData.channelId));
return useMemo(() => {
let r2 = stateFromStores;
if (stateFromStores == null) {
r2 = a0.message != null ? new UnknownChannelRecord({
id: a0.saveData.channelId,
guild_id: a0.saveData.guildId,
type: ChannelTypes.UNKNOWN,
name: intl.string(t.J90oLW)
}) : void 0;
}
return r2;
}, [stateFromStores, a0]);
}
export async function savedMessageJumpToMessage(c26572_0, c26572_1) {
let c26572_2, c26572_3, c26572_4;
let c26572_5 = 0;
const r10 = void 0;
L28: {
L23: {
L25: {
L24: {
try {
let env30163;
c26572_3 = r10;
const r16 = env30163 = {};
c26572_2 = r16;
env30163[0] = c26572_0;
env30163[1] = c26572_1;
env30163[2] = void 0;
if (c26572_1?.type === ChannelTypes.UNKNOWN && c26572_0.saveData.guildId == null) {
c26572_5 = 1;
env30163[2] = await ChannelActionCreators.fetchChannel(c26572_0.saveData.channelId);
if (env30163[2].recipients == null) {
c26572_5 = 0;
break L25;
}
if (env30163[2].recipients.length > 1) {
c26572_5 = 0;
break L24;
}
await ChannelActionCreators.ensurePrivateChannel(env30163[2].recipients.map((recipient) => recipient.id));
c26572_5 = 0;
const r117 = env30163[1];
safeTransitionTo_native(Routes.CHANNEL(r117 == null ? void 0 : r117.getGuildId(), env30163[0].saveData.channelId, env30163[0].saveData.messageId), {
openChannel: true
});
break L23;
}
const r42 = env30163[1];
safeTransitionTo_native(Routes.CHANNEL(r42 == null ? void 0 : r42.getGuildId(), env30163[0].saveData.channelId, env30163[0].saveData.messageId), {
openChannel: true
});
break L28;
} catch ($e) {
const r31 = $e;
let r8 = r31;
c26572_4 = r31;
if (c26572_5 !== 0) {
while (true) {
try {
c26572_5 = 0;
const r158 = env30163[1];
safeTransitionTo_native(Routes.CHANNEL(r158 == null ? void 0 : r158.getGuildId(), env30163[0].saveData.channelId, env30163[0].saveData.messageId), {
openChannel: true
});
break L23;
} catch (r147) {
r8 = r147;
c26572_4 = r147;
if (c26572_5 === 0) {
break;
}
}
}
}
throw r8;
}
}
return void 0;
}
return void 0;
}
return void 0;
}
}
@@ -0,0 +1,85 @@
// Metro module 9935 (f9936).
import SavedMessagesStore from "./SavedMessagesStore";
import { Endpoints } from "../../Constants";
import Dispatcher from "../../Dispatcher";
import { HTTP, rejectWithMigratedError } from "../../_bundle/sendRequest";
import { savedMessageDataToClient, savedMessageCreateObjectToClient } from "./SavedMessagesTypes";
import { createMessageRecord } from "../messages/MessageRecordUtils";
function $mk115573($env) {
return (a0) => ({
message: a0.message != null ? createMessageRecord(a0.message) : null,
saveData: savedMessageDataToClient(a0.save_data)
});
}
let env6600 = {};
export function dismissBookmarkNudge() {
Dispatcher.dispatch({
type: "BOOKMARK_NUDGE_DISMISS"
});
}
export async function upsertSavedMessage(c26566_0) {
let r71;
let c30160_0;
L12: {
c30160_0 = void 0;
c30160_0 = await HTTP.put({
url: Endpoints.PUT_SAVED_MESSAGE(c26566_0.channelId, c26566_0.messageId),
body: {
due_at: c26566_0.dueAt
},
rejectWithError: rejectWithMigratedError()
});
if (c30160_0.ok) {
r71 = savedMessageCreateObjectToClient(c30160_0.body);
break L12;
}
return void 0;
}
return r71;
}
export async function deleteSavedMessage(c26567_0) {
L9: {
if ((await HTTP.del({
url: Endpoints.DELETE_SAVED_MESSAGE(c26567_0.channelId, c26567_0.messageId),
rejectWithError: rejectWithMigratedError()
})).ok) {
break L9;
}
return void 0;
}
return true;
}
export async function fetchAndUpdateSavedMessages() {
let c26568_0, c26568_1;
L15: {
let env30161;
const r12 = env6600;
c26568_1 = r12;
const r25 = env30161 = {
$parent: r12
};
c26568_0 = r25;
env30161[0] = void 0;
env30161[1] = void 0;
if (SavedMessagesStore.getIsStale()) {
env30161[0] = await HTTP.get({
url: Endpoints.GET_SAVED_MESSAGES,
rejectWithError: rejectWithMigratedError()
});
if (env30161[0].ok) {
env30161[1] = env30161[0].body.results.map($mk115573(env6600));
Dispatcher.dispatch({
type: "SAVED_MESSAGES_UPDATE",
savedMessages: env30161[1]
});
break L15;
}
Dispatcher.dispatch({
type: "SAVED_MESSAGES_UPDATE",
savedMessages: []
});
break L15;
}
return Promise.resolve();
}
}
@@ -0,0 +1,18 @@
// Metro module 16311 (f16312).
import ForLaterExperiment from "./ForLaterExperiment";
import { fetchAndUpdateSavedMessages } from "./SavedMessagesActions";
import AutomaticLifecycleManager from "../../lib/AutomaticLifecycleManager";
class SavedMessagesManager extends AutomaticLifecycleManager {
actions = {
POST_CONNECTION_OPEN: () => this.handlePostConnectionOpen()
};
handlePostConnectionOpen = () => {
if (ForLaterExperiment.getConfig({
location: "saved_messages_manager"
}).enabled) {
fetchAndUpdateSavedMessages();
}
};
}
const savedMessagesManager = new SavedMessagesManager();
export default savedMessagesManager;
@@ -0,0 +1,295 @@
// Metro module 9553 (f9554).
import UserStore from "../../stores/UserStore";
import { SecondaryIndexMap } from "../../_bundle/Module3813";
import { SavedMessageSortTypes } from "./SavedMessagesTypes";
import { updateMessageRecord } from "../messages/MessageRecordUtils";
import Module589 from "../../_bundle/Module589";
import Dispatcher from "../../Dispatcher";
let c6299_3, c6299_5, c6299_6, c6299_7, c6299_8, c6299_9, c6299_10, isChannelRelevant, upsertSavedMessage, nullifyMessageObject;
const getTimeSafe = function getTimeSafe(a0) {
let time;
if (a0 == null) {
return c6299_3;
}
try {
time = new Date(a0).getTime();
} catch ($e) {
throw new Error(`Invalid date given (${a0})`);
}
return time;
};
isChannelRelevant = function isChannelRelevant(id) {
const r7 = c6299_10.get(id);
return r7 != null && r7.size > 0;
};
upsertSavedMessage = function upsertSavedMessage(a0) {
const saveData = a0.saveData;
const r16 = `${saveData.channelId}-${saveData.messageId}`;
if (c6299_5.get(r16) == null) {
c6299_7 = Date.now();
}
c6299_5.set(r16, a0);
const messageId = a0.saveData.messageId;
const channelId = a0.saveData.channelId;
let r31 = c6299_10.get(channelId);
if (r31 == null) {
r31 = new Set();
}
r31.add(messageId);
c6299_10.set(channelId, r31);
if (a0.message == null) {
c6299_9.add(messageId);
}
if (a0.saveData.dueAt != null && new Date() > a0.saveData.dueAt) {
c6299_8.add(messageId);
} else {
c6299_8.delete(messageId);
}
};
nullifyMessageObject = function nullifyMessageObject(a0) {
const r13 = `${a0.channelId}-${a0.messageId}`;
const r17 = c6299_5.get(r13);
if (r17?.message == null) {
return false;
}
c6299_5.set(r13, {
...r17,
message: null
});
return true;
};
const handleGuild = function handleGuild() {
let r1 = c6299_9.size !== 0;
if (r1) {
const r3 = c6299_6;
let r2 = !r3;
if (!r3) {
c6299_6 = true;
r2 = void 0;
}
r1 = r2;
}
return r1;
};
c6299_3 = 10000000000000;
c6299_5 = new SecondaryIndexMap((a0) => [SavedMessageSortTypes.ALL, a0.saveData.dueAt != null ? SavedMessageSortTypes.REMINDER : SavedMessageSortTypes.BOOKMARK], ({ saveData }) => saveData.dueAt != null ? getTimeSafe(saveData.dueAt) : c6299_3 - getTimeSafe(saveData.savedAt));
c6299_6 = true;
c6299_7 = 0;
c6299_8 = new Set();
c6299_9 = new Set();
c6299_10 = new Map();
class SavedMessagesStore extends Module589.Store {
static displayName = "SavedMessagesStore";
initialize() {
this.waitFor(UserStore);
}
getSavedMessages() {
return c6299_5.values(SavedMessageSortTypes.ALL);
}
getSavedMessage(a0, a1) {
return c6299_5.get(`${a0}-${a1}`);
}
getMessageBookmarks() {
return c6299_5.values(SavedMessageSortTypes.BOOKMARK);
}
getMessageReminders() {
return c6299_5.values(SavedMessageSortTypes.REMINDER);
}
getOverdueMessageReminderCount() {
return c6299_8.size;
}
hasOverdueReminder() {
return c6299_8.size > 0;
}
getMostRecentOverdueDueAt() {
const r4 = Date.now();
let r22 = 0;
for (const item of c6299_5.values(SavedMessageSortTypes.REMINDER)) {
const timeSafe = getTimeSafe(item.saveData.dueAt);
if (!(timeSafe > r4)) {
r22 = timeSafe;
continue;
}
break;
}
return r22;
}
getSavedMessageCount() {
return c6299_5.size();
}
getIsStale() {
return c6299_6;
}
getLastChanged() {
return c6299_7;
}
isMessageBookmarked(a0, a1) {
const r13 = c6299_5.get(`${a0}-${a1}`);
return r13 != null && r13.saveData.dueAt == null;
}
isMessageReminder(a0, a1) {
const r13 = c6299_5.get(`${a0}-${a1}`);
return r13 != null && r13.saveData.dueAt != null;
}
}
const savedMessagesStore = new SavedMessagesStore(Dispatcher, {
POST_CONNECTION_OPEN: function handlePostConnectionOpen() {
c6299_6 = true;
},
LOGOUT: function handleLogout() {
c6299_6 = true;
c6299_5.clear();
c6299_10.clear();
c6299_9.clear();
},
SAVED_MESSAGES_UPDATE: function handleUpdate({ savedMessages }) {
c6299_6 = false;
c6299_5.clear();
c6299_10.clear();
c6299_9.clear();
for (const item of savedMessages) {
upsertSavedMessage(item);
}
},
SAVED_MESSAGE_CREATE: function handleCreate(a0) {
upsertSavedMessage(a0.savedMessage);
},
SAVED_MESSAGE_DELETE: function handleDelete({ savedMessageData }) {
const r13 = `${savedMessageData.channelId}-${savedMessageData.messageId}`;
const r16 = c6299_5.get(r13);
const r2 = r16 == null;
let r0 = false;
if (!r2) {
c6299_5.delete(r13);
const messageId = savedMessageData.messageId;
const r24 = c6299_10.get(r16.saveData.channelId);
if (r24 != null) {
r24.delete(messageId);
}
c6299_9.delete(messageId);
c6299_8.delete(messageId);
c6299_7 = Date.now();
r0 = void 0;
}
return r0;
},
MESSAGE_DELETE: function handleMessageDelete(a0) {
const r14 = `${a0.channelId}-${a0.id}`;
const r18 = c6299_5.get(r14);
const r2 = r18?.message == null;
let r20 = false;
if (!r2) {
c6299_5.set(r14, {
...r18,
message: null
});
r20 = true;
}
return r20;
},
MESSAGE_DELETE_BULK: function handleMessageDeleteBulk({ ids, channelId }) {
for (const item of ids) {
nullifyMessageObject({
messageId: item,
channelId
});
}
},
MESSAGE_UPDATE: function handleMessageUpdate({ message }) {
if (message.id != null && message.channel_id != null) {
const r18 = `${message.channel_id}-${message.id}`;
const r21 = c6299_5.get(r18);
if (r21?.message == null) {
return false;
}
c6299_5.set(r18, {
...r21,
message: updateMessageRecord(r21.message, message)
});
return void 0;
}
return false;
},
GUILD_CREATE: handleGuild,
GUILD_UPDATE: handleGuild,
GUILD_DELETE: handleGuild,
CHANNEL_CREATE: function handleChannelCreate({ channel }) {
let r2 = c6299_9.size !== 0;
if (r2) {
const r1 = c6299_6;
let r3 = !r1;
if (!r1) {
const r13 = c6299_10.get(channel.id);
let r18 = !!(r13 != null && r13.size > 0);
if (r18) {
c6299_6 = true;
r18 = void 0;
}
r3 = r18;
}
r2 = r3;
}
return r2;
},
CHANNEL_UPDATES: function handleChannelUpdates({ channels }) {
if (c6299_9.size === 0) {
return false;
}
if (c6299_6) {
return false;
}
let r24 = false;
for (const item of channels) {
if (isChannelRelevant(item.id)) {
c6299_6 = true;
r24 = true;
}
}
return r24;
},
CHANNEL_DELETE: function handleChannelDelete({ channel }) {
let r2 = c6299_9.size !== 0;
if (r2) {
const r1 = c6299_6;
let r3 = !r1;
if (!r1) {
const r13 = c6299_10.get(channel.id);
let r18 = !!(r13 != null && r13.size > 0);
if (r18) {
c6299_6 = true;
r18 = void 0;
}
r3 = r18;
}
r2 = r3;
}
return r2;
},
GUILD_MEMBER_UPDATE: function handleGuildMemberUpdate({ user }) {
let r2 = c6299_9.size !== 0;
if (r2) {
const r1 = c6299_6;
let r3 = !r1;
if (!r1) {
let r18 = user.id === UserStore.getCurrentUser()?.id;
if (r18) {
c6299_6 = true;
r18 = void 0;
}
r3 = r18;
}
r2 = r3;
}
return r2;
},
GUILD_ROLE_CREATE: handleGuild,
GUILD_ROLE_UPDATE: handleGuild,
GUILD_ROLE_DELETE: handleGuild,
MESSAGE_REMINDER_DUE: function handleMessageReminderDue(a0) {
c6299_8.add(a0.savedMessage.saveData.messageId);
}
});
export default savedMessagesStore;
export function getComparator(a0) {
return a0.dueAt != null ? getTimeSafe(a0.dueAt) : c6299_3 - getTimeSafe(a0.savedAt);
}
@@ -0,0 +1,47 @@
// Metro module 9554 (f9555).
import { createMessageRecord } from "../messages/MessageRecordUtils";
const r11 = {
ALL: "ALL",
REMINDER: "REMINDER",
BOOKMARK: "BOOKMARK"
};
export { r11 as SavedMessageSortTypes };
export function savedMessageDataToClient(a0) {
return {
channelId: a0.channel_id,
messageId: a0.message_id,
savedAt: new Date(a0.saved_at),
authorSummary: a0.author_summary,
channelSummary: a0.channel_summary,
messageSummary: a0.message_summary,
guildId: a0.guild_id !== 0 ? a0.guild_id : void 0,
authorId: a0.author_id !== 0 ? a0.author_id : void 0,
notes: a0.notes,
dueAt: a0.due_at != null ? new Date(a0.due_at) : void 0
};
}
export function savedMessageCreateObjectToClient(a0) {
const message = a0.message != null ? createMessageRecord(a0.message) : null;
const save_data = a0.save_data;
return {
message,
saveData: {
channelId: save_data.channel_id,
messageId: save_data.message_id,
savedAt: new Date(save_data.saved_at),
authorSummary: save_data.author_summary,
channelSummary: save_data.channel_summary,
messageSummary: save_data.message_summary,
guildId: save_data.guild_id !== 0 ? save_data.guild_id : void 0,
authorId: save_data.author_id !== 0 ? save_data.author_id : void 0,
notes: save_data.notes,
dueAt: save_data.due_at != null ? new Date(save_data.due_at) : void 0
}
};
}
export function savedMessageDeleteObjectToClient(a0) {
return {
channelId: a0.channel_id,
messageId: a0.message_id
};
}
@@ -0,0 +1,7 @@
// Metro module 9557 (f9558).
import UserStore from "../../stores/UserStore";
import { PremiumTypes } from "../premium/PremiumConstants";
import { isPremium } from "../../utils/PremiumTypeUtils";
export default function hasForLaterPremiumType() {
return isPremium(UserStore.getCurrentUser(), PremiumTypes.TIER_2);
};
@@ -0,0 +1,48 @@
// Metro module 16312 (f16313).
import SavedMessagesStore from "../SavedMessagesStore";
import ForLaterExperiment from "../ForLaterExperiment";
import Dispatcher from "../../../Dispatcher";
import Durations from "../../../utils/Durations";
import AutomaticLifecycleManager from "../../../lib/AutomaticLifecycleManager";
let c11730_3;
const scheduleNextNotification = function scheduleNextNotification() {
if (ForLaterExperiment.getConfig({
location: "MessageRemindersNotificationManager"
}).enabled) {
if (c11730_3 != null) {
clearTimeout(c11730_3);
}
const savedMessage = SavedMessagesStore.getMessageReminders().find((item) => item.saveData.dueAt != null && item.saveData.dueAt > new Date());
if ((savedMessage == null ? void 0 : savedMessage.saveData?.dueAt) != null) {
const r35 = Date.now() + Durations.Millis.WEEK;
if (!(savedMessage.saveData.dueAt.getTime() > r35)) {
c11730_3 = setTimeout(() => {
if (ForLaterExperiment.getConfig({
location: "MessageRemindersNotificationManager"
}).enabled) {
Dispatcher.dispatch({
type: "MESSAGE_REMINDER_DUE",
savedMessage
});
scheduleNextNotification();
}
}, savedMessage.saveData.dueAt.getTime() - Date.now());
}
} else {
c11730_3 = null;
}
}
};
c11730_3 = null;
class MessageRemindersNotificationManager extends AutomaticLifecycleManager {
actions = {
SAVED_MESSAGES_UPDATE: () => this.handleUpdates(),
SAVED_MESSAGE_CREATE: () => this.handleUpdates(),
SAVED_MESSAGE_DELETE: () => this.handleUpdates()
};
handleUpdates = () => {
scheduleNextNotification();
};
}
const messageRemindersNotificationManager = new MessageRemindersNotificationManager();
export default messageRemindersNotificationManager;
@@ -0,0 +1,38 @@
// Metro module 9946 (f9947).
import Module3771 from "../../../_bundle/Module3771";
import { intl, t } from "../../../intl/index.native";
const r15 = [{
getDueAt: () => Module3771().add(30, "minutes").toDate(),
getLabel: () => intl.string(t["OV8l/H"])
}, {
getDueAt: () => Module3771().add(1, "hour").toDate(),
getLabel: () => intl.string(t["zf0R+0"])
}, {
getDueAt: () => Module3771().add(4, "hour").toDate(),
getLabel: () => intl.string(t["5gztZN"])
}, {
getDueAt: () => {
const r13 = Module3771().startOf("day").add(9, "hours");
return Module3771().hour() >= 9 ? r13.add(1, "day").toDate() : r13.toDate();
},
getLabel: () => Module3771().hour() >= 9 ? intl.string(t["7MKr2P"]) : intl.string(t.FnFI3m)
}, {
getDueAt: () => {
let r13;
L4: {
const r12 = Module3771().day();
if (r12 !== 0) {
r13 = 8;
if (r12 !== 1) {
break L4;
}
r13 = Module3771().startOf("day").add(9, "hours").isAfter(Module3771()) ? 1 : 8;
} else {
r13 = 1;
}
}
return Module3771().day(r13).startOf("day").add(9, "hours").toDate();
},
getLabel: () => intl.string(t["q+Ls05"])
}];
export { r15 as MESSAGE_REMINDER_DURATION_ITEMS };
@@ -0,0 +1,72 @@
// Metro module 9945 (f9946).
import { useState, useEffect, useMemo } from "react";
import SavedMessagesStore from "../../SavedMessagesStore";
import { createStyles } from "../../../../design/components/Styles/native/createStyles";
import Module712 from "../../../../_bundle/Module712";
import { useStateFromStores } from "../../../../_bundle/Module589";
import Durations from "../../../../utils/Durations";
import { useDueInString, DueInStringTypes } from "../../SavedMessageUtils";
import { BottomSheetTitleHeader } from "../../../../design/components/Sheet/native/BottomSheetTitleHeader.native";
import { intl, t } from "../../../../intl/index.native";
import { PressableOpacity } from "../../../../design/void/Pressables/native/Pressables";
import { ArrowLargeLeftIcon } from "../../../../design/components/Icon/native/redesign/generated/ArrowLargeLeftIcon";
import { MESSAGE_REMINDER_DURATION_ITEMS } from "../MessageRemindersTypes";
import { TableRow } from "../../../../design/components/TableRow/native/TableRow.native";
import ActionSheetActionCreators from "../../../action_sheet/native/ActionSheetActionCreators";
import ModalActionCreators from "../../../../actions/ModalActionCreators";
import { BottomSheet } from "../../../../design/components/Sheet/native/BottomSheet.native";
import { TableRowGroup } from "../../../../design/components/TableRow/native/TableRowGroup.native";
import { CheckmarkLargeIcon } from "../../../../design/components/Icon/native/redesign/generated/CheckmarkLargeIcon";
const useStyles = createStyles({
body: {
paddingHorizontal: Module712.space.PX_16,
gap: Module712.space.PX_24
}
});
export default function MessageReminderDurationActionSheet(props) {
let setState, dueInText;
const { createReminder, removeReminder, channelId, messageId, onBack } = props;
setState = void 0;
dueInText = void 0;
const styles = useStyles();
const stateFromStores = useStateFromStores([SavedMessagesStore], () => SavedMessagesStore.getSavedMessage(channelId, messageId));
let now;
[now, setState] = useState(new Date());
useEffect(() => {
let c26573_0 = setInterval(() => setState(new Date()), Durations.Millis.MINUTE);
return () => {
clearInterval(c26573_0);
};
}, []);
dueInText = useDueInString({
dueAt: stateFromStores == null ? void 0 : stateFromStores.saveData.dueAt,
now,
type: DueInStringTypes.SHORT
}).dueInText;
return <BottomSheet header={useMemo(() => <BottomSheetTitleHeader title={intl.string(t.roMu1H)} subtitle={dueInText} leading={onBack != null && <PressableOpacity accessibilityRole="button" accessibilityLabel={intl.string(t["13/7kX"])} onPress={onBack}>
<ArrowLargeLeftIcon size="md" />
</PressableOpacity>} />, [onBack, dueInText])} bodyStyles={styles.body} startExpanded>
<TableRowGroup hasIcons={false}>
{useMemo(() => {
const r13 = MESSAGE_REMINDER_DURATION_ITEMS.map(({ getDueAt, getLabel }) => <TableRow key={`create-reminder-${getLabel()}`} label={getLabel()} onPress={() => {
createReminder(getDueAt());
ActionSheetActionCreators.hideActionSheet();
}} />);
r13.push(<TableRow key="create-reminder-custom" label={intl.string(t.OLA8Zi)} onPress={() => {
ActionSheetActionCreators.hideActionSheet();
ModalActionCreators.pushLazy(import("./MessageRemindersCustomDurationModal"), {
onClose: ModalActionCreators.pop(),
createReminder
}, "create-reminder-custom", {
presentation: "modal"
});
}} arrow />);
return r13;
}, [createReminder])}
</TableRowGroup>
{removeReminder != null && <TableRow key="remove-reminder" icon={<CheckmarkLargeIcon />} label={intl.string(t.yjGtdJ)} onPress={() => {
ActionSheetActionCreators.hideActionSheet();
removeReminder();
}} start end />}
</BottomSheet>;
};
@@ -0,0 +1,100 @@
// Metro module 9947 (f9948).
import { memo, useState, useCallback } from "react";
import { View } from "react-native";
import { createStyles } from "../../../../design/components/Styles/native/createStyles";
import Module712 from "../../../../_bundle/Module712";
import Module3771 from "../../../../_bundle/Module3771";
import { dismissGlobalKeyboard } from "../../../../utils/native/KeyboardManagerUtils";
import { intl, t } from "../../../../intl/index.native";
import ActionSheetActionCreators from "../../../action_sheet/native/ActionSheetActionCreators";
import { Header } from "../../../../_bundle/Module5150";
import { GenericHeaderTitle } from "../../../main_tabs_v2/native/shared_components/HeaderShared";
import { isIOS } from "../../../../utils/PlatformUtils";
import { getHeaderCloseButton } from "../../../../design/components/Navigator/native/NavigatorHeader.native";
import { PressableOpacity } from "../../../../design/void/Pressables/native/Pressables";
import { Text } from "../../../../design/components/Text/native/Text";
const useStyles = createStyles({
modal: {
flex: 1,
backgroundColor: Module712.colors.BACKGROUND_BASE_LOWER
},
headerContainer: {
paddingHorizontal: Module712.space.PX_16,
paddingTop: Module712.space.PX_8
},
container: {
paddingHorizontal: 16,
paddingTop: 24,
gap: 24
},
formHeader: {
marginBottom: 8
},
inputContainer: {
paddingHorizontal: 16,
paddingVertical: 12,
borderRadius: Module712.radii.lg,
backgroundColor: Module712.colors.INPUT_BACKGROUND_DEFAULT
}
});
const r56 = memo(function({ onClose, createReminder }) {
let state, setState, callback;
state = void 0;
setState = void 0;
callback = void 0;
const handleOpenDatePicker2 = function handleOpenDatePicker(a0) {
dismissGlobalKeyboard();
const title = a0 === "date" ? intl.string(t.pSZKvM) : intl.string(t.GOmEb8);
ActionSheetActionCreators.openLazy(import("../../../../components_native/DatePickerActionSheet"), "DatePicker", {
title,
startDate: state.toDate(),
minimumDate: Module3771().toDate(),
mode: a0,
onSubmit: setState
});
};
const styles = useStyles();
[state, setState] = useState(() => Module3771());
callback = useCallback(() => {
createReminder(state.toDate());
onClose();
}, [createReminder, state, onClose]);
const text2 = state.format("MMM Do YYYY");
const text = state.format("LT");
return <View style={styles.modal}>
<View style={styles.headerContainer}>
<Header title={intl.string(t.VKsXpY)} headerTitle={() => <GenericHeaderTitle title={intl.string(t.VKsXpY)} />} headerTitleAlign="center" headerStatusBarHeight={isIOS() ? 0 : void 0} headerLeft={getHeaderCloseButton(onClose)} headerRight={() => <PressableOpacity accessibilityRole="button" onPress={callback}>
<Text variant="text-md/semibold" color="control-brand-foreground">
{intl.string(t["R3BPH+"])}
</Text>
</PressableOpacity>} />
</View>
<View style={styles.container}>
<View>
<Text style={styles.formHeader} variant="text-sm/semibold" color="text-subtle">
{intl.string(t.pSZKvM)}
</Text>
<PressableOpacity accessibilityRole="button" accessibilityLabel={intl.string(t.pSZKvM)} accessibilityValue={{
text: text2
}} onPress={() => {
handleOpenDatePicker2("date");
}} style={styles.inputContainer}>
<Text variant="text-md/medium">{text2}</Text>
</PressableOpacity>
</View>
<View>
<Text style={styles.formHeader} variant="text-sm/semibold" color="text-subtle">
{intl.string(t.GOmEb8)}
</Text>
<PressableOpacity accessibilityRole="button" accessibilityLabel={intl.string(t.pSZKvM)} accessibilityValue={{
text
}} onPress={() => {
handleOpenDatePicker2("time");
}} style={styles.inputContainer}>
<Text variant="text-md/medium">{text}</Text>
</PressableOpacity>
</View>
</View>
</View>;
});
export default r56;
@@ -0,0 +1,62 @@
// Metro module 9944 (f9945).
import { useCallback } from "react";
import { View } from "react-native";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import ActionSheetActionCreators from "../../action_sheet/native/ActionSheetActionCreators";
import { addOrUpdateSavedMessage, removeSavedMessage } from "../SavedMessageHelpers.native";
import { intl, t } from "../../../intl/index.native";
import { ChatArrowRightIcon } from "../../../design/components/Icon/native/redesign/generated/ChatArrowRightIcon";
import { XSmallIcon } from "../../../design/components/Icon/native/redesign/generated/XSmallIcon";
import { PencilIcon } from "../../../design/components/Icon/native/redesign/generated/PencilIcon";
import { ContextMenu } from "../../../design/components/ContextMenu/native/ContextMenu.native";
import { IconButton } from "../../../design/components/Button/native/IconButton.native";
import Module8964 from "../../../_bundle/Module8964";
const useStyles = createStyles({
actionGroup: {
flexDirection: "row",
gap: 8
}
});
export default function ForLaterCardActionButtons(props) {
const { savedMessage, jumpToMessage } = props;
const styles = useStyles();
const callback = useCallback(() => ActionSheetActionCreators.openLazy(import("../message_reminders/native/MessageReminderDurationActionSheet"), "MessageReminderDurationActionSheet", {
createReminder: (a0) => addOrUpdateSavedMessage({
...savedMessage.saveData,
dueAt: a0
}),
removeReminder: () => removeSavedMessage({
channelId: savedMessage.saveData.channelId,
messageId: savedMessage.saveData.messageId,
displayToast: true,
isReminder: true
}),
channelId: savedMessage.saveData.channelId,
messageId: savedMessage.saveData.messageId
}), [savedMessage]);
const items = [{
label: intl.string(t["+TSRGD"]),
IconComponent: ChatArrowRightIcon,
action: () => jumpToMessage()
}, {
label: intl.string(savedMessage.saveData.dueAt != null ? t["a6gcZ/"] : t.SvXS1Z),
IconComponent: XSmallIcon,
action: () => removeSavedMessage(savedMessage.saveData),
variant: "destructive"
}];
if (savedMessage.saveData.dueAt != null) {
items.unshift({
label: intl.string(t.vrbqs1),
IconComponent: PencilIcon,
action: callback
});
}
return <View style={styles.actionGroup}>
<ContextMenu items={items} keyboardShouldPersistTaps="handled" triggerOnTap>
{(a0) => {
const { ref, ...rest } = a0;
return <IconButton ref={a0.ref} {...rest} variant="secondary" accessibilityLabel={intl.string(t.e1heBD)} size="sm" icon={Module8964} />;
}}
</ContextMenu>
</View>;
};
@@ -0,0 +1,76 @@
// Metro module 9951 (f9952).
import { View } from "react-native";
import GuildStore from "../../../stores/GuildStore";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import { ChevronSmallRightIcon } from "../../../design/components/Icon/native/redesign/generated/ChevronSmallRightIcon";
import { useStateFromStores } from "../../../_bundle/Module589";
import GuildIcon, { GuildIconSizes } from "../../guild/native/GuildIcon";
import GroupDMAvatar from "../../group_dm/native/GroupDMAvatar";
import { AvatarSizes } from "../../../design/void/native";
import { ChatIcon } from "../../../design/components/Icon/native/redesign/generated/ChatIcon";
import useChannelName from "../../channel/useChannelName";
import { getChannelIconComponentWithGuild } from "../../../utils/native/ChannelUtils";
import { intl, t } from "../../../intl/index.native";
import { Text } from "../../../design/components/Text/native/Text";
let useStyles, ChannelName;
const HeaderIcon = function HeaderIcon(props) {
const channel = props.channel;
const styles = useStyles();
const stateFromStores = useStateFromStores([GuildStore], () => GuildStore.getGuild(channel.guild_id));
return stateFromStores != null ? <GuildIcon guild={stateFromStores} size={GuildIconSizes.XSMALL} /> : (channel == null ? void 0 : channel.isGroupDM()) ? <GroupDMAvatar channel={channel} size={AvatarSizes.XSMALL} /> : <View style={styles.dmIcon}>
<ChatIcon size="xxs" />
</View>;
};
ChannelName = function ChannelName(props) {
const channel2 = props.channel;
const styles = useStyles();
const stateFromStores = useStateFromStores([GuildStore], () => GuildStore.getGuild(channel2.guild_id));
const channelName = useChannelName(channel2, false);
const ChannelIconComponentWithGuild = getChannelIconComponentWithGuild(channel2, stateFromStores);
const r27 = channel2.isPrivate() || ChannelIconComponentWithGuild == null;
const r31 = channel2.isDM() ? intl.formatToPlainString(t.smD7XV, {
username: channelName
}) : channelName;
return <View style={styles.channelNameContainer}>
{r27 ? null : <ChannelIconComponentWithGuild style={styles.channelTypeIcon} size="xxs" />}
<Text style={styles.channelName} variant="text-md/semibold" color="mobile-text-heading-primary" lineClamp={1}>{r31}</Text>
</View>;
};
useStyles = createStyles({
cardHeader: {
flexDirection: "row",
alignItems: "center",
gap: 8
},
dmIcon: {
padding: 6,
backgroundColor: Module712.colors.BACKGROUND_BASE_LOWEST,
borderRadius: Module712.radii.sm
},
channelNameContainer: {
flexDirection: "row",
alignItems: "center",
flexShrink: 1
},
channelName: {
flexShrink: 1
},
channelTypeIcon: {
marginRight: 4
},
actionsContainer: {
marginVertical: -4,
marginLeft: "auto"
}
});
export function ForLaterCardHeader(props) {
const { channel: channel3, actions } = props;
const styles = useStyles();
return <View style={styles.cardHeader}>
<HeaderIcon channel={channel3} />
{channel3.isPrivate() ? null : <ChevronSmallRightIcon size="xxs" />}
<ChannelName channel={channel3} />
<View style={styles.actionsContainer}>{actions}</View>
</View>;
}
@@ -0,0 +1,54 @@
// Metro module 9950 (f9951).
import { View } from "react-native";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import { useDueInString, DueInStringTypes } from "../SavedMessageUtils";
import { ClockIcon } from "../../../design/components/Icon/native/redesign/generated/ClockIcon";
import { Text } from "../../../design/components/Text/native/Text";
const useStyles = createStyles({
container: {
flexDirection: "row",
alignItems: "center",
backgroundColor: Module712.colors.BACKGROUND_BASE_LOWER,
borderTopLeftRadius: Module712.radii.lg,
borderTopRightRadius: Module712.radii.lg,
overflow: "hidden",
gap: 8,
marginHorizontal: -16,
marginTop: -16,
paddingHorizontal: 16,
paddingVertical: 12
},
icon: {
width: 24,
height: 24,
borderRadius: Module712.radii.sm,
backgroundColor: Module712.colors.CARD_BACKGROUND_DEFAULT,
alignItems: "center",
justifyContent: "center"
},
actionsContainer: {
marginVertical: -4,
marginLeft: "auto"
}
});
export function ForLaterCardReminderHeader(props) {
const { savedMessage, throttledNow, actions } = props;
const styles = useStyles();
const dueInString = useDueInString({
dueAt: savedMessage == null ? void 0 : savedMessage.saveData.dueAt,
now: throttledNow,
type: DueInStringTypes.SHORT
});
const { dueInText, isOverdue } = dueInString;
if (savedMessage.saveData.dueAt == null) {
return null;
}
return <View style={styles.container}>
<View style={styles.icon}>
<ClockIcon size="xxs" color={isOverdue ? Module712.colors.TEXT_FEEDBACK_CRITICAL : Module712.colors.INTERACTIVE_TEXT_DEFAULT} />
</View>
<Text variant="text-md/semibold" color={isOverdue ? "text-feedback-critical" : "mobile-text-heading-primary"}>{dueInText}</Text>
<View style={styles.actionsContainer}>{actions}</View>
</View>;
}
@@ -0,0 +1,51 @@
// Metro module 9953 (f9954).
import { Image as Image2, ScrollView, View } from "react-native";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module9954 from "../../../_bundle/Module9954";
import { Text } from "../../../design/components/Text/native/Text";
import { intl, t } from "../../../intl/index.native";
import { SavedMessageSortTypes } from "../SavedMessagesTypes";
const useStyles = createStyles({
scrollView: {
flex: 1
},
pageContainer: {
flexGrow: 1,
justifyContent: "center",
alignItems: "center",
paddingHorizontal: 32,
paddingVertical: 16
},
container: {
alignItems: "center",
maxWidth: 311
},
image: {
width: 140,
height: 130
},
textContainer: {
marginTop: 24,
gap: 8
},
text: {
textAlign: "center"
}
});
export function ForLaterEmptyState(props) {
const type = props.type;
const styles = useStyles();
return <ScrollView style={styles.scrollView} contentContainerStyle={styles.pageContainer}>
<View style={styles.container}>
<Image2 source={Module9954} style={styles.image} />
<View style={styles.textContainer}>
<Text variant="heading-xl/extrabold" color="mobile-text-heading-primary" style={styles.text}>
{intl.string(type === SavedMessageSortTypes.REMINDER ? t.AE4yja : t.erEf2g)}
</Text>
<Text variant="text-sm/medium" color="text-default" style={styles.text}>
{intl.string(type === SavedMessageSortTypes.REMINDER ? t.iBFuNE : t["w1o+75"])}
</Text>
</View>
</View>
</ScrollView>;
}
@@ -0,0 +1,123 @@
// Metro module 9941 (f9942).
import { memo, useCallback } from "react";
import { View } from "react-native";
import PermissionStore from "../../../stores/PermissionStore";
import { AnalyticEvents, ChannelTypes, Permissions } from "../../../Constants";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import { Card } from "../../../design/components/Card/native/Card.native";
import { CircleErrorIcon } from "../../../design/components/Icon/native/redesign/generated/CircleErrorIcon";
import { Text } from "../../../design/components/Text/native/Text";
import { intl, t } from "../../../intl/index.native";
import { IconButton } from "../../../design/components/Button/native/IconButton.native";
import Module4149 from "../../../_bundle/Module4149";
import { removeSavedMessage } from "../SavedMessageHelpers.native";
import { useSavedMessageChannel, savedMessageJumpToMessage } from "../SavedMessageUtils";
import ModalActionCreators from "../../../actions/ModalActionCreators";
import AnalyticsUtils from "../../../utils/AnalyticsUtils";
import { SavedMessageSortTypes } from "../SavedMessagesTypes";
import Module3771 from "../../../_bundle/Module3771";
import validateJumpWithAlert from "../../messages/validateJumpWithAlert";
import { useStateFromStores } from "../../../_bundle/Module589";
import ForLaterCardActionButtons from "./ForLaterCardActionButtons";
import { ForLaterCardReminderHeader } from "./ForLaterCardReminderHeader";
import { ForLaterCardHeader } from "./ForLaterCardHeader";
import { ForLaterMessageRow } from "./ForLaterMessageRow";
let useStyles;
const ForLaterDeletedMessageCard = function ForLaterDeletedMessageCard(props) {
const savedMessage = props.savedMessage;
const styles = useStyles();
return <Card variant="primary" border="subtle" shadow="none" style={[styles.card, styles.deletedCard]}>
<CircleErrorIcon size="xs" color={Module712.colors.ICON_MUTED} />
<Text variant="text-md/semibold" color="mobile-text-heading-primary" style={styles.deletedText}>
{savedMessage.saveData.dueAt != null ? intl.string(t["wuQm+j"]) : intl.string(t.o572Fe)}
</Text>
<View style={styles.deletedActionButton}>
<IconButton variant="secondary" accessibilityLabel={intl.string(t.SvXS1Z)} size="sm" icon={Module4149} onPress={() => removeSavedMessage(savedMessage.saveData)} />
</View>
</Card>;
};
useStyles = createStyles({
card: {
gap: 16,
marginBottom: 16
},
cardDivider: {
marginHorizontal: -16,
height: 1,
alignSelf: "stretch",
backgroundColor: Module712.colors.BACKGROUND_MOD_MUTED
},
messagePreview: {
marginHorizontal: -16,
marginTop: -9,
marginBottom: -16,
borderBottomLeftRadius: Module712.modules.mobile.CARD_DEFAULT_RADIUS,
borderBottomRightRadius: Module712.modules.mobile.CARD_DEFAULT_RADIUS,
overflow: "hidden"
},
deletedCard: {
flexDirection: "row",
alignItems: "center",
gap: 8
},
deletedText: {
flex: 1
},
deletedActionButton: {
marginLeft: "auto"
}
});
const r59 = memo(function ForLaterMessageCard(props) {
const { savedMessage: savedMessage2, throttledNow } = props;
const styles = useStyles();
const savedMessageChannel = useSavedMessageChannel(savedMessage2);
const callback = useCallback(async () => {
L11: {
let _jumpTo2;
const jumpTo = function jumpTo() {
return _jumpTo2.apply(this, arguments);
};
_jumpTo2 = function _jumpTo() {
const r9 = async () => {
let c31994_0;
c31994_0 = void 0;
await savedMessageJumpToMessage(savedMessage2, savedMessageChannel);
ModalActionCreators.pop();
const FOR_LATER_SAVED_MESSAGE_JUMP = AnalyticEvents.FOR_LATER_SAVED_MESSAGE_JUMP;
const message = savedMessage2.message;
AnalyticsUtils.track(FOR_LATER_SAVED_MESSAGE_JUMP, {
channel_id: savedMessage2.saveData.channelId,
message_id: savedMessage2.saveData.messageId,
message_author_id: message == null ? void 0 : message.author.id,
type: savedMessage2.saveData.dueAt != null ? SavedMessageSortTypes.REMINDER : SavedMessageSortTypes.BOOKMARK,
due_duration: savedMessage2.saveData.dueAt != null ? Module3771().diff(savedMessage2.saveData.dueAt) : void 0
});
};
_jumpTo2 = r9;
return r9.apply(this, arguments);
};
if (validateJumpWithAlert(savedMessage2.message, jumpTo)) {
await jumpTo();
break L11;
}
return void 0;
}
}, [savedMessage2, savedMessageChannel]);
const stateFromStores = useStateFromStores([PermissionStore], () => savedMessageChannel?.type === ChannelTypes.UNKNOWN || (!!(savedMessageChannel == null ? void 0 : savedMessageChannel.isPrivate()) || PermissionStore.can(Permissions.VIEW_CHANNEL, savedMessageChannel)));
if (savedMessage2.message != null && savedMessageChannel != null && stateFromStores) {
const actions = <ForLaterCardActionButtons savedMessage={savedMessage2} jumpToMessage={callback} />;
const r1 = savedMessage2.saveData.dueAt != null;
return <Card variant="primary" border="subtle" shadow="none" style={styles.card} onPress={callback}>
{r1 ? <ForLaterCardReminderHeader savedMessage={savedMessage2} throttledNow={throttledNow} actions={actions} /> : null}
<ForLaterCardHeader channel={savedMessageChannel} actions={r1 ? null : actions} />
<View style={styles.cardDivider} />
<View style={styles.messagePreview}>
<ForLaterMessageRow message={savedMessage2.message} lineClamp={2} maxHeight={250} />
</View>
</Card>;
}
return <ForLaterDeletedMessageCard savedMessage={savedMessage2} />;
});
export default r59;
export { ForLaterDeletedMessageCard };
@@ -0,0 +1,47 @@
// Metro module 9952 (f9953).
import { useMemo } from "react";
import useTheme from "../../../hooks/useTheme";
import { createNativeStyleProperties } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import { RenderEmbeds, InlineEmbedMedia, InlineAttachmentMedia } from "../../user_settings/UserSettings";
import RowGenerator from "../../messages/native/renderer/RowGenerator";
import ChatItem from "../../../components_native/chat/ChatItem";
import { isIOS } from "../../../utils/PlatformUtils";
export function ForLaterMessageRow(props) {
const { message, lineClamp, maxHeight } = props;
const theme = useTheme();
let c17576_1 = createNativeStyleProperties({
seeMoreLabelColor: Module712.colors.TEXT_DEFAULT
})(theme);
const setting = RenderEmbeds.getSetting();
const setting2 = InlineEmbedMedia.getSetting();
const setting3 = InlineAttachmentMedia.getSetting();
return <ChatItem pointerEvents="none" horizontalOffset={0} modifyRow={function modifyRow(a0) {
if (lineClamp != null) {
a0.truncation = {
numberOfLines: lineClamp,
expandable: isIOS(),
seeMoreLabel: isIOS() ? "..." : "",
seeMoreLabelColor: c17576_1.seeMoreLabelColor
};
}
}} message={message} rowGenerator={useMemo(() => {
const rowGenerator = new RowGenerator();
rowGenerator.setOptions({
renderEmbeds: setting,
inlineEmbedMedia: setting2,
inlineAttachmentMedia: setting3,
renderReplies: false,
renderExecutedCommands: false,
animateEmoji: false,
renderGiftCode: false,
renderActivityInstanceEmbed: false,
renderActivityInviteEmbed: false,
renderThreadEmbeds: false,
renderForumPostActions: false,
ignoreMentioned: true,
shouldDisableInteractiveComponents: true
});
return rowGenerator;
}, [setting, setting2, setting3])} maxHeight={maxHeight} />;
}
@@ -0,0 +1,35 @@
// Metro module 9937 (f9938).
import { View } from "react-native";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import { intl, t } from "../../../intl/index.native";
import { SavedMessageSortTypes } from "../SavedMessagesTypes";
import { Header } from "../../../_bundle/Module5150";
import { GenericHeaderTitle } from "../../main_tabs_v2/native/shared_components/HeaderShared";
import { isIOS } from "../../../utils/PlatformUtils";
import { getHeaderCloseButton } from "../../../design/components/Navigator/native/NavigatorHeader.native";
import ModalActionCreators from "../../../actions/ModalActionCreators";
import ForLaterScreen from "./ForLaterScreen";
const useStyles = createStyles({
modal: {
backgroundColor: Module712.colors.BACKGROUND_BASE_LOWER,
borderBottomWidth: 0,
shadowColor: "transparent",
height: "100%"
},
headerContainer: {
paddingHorizontal: Module712.space.PX_16,
paddingTop: Module712.space.PX_8
}
});
export default function ForLaterModal(props) {
const type = props.type;
const styles = useStyles();
const title = intl.string(type === SavedMessageSortTypes.REMINDER ? t.aUXxzT : t["2pAkDA"]);
return <View style={styles.modal}>
<View style={styles.headerContainer}>
<Header title={title} headerTitle={() => <GenericHeaderTitle title={title} />} headerTitleAlign="center" headerStatusBarHeight={isIOS() ? 0 : void 0} headerLeft={getHeaderCloseButton(ModalActionCreators.pop)} />
</View>
<ForLaterScreen key={type} type={type} onClose={ModalActionCreators.pop} />
</View>;
};
@@ -0,0 +1,82 @@
// Metro module 15274 (f15275).
import { forwardRef, useCallback } from "react";
import { View } from "react-native";
import SavedMessagesStore from "../SavedMessagesStore";
import ClipView, { CutoutShape } from "../../../design/components/Icon/native/ClipView";
import { ICON_SIZE } from "../../../_bundle/Module15275";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import useTheme from "../../../hooks/useTheme";
import { useToken } from "../../../design/tokens/native/useToken";
import { useIconSizeStyles } from "../../../design/components/Button/native/ButtonHooks.native";
import { SavedMessageSortTypes } from "../SavedMessagesTypes";
import { ClockIcon } from "../../../design/components/Icon/native/redesign/generated/ClockIcon";
import { BookmarkIcon } from "../../../design/components/Icon/native/redesign/generated/BookmarkIcon";
import { useStateFromStores } from "../../../_bundle/Module589";
import hasForLaterPremiumType from "../hasForLaterPremiumType";
import openPremiumUpsellActionSheet from "../../premium/roadblocks/native/utils/openPremiumUpsellActionSheet";
import { EntitlementFeatureNames } from "../../../_bundle/Module6201";
import { showForLaterModal } from "./showForLaterModal";
import { IconButton } from "../../../design/components/Button/native/IconButton.native";
import { intl, t } from "../../../intl/index.native";
let c10852_8, useStyles;
const BadgedIcon = function BadgedIcon(props) {
const { type: type2, showRedDot } = props;
const token = useToken(Module712.colors.INTERACTIVE_TEXT_DEFAULT, useTheme());
const styles = useStyles();
const styles2 = useIconSizeStyles("sm", true, 2);
const Component = type2 === SavedMessageSortTypes.REMINDER ? ClockIcon : BookmarkIcon;
return <View style={[styles.container, styles2]}>
{showRedDot ? <View style={styles.iconAnchor}>
<ClipView cutouts={[c10852_8]}>
<Component size="sm" color={token} />
</ClipView>
<View style={styles.dot} />
</View> : <Component size="sm" color={token} />}
</View>;
};
c10852_8 = {
shape: CutoutShape.Circle,
x: ICON_SIZE.sm - 9,
y: -1,
size: 10
};
useStyles = createStyles({
container: {
aspectRatio: 1,
alignItems: "center",
justifyContent: "center",
position: "relative"
},
iconAnchor: {
width: ICON_SIZE.sm,
height: ICON_SIZE.sm,
position: "relative"
},
dot: {
position: "absolute",
height: 6.5,
width: 6.5,
backgroundColor: Module712.colors.BACKGROUND_FEEDBACK_NOTIFICATION,
borderRadius: Module712.radii.lg,
right: 1,
top: 0.7
}
});
const r62 = forwardRef(function({ type, onOpen }, a1) {
let stateFromStores;
stateFromStores = void 0;
const stateFromStores2 = useStateFromStores([SavedMessagesStore], () => SavedMessagesStore.hasOverdueReminder(), []);
stateFromStores = useStateFromStores([SavedMessagesStore], () => SavedMessagesStore.getSavedMessageCount());
return <View ref={a1}>
<IconButton variant="tertiary" size="sm" icon={<BadgedIcon type={type} showRedDot={type === SavedMessageSortTypes.REMINDER && stateFromStores2} />} onPress={useCallback(() => {
onOpen();
if (stateFromStores === 0 && !hasForLaterPremiumType()) {
openPremiumUpsellActionSheet(EntitlementFeatureNames.SAVED_MESSAGES);
} else {
showForLaterModal(type);
}
}, [onOpen, stateFromStores, type])} accessibilityLabel={intl.string(type === SavedMessageSortTypes.REMINDER ? t.aUXxzT : t["2pAkDA"])} maxFontSizeMultiplier={2} />
</View>;
});
export default r62;
@@ -0,0 +1,86 @@
// Metro module 9938 (f9939).
import { useState, useEffect, useCallback, memo } from "react";
import { View } from "react-native";
import SavedMessagesStore from "../SavedMessagesStore";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import ReanimatedRexport, { useSharedValue, useAnimatedStyle } from "../../reanimated/ReanimatedRexport";
import { withSpring } from "../../../design/animation/reanimated/spring/spring";
import useSavedMessagesForPage from "../useSavedMessagesForPage";
import { useStateFromStores } from "../../../_bundle/Module589";
import useTrackImpression from "../../app_analytics/useTrackImpression";
import { ImpressionTypes, ImpressionNames } from "../../../_bundle/Module503";
import Durations from "../../../utils/Durations";
import ForLaterMessageCard from "./ForLaterMessageCard";
import { ForLaterEmptyState } from "./ForLaterEmptyState";
import { FlashList } from "../../../_bundle/noop_6676";
let useStyles, __initData, ForLaterPage;
const keyExtractor = function keyExtractor(a0) {
return a0.saveData.messageId;
};
ForLaterPage = function ForLaterPage(props) {
let state, setState;
const { type, handleScroll } = props;
state = void 0;
setState = void 0;
const styles = useStyles();
const savedMessagesForPage = useSavedMessagesForPage(type);
const stateFromStores = useStateFromStores([SavedMessagesStore], () => SavedMessagesStore.getOverdueMessageReminderCount());
useTrackImpression({
type: ImpressionTypes.MODAL,
name: ImpressionNames.FOR_LATER_LIST_VIEWED,
properties: {
total_count: savedMessagesForPage.length,
overdue_count: stateFromStores
}
}, {}, [savedMessagesForPage.length, stateFromStores]);
[state, setState] = useState(new Date());
useEffect(() => {
let c26569_0 = setInterval(() => setState(new Date()), Durations.Millis.MINUTE);
return () => {
clearInterval(c26569_0);
};
}, []);
const callback = useCallback((a0) => <ForLaterMessageCard savedMessage={a0.item} throttledNow={state} />, [state]);
return savedMessagesForPage.length === 0 ? <ForLaterEmptyState type={type} /> : <FlashList data={savedMessagesForPage} renderItem={callback} contentContainerStyle={styles.cardContainer} keyExtractor={keyExtractor} onScroll={handleScroll} />;
};
useStyles = createStyles({
container: {
backgroundColor: Module712.colors.BACKGROUND_BASE_LOWER,
flexGrow: 1
},
headerBorder: {
height: 1,
width: "100%",
backgroundColor: Module712.colors.BORDER_SUBTLE
},
cardContainer: {
paddingHorizontal: 16,
paddingVertical: 8
}
});
__initData = {
code: "function ForLaterScreenTsx1(){const{borderOpacity}=this.__closure;return{opacity:borderOpacity.get()};}"
};
const r47 = memo(function({ type }) {
const styles = useStyles();
const sharedValue = useSharedValue(0);
const callback = useCallback((a0) => {
sharedValue.set(withSpring(a0.nativeEvent.contentOffset.y > 8 ? 1 : 0));
}, [sharedValue]);
const r23 = function() {
return {
opacity: sharedValue.get()
};
};
r23.__closure = {
borderOpacity: sharedValue
};
r23.__workletHash = 16693192032676;
r23.__initData = __initData;
return <View style={styles.container}>
<ReanimatedRexport.View style={[styles.headerBorder, useAnimatedStyle(r23)]} />
<ForLaterPage type={type} handleScroll={callback} />
</View>;
});
export default r47;
@@ -0,0 +1,9 @@
// Metro module 9936 (f9937).
import ModalActionCreators from "../../../actions/ModalActionCreators";
export function showForLaterModal(a0) {
ModalActionCreators.pushLazy(import("./ForLaterModal"), {
type: a0
}, "for-later-modal", {
presentation: "modal"
});
}
@@ -0,0 +1,41 @@
// Metro module 15272 (f15273).
import { useMemo } from "react";
import { Image as Image2 } from "react-native";
import { ContentDismissActionType } from "../../dismissible_content/DismissibleContentConstants";
import { DismissibleContent } from "../../../_bundle/Module1358";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module6204 from "../../../_bundle/Module6204";
import ForLaterExperiment from "../ForLaterExperiment";
import { useSelectedDismissibleContent } from "../../dismissible_content/hooks/useSelectedDismissibleContent";
import { intl, t } from "../../../intl/index.native";
import { useCoachmark } from "../../../design/components/Coachmark/native/useCoachmark.native";
let FOR_LATER_NOTIFICATIONS_COACHMARK, useStyles;
const CoachmarkImg = function CoachmarkImg() {
return <Image2 source={Module6204} style={useStyles().imageContainer} />;
};
FOR_LATER_NOTIFICATIONS_COACHMARK = DismissibleContent.FOR_LATER_NOTIFICATIONS_COACHMARK;
useStyles = createStyles({
imageContainer: {
width: 100,
height: 80
}
});
export default function useForLaterCoachmark(a0) {
const r10 = ForLaterExperiment.useConfig({
location: "forLaterCoachmark"
}).enabled ? [FOR_LATER_NOTIFICATIONS_COACHMARK] : [];
const [r11, r25] = useSelectedDismissibleContent(r10, void 0, true);
let c21833_0 = r11;
let c21833_1 = r25;
useCoachmark(a0, useMemo(() => ({
title: intl.string(t.qPbFK2),
description: intl.string(t.URrJq1),
position: "bottom",
visible: c21833_0 === FOR_LATER_NOTIFICATIONS_COACHMARK,
onDismiss: () => {
c21833_1(ContentDismissActionType.USER_DISMISS);
},
renderImgComponent: () => <CoachmarkImg />
}), [r25, r11]));
return r25;
};
@@ -0,0 +1,8 @@
// Metro module 9940 (f9941).
import { useEffect } from "react";
import { fetchAndUpdateSavedMessages } from "./SavedMessagesActions";
export default function useRefreshSavedMessages() {
useEffect(() => {
fetchAndUpdateSavedMessages();
}, []);
};
@@ -0,0 +1,64 @@
// Metro module 9939 (f9940).
import { useState, useRef, useEffect } from "react";
import SavedMessagesStore from "./SavedMessagesStore";
import { SavedMessageSortTypes } from "./SavedMessagesTypes";
import useRefreshSavedMessages from "./useRefreshSavedMessages";
import { useStateFromStoresArray } from "../../_bundle/Module589";
import { isNotNullish } from "../../utils/GlobalUtils";
function $mk83579() {
return (a0) => a0.saveData;
}
const getSavedMessagesForType = function getSavedMessagesForType(a0) {
if (SavedMessageSortTypes.BOOKMARK === a0) {
return SavedMessagesStore.getMessageBookmarks();
}
if (SavedMessageSortTypes.REMINDER === a0) {
return SavedMessagesStore.getMessageReminders();
}
return SavedMessagesStore.getSavedMessages();
};
export default function useSavedMessagesForPage(r3 = SavedMessageSortTypes.ALL) {
let state, setState, ref;
const ALL = r3;
state = void 0;
setState = void 0;
ref = void 0;
[state, setState] = useState(() => (SavedMessageSortTypes.BOOKMARK === ALL ? SavedMessagesStore.getMessageBookmarks() : SavedMessageSortTypes.REMINDER === ALL ? SavedMessagesStore.getMessageReminders() : SavedMessagesStore.getSavedMessages()).map($mk83579()));
ref = useRef(SavedMessagesStore.getIsStale());
useEffect(() => {
let lastChanged;
const handleChange2 = function handleChange() {
const lastChanged2 = SavedMessagesStore.getLastChanged();
if (lastChanged !== lastChanged2) {
lastChanged = lastChanged2;
if (ref.current && !SavedMessagesStore.getIsStale()) {
ref.current = false;
setState((SavedMessageSortTypes.BOOKMARK === ALL ? SavedMessagesStore.getMessageBookmarks() : SavedMessageSortTypes.REMINDER === ALL ? SavedMessagesStore.getMessageReminders() : SavedMessagesStore.getSavedMessages()).map($mk83579()));
return void 0;
}
setState((prevState) => {
const r0 = [...prevState];
const map = new Map(getSavedMessagesForType(ALL).map((item) => [item.saveData.messageId, item]));
for (const item of prevState) {
if (map.has(item.messageId)) {
map.delete(item.messageId);
} else {
r0.splice(r0.indexOf(item), 1);
}
}
for (const item2 of map.values()) {
r0.push(item2.saveData);
}
return r0;
});
}
};
lastChanged = SavedMessagesStore.getLastChanged();
SavedMessagesStore.addChangeListener(handleChange2);
return () => {
SavedMessagesStore.removeChangeListener(handleChange2);
};
}, [ALL]);
useRefreshSavedMessages();
return useStateFromStoresArray([SavedMessagesStore], () => state.map((item) => SavedMessagesStore.getSavedMessage(item.channelId, item.messageId)).filter(isNotNullish));
};