]> Untitled Git - lemmy-ui.git/blobdiff - src/shared/utils.ts
Merge branch 'LemmyNet:main' into multiple-images-upload
[lemmy-ui.git] / src / shared / utils.ts
index 3354fcc5d1bf5698626c9d2e2c10bf813d6aa2ce..d0b9b4bf6de888d1802a9271aef856c0d6f870ad 100644 (file)
@@ -1,4 +1,4 @@
-import { None, Option, Result, Some } from "@sniptt/monads";
+import { Err, None, Ok, Option, Result, Some } from "@sniptt/monads";
 import { ClassConstructor, deserialize, serialize } from "class-transformer";
 import emojiShortName from "emoji-short-name";
 import {
@@ -23,6 +23,7 @@ import {
   PersonViewSafe,
   PostReportView,
   PostView,
+  PrivateMessageReportView,
   PrivateMessageView,
   RegistrationApplicationView,
   Search,
@@ -69,7 +70,7 @@ export const webArchiveUrl = "https://web.archive.org";
 export const elementUrl = "https://element.io";
 
 export const postRefetchSeconds: number = 60 * 1000;
-export const fetchLimit = 20;
+export const fetchLimit = 40;
 export const trendingFetchLimit = 6;
 export const mentionDropdownFetchLimit = 10;
 export const commentTreeMaxDepth = 8;
@@ -246,14 +247,10 @@ export function isAdmin(
   });
 }
 
-export function amAdmin(
-  admins: Option<PersonViewSafe[]>,
-  myUserInfo = UserService.Instance.myUserInfo
-): boolean {
-  return myUserInfo.match({
-    some: mui => isAdmin(admins, mui.local_user_view.person.id),
-    none: false,
-  });
+export function amAdmin(myUserInfo = UserService.Instance.myUserInfo): boolean {
+  return myUserInfo
+    .map(mui => mui.local_user_view.person.admin)
+    .unwrapOr(false);
 }
 
 export function amCommunityCreator(
@@ -418,7 +415,7 @@ export function getLanguages(
   myUserInfo = UserService.Instance.myUserInfo
 ): string[] {
   let myLang = myUserInfo
-    .map(m => m.local_user_view.local_user.lang)
+    .map(m => m.local_user_view.local_user.interface_language)
     .unwrapOr("browser");
   let lang = override || myLang;
 
@@ -543,6 +540,7 @@ export function toast(text: string, background = "success") {
 export function pictrsDeleteToast(
   clickToDeleteText: string,
   deletePictureText: string,
+  failedDeletePictureText: string,
   deleteUrl: string
 ) {
   if (isBrowser()) {
@@ -555,9 +553,16 @@ export function pictrsDeleteToast(
       duration: 10000,
       onClick: () => {
         if (toast) {
-          window.location.replace(deleteUrl);
-          alert(deletePictureText);
-          toast.hideToast();
+          fetch(deleteUrl, {})
+          .then( res => {
+            console.log(res)
+            toast.hideToast();
+            if (res.ok === true){
+              alert(deletePictureText);
+            } else{
+              alert(failedDeletePictureText);
+            }
+          })
         }
       },
       close: true,
@@ -630,21 +635,18 @@ export function notifyPrivateMessage(pmv: PrivateMessageView, router: any) {
 function notify(info: NotifyInfo, router: any) {
   messageToastify(info, router);
 
-  // TODO absolute nightmare bug, but notifs are currently broken.
-  // Notification.new will try to do a browser fetch ???
-
-  // if (Notification.permission !== "granted") Notification.requestPermission();
-  // else {
-  //   var notification = new Notification(info.name, {
-  //     icon: info.icon,
-  //     body: info.body,
-  //   });
+  if (Notification.permission !== "granted") Notification.requestPermission();
+  else {
+    var notification = new Notification(info.name, {
+      ...{ body: info.body },
+      ...(info.icon.isSome() && { icon: info.icon.unwrap() }),
+    });
 
-  //   notification.onclick = (ev: Event): any => {
-  //     ev.preventDefault();
-  //     router.history.push(info.link);
-  //   };
-  // }
+    notification.onclick = (ev: Event): any => {
+      ev.preventDefault();
+      router.history.push(info.link);
+    };
+  }
 }
 
 export function setupTribute() {
@@ -951,6 +953,7 @@ export function editPostRes(data: PostView, post: PostView) {
   }
 }
 
+// TODO possible to make these generic?
 export function updatePostReportRes(
   data: PostReportView,
   reports: PostReportView[]
@@ -971,6 +974,18 @@ export function updateCommentReportRes(
   }
 }
 
+export function updatePrivateMessageReportRes(
+  data: PrivateMessageReportView,
+  reports: PrivateMessageReportView[]
+) {
+  let found = reports.find(
+    c => c.private_message_report.id == data.private_message_report.id
+  );
+  if (found) {
+    found.private_message_report = data.private_message_report;
+  }
+}
+
 export function updateRegistrationApplicationRes(
   data: RegistrationApplicationView,
   applications: RegistrationApplicationView[]
@@ -1271,7 +1286,7 @@ export function showLocal(isoData: IsoData): boolean {
     .unwrapOr(false);
 }
 
-interface ChoicesValue {
+export interface ChoicesValue {
   value: string;
   label: string;
 }
@@ -1330,13 +1345,14 @@ export const choicesConfig = {
   shouldSort: false,
   searchResultLimit: fetchLimit,
   classNames: {
-    containerOuter: "choices",
-    containerInner: "choices__inner bg-secondary border-0",
+    containerOuter: "choices custom-select px-0",
+    containerInner:
+      "choices__inner bg-secondary border-0 py-0 modlog-choices-font-size",
     input: "form-control",
     inputCloned: "choices__input--cloned",
     list: "choices__list",
     listItems: "choices__list--multiple",
-    listSingle: "choices__list--single",
+    listSingle: "choices__list--single py-0",
     listDropdown: "choices__list--dropdown",
     item: "choices__item bg-secondary",
     itemSelectable: "choices__item--selectable",
@@ -1430,3 +1446,62 @@ export function postToCommentSortType(sort: SortType): CommentSortType {
     return CommentSortType.Top;
   }
 }
+
+export function arrayGet<T>(arr: Array<T>, index: number): Result<T, string> {
+  let out = arr.at(index);
+  if (out == undefined) {
+    return Err("Index undefined");
+  } else {
+    return Ok(out);
+  }
+}
+
+export function myFirstDiscussionLanguageId(
+  myUserInfo = UserService.Instance.myUserInfo
+): Option<number> {
+  return myUserInfo.andThen(mui =>
+    arrayGet(mui.discussion_languages, 0)
+      .ok()
+      .map(i => i.id)
+  );
+}
+
+export function canCreateCommunity(
+  siteRes: GetSiteResponse,
+  myUserInfo = UserService.Instance.myUserInfo
+): boolean {
+  let adminOnly = siteRes.site_view
+    .map(s => s.site.community_creation_admin_only)
+    .unwrapOr(false);
+  return !adminOnly || amAdmin(myUserInfo);
+}
+
+export function isPostBlocked(
+  pv: PostView,
+  myUserInfo = UserService.Instance.myUserInfo
+): boolean {
+  return myUserInfo
+    .map(
+      mui =>
+        mui.community_blocks
+          .map(c => c.community.id)
+          .includes(pv.community.id) ||
+        mui.person_blocks.map(p => p.target.id).includes(pv.creator.id)
+    )
+    .unwrapOr(false);
+}
+
+/// Checks to make sure you can view NSFW posts. Returns true if you can.
+export function nsfwCheck(
+  pv: PostView,
+  myUserInfo = UserService.Instance.myUserInfo
+): boolean {
+  let nsfw = pv.post.nsfw || pv.community.nsfw;
+  return (
+    !nsfw ||
+    (nsfw &&
+      myUserInfo
+        .map(m => m.local_user_view.local_user.show_nsfw)
+        .unwrapOr(false))
+  );
+}