]> Untitled Git - lemmy.git/blobdiff - ui/src/utils.ts
routes.api: fix get_captcha endpoint (#1135)
[lemmy.git] / ui / src / utils.ts
index 5e0ec47d456e7f59d95c8d30121e1c749d2dc00b..a312a663c5ced1fc8e59d5420502a2c5be65330d 100644 (file)
@@ -25,6 +25,7 @@ import 'moment/locale/sq';
 import 'moment/locale/km';
 import 'moment/locale/ga';
 import 'moment/locale/sr';
+import 'moment/locale/ko';
 
 import {
   UserOperation,
@@ -34,9 +35,7 @@ import {
   PrivateMessage,
   User,
   SortType,
-  CommentSortType,
   ListingType,
-  DataType,
   SearchType,
   WebSocketResponse,
   WebSocketJsonResponse,
@@ -44,7 +43,9 @@ import {
   SearchResponse,
   CommentResponse,
   PostResponse,
-} from './interfaces';
+} from 'lemmy-js-client';
+
+import { CommentSortType, DataType } from './interfaces';
 import { UserService, WebSocketService } from './services';
 
 import Tribute from 'tributejs/src/Tribute.js';
@@ -59,6 +60,8 @@ import tippy from 'tippy.js';
 import moment from 'moment';
 
 export const favIconUrl = '/static/assets/favicon.svg';
+export const favIconPngUrl = '/static/assets/apple-touch-icon.png';
+export const defaultFavIcon = `${window.location.protocol}//${window.location.host}${favIconPngUrl}`;
 export const repoUrl = 'https://github.com/LemmyNet/lemmy';
 export const helpGuideUrl = '/docs/about_guide.html';
 export const markdownHelpUrl = `${helpGuideUrl}#markdown-guide`;
@@ -82,6 +85,7 @@ export const languages = [
   { code: 'gl', name: 'Galego' },
   { code: 'hu', name: 'Magyar Nyelv' },
   { code: 'ka', name: 'ქართული ენა' },
+  { code: 'ko', name: '한국어' },
   { code: 'km', name: 'ភាសាខ្មែរ' },
   { code: 'hi', name: 'मानक हिन्दी' },
   { code: 'fa', name: 'فارسی' },
@@ -271,27 +275,11 @@ export function capitalizeFirstLetter(str: string): string {
 }
 
 export function routeSortTypeToEnum(sort: string): SortType {
-  if (sort == 'new') {
-    return SortType.New;
-  } else if (sort == 'hot') {
-    return SortType.Hot;
-  } else if (sort == 'active') {
-    return SortType.Active;
-  } else if (sort == 'topday') {
-    return SortType.TopDay;
-  } else if (sort == 'topweek') {
-    return SortType.TopWeek;
-  } else if (sort == 'topmonth') {
-    return SortType.TopMonth;
-  } else if (sort == 'topyear') {
-    return SortType.TopYear;
-  } else if (sort == 'topall') {
-    return SortType.TopAll;
-  }
+  return SortType[sort];
 }
 
 export function routeListingTypeToEnum(type: string): ListingType {
-  return ListingType[capitalizeFirstLetter(type)];
+  return ListingType[type];
 }
 
 export function routeDataTypeToEnum(type: string): DataType {
@@ -425,6 +413,8 @@ export function getMomentLanguage(): string {
     lang = 'ga';
   } else if (lang.startsWith('sr')) {
     lang = 'sr';
+  } else if (lang.startsWith('ko')) {
+    lang = 'ko';
   } else {
     lang = 'en';
   }
@@ -526,8 +516,19 @@ export function pictrsImage(hash: string, thumbnail: boolean = false): string {
   return out;
 }
 
-export function isCommentType(item: Comment | PrivateMessage): item is Comment {
-  return (item as Comment).community_id !== undefined;
+export function isCommentType(
+  item: Comment | PrivateMessage | Post
+): item is Comment {
+  return (
+    (item as Comment).community_id !== undefined &&
+    (item as Comment).content !== undefined
+  );
+}
+
+export function isPostType(
+  item: Comment | PrivateMessage | Post
+): item is Post {
+  return (item as Post).stickied !== undefined;
 }
 
 export function toast(text: string, background: string = 'success') {
@@ -563,18 +564,20 @@ export function pictrsDeleteToast(
   }).showToast();
 }
 
-export function messageToastify(
-  creator: string,
-  avatar: string,
-  body: string,
-  link: string,
-  router: any
-) {
+interface NotifyInfo {
+  name: string;
+  icon: string;
+  link: string;
+  body: string;
+}
+
+export function messageToastify(info: NotifyInfo, router: any) {
+  let htmlBody = info.body ? md.render(info.body) : '';
   let backgroundColor = `var(--light)`;
 
   let toast = Toastify({
-    text: `${body}<br />${creator}`,
-    avatar: avatar,
+    text: `${htmlBody}<br />${info.name}`,
+    avatar: info.icon,
     backgroundColor: backgroundColor,
     className: 'text-dark',
     close: true,
@@ -584,12 +587,59 @@ export function messageToastify(
     onClick: () => {
       if (toast) {
         toast.hideToast();
-        router.history.push(link);
+        router.history.push(info.link);
       }
     },
   }).showToast();
 }
 
+export function notifyPost(post: Post, router: any) {
+  let info: NotifyInfo = {
+    name: post.community_name,
+    icon: post.community_icon ? post.community_icon : defaultFavIcon,
+    link: `/post/${post.id}`,
+    body: post.name,
+  };
+  notify(info, router);
+}
+
+export function notifyComment(comment: Comment, router: any) {
+  let info: NotifyInfo = {
+    name: comment.creator_name,
+    icon: comment.creator_avatar ? comment.creator_avatar : defaultFavIcon,
+    link: `/post/${comment.post_id}/comment/${comment.id}`,
+    body: comment.content,
+  };
+  notify(info, router);
+}
+
+export function notifyPrivateMessage(pm: PrivateMessage, router: any) {
+  let info: NotifyInfo = {
+    name: pm.creator_name,
+    icon: pm.creator_avatar ? pm.creator_avatar : defaultFavIcon,
+    link: `/inbox`,
+    body: pm.content,
+  };
+  notify(info, router);
+}
+
+function notify(info: NotifyInfo, router: any) {
+  messageToastify(info, router);
+
+  if (Notification.permission !== 'granted') Notification.requestPermission();
+  else {
+    var notification = new Notification(info.name, {
+      icon: info.icon,
+      body: info.body,
+    });
+
+    notification.onclick = () => {
+      event.preventDefault();
+      router.history.push(info.link);
+    };
+  }
+}
+
 export function setupTribute(): Tribute {
   return new Tribute({
     noMatchTemplate: function () {
@@ -668,8 +718,8 @@ function userSearch(text: string, cb: any) {
   if (text) {
     let form: SearchForm = {
       q: text,
-      type_: SearchType[SearchType.Users],
-      sort: SortType[SortType.TopAll],
+      type_: SearchType.Users,
+      sort: SortType.TopAll,
       page: 1,
       limit: mentionDropdownFetchLimit,
     };
@@ -705,8 +755,8 @@ function communitySearch(text: string, cb: any) {
   if (text) {
     let form: SearchForm = {
       q: text,
-      type_: SearchType[SearchType.Communities],
-      sort: SortType[SortType.TopAll],
+      type_: SearchType.Communities,
+      sort: SortType.TopAll,
       page: 1,
       limit: mentionDropdownFetchLimit,
     };
@@ -742,7 +792,7 @@ export function getListingTypeFromProps(props: any): ListingType {
   return props.match.params.listing_type
     ? routeListingTypeToEnum(props.match.params.listing_type)
     : UserService.Instance.user
-    ? UserService.Instance.user.default_listing_type
+    ? Object.values(ListingType)[UserService.Instance.user.default_listing_type]
     : ListingType.All;
 }
 
@@ -757,7 +807,7 @@ export function getSortTypeFromProps(props: any): SortType {
   return props.match.params.sort
     ? routeSortTypeToEnum(props.match.params.sort)
     : UserService.Instance.user
-    ? UserService.Instance.user.default_sort_type
+    ? Object.values(SortType)[UserService.Instance.user.default_sort_type]
     : SortType.Active;
 }
 
@@ -980,12 +1030,17 @@ function randomHsl() {
   return `hsla(${Math.random() * 360}, 100%, 50%, 1)`;
 }
 
-export function previewLines(text: string, lines: number = 3): string {
-  // Use lines * 2 because markdown requires 2 lines
+export function previewLines(
+  text: string,
+  maxChars: number = 300,
+  maxLines: number = 1
+): string {
   return (
     text
+      .slice(0, maxChars)
       .split('\n')
-      .slice(0, lines * 2)
+      // Use lines * 2 because markdown requires 2 lines
+      .slice(0, maxLines * 2)
       .join('\n') + '...'
   );
 }