constructor(props: any, context: any) {
super(props, context);
this.state = this.emptyState;
- this.parseMessage = this.parseMessage.bind(this);
+ this.parseMessage = this.parseMessage.bind(this);
this.subscription = wsSubscribe(this.parseMessage);
// Only fetch the data if coming from another route
if (this.isoData.path == this.context.router.route.match.url) {
this.state.communities = this.isoData.routeData[0].communities;
+ this.state.communities.sort(
+ (a, b) => b.number_of_subscribers - a.number_of_subscribers
+ );
this.state.loading = false;
} else {
this.refetch();
CommunityForm as CommunityFormI,
UserOperation,
Category,
- ListCategoriesResponse,
CommunityResponse,
WebSocketJsonResponse,
Community,
interface CommunityFormProps {
community?: Community; // If a community is given, that means this is an edit
+ categories: Category[];
onCancel?(): any;
onCreate?(community: Community): any;
onEdit?(community: Community): any;
interface CommunityFormState {
communityForm: CommunityFormI;
- categories: Category[];
loading: boolean;
}
communityForm: {
name: null,
title: null,
- category_id: null,
+ category_id: this.props.categories[0].id,
nsfw: false,
icon: null,
banner: null,
},
- categories: [],
loading: false,
};
err => console.error(err),
() => console.log('complete')
);
-
- WebSocketService.Instance.listCategories();
}
componentDidUpdate() {
value={this.state.communityForm.category_id}
onInput={linkEvent(this, this.handleCommunityCategoryChange)}
>
- {this.state.categories.map(category => (
+ {this.props.categories.map(category => (
<option value={category.id}>{category.name}</option>
))}
</select>
this.state.loading = false;
this.setState(this.state);
return;
- } else if (res.op == UserOperation.ListCategories) {
- let data = res.data as ListCategoriesResponse;
- this.state.categories = data.categories;
- if (!this.props.community) {
- this.state.communityForm.category_id = data.categories[0].id;
- }
- this.setState(this.state);
} else if (res.op == UserOperation.CreateCommunity) {
let data = res.data as CommunityResponse;
this.state.loading = false;
import { Component } from 'inferno';
import { Helmet } from 'inferno-helmet';
import { Subscription } from 'rxjs';
-import { retryWhen, delay, take } from 'rxjs/operators';
import { CommunityForm } from './community-form';
import {
Community,
UserOperation,
WebSocketJsonResponse,
- GetSiteResponse,
Site,
+ ListCategoriesResponse,
+ Category,
} from 'lemmy-js-client';
-import { toast, wsJsonToRes } from '../utils';
+import {
+ setIsoData,
+ toast,
+ wsJsonToRes,
+ wsSubscribe,
+ isBrowser,
+ lemmyHttp,
+} from '../utils';
import { WebSocketService, UserService } from '../services';
import { i18n } from '../i18next';
interface CreateCommunityState {
site: Site;
+ categories: Category[];
+ loading: boolean;
}
export class CreateCommunity extends Component<any, CreateCommunityState> {
+ private isoData = setIsoData(this.context);
private subscription: Subscription;
private emptyState: CreateCommunityState = {
- site: {
- id: undefined,
- name: undefined,
- creator_id: undefined,
- published: undefined,
- creator_name: undefined,
- number_of_users: undefined,
- number_of_posts: undefined,
- number_of_comments: undefined,
- number_of_communities: undefined,
- enable_downvotes: undefined,
- open_registration: undefined,
- enable_nsfw: undefined,
- },
+ site: this.isoData.site.site,
+ categories: [],
+ loading: true,
};
constructor(props: any, context: any) {
super(props, context);
this.handleCommunityCreate = this.handleCommunityCreate.bind(this);
this.state = this.emptyState;
+ this.parseMessage = this.parseMessage.bind(this);
+ this.subscription = wsSubscribe(this.parseMessage);
+
+ // TODO not sure if this works
if (!UserService.Instance.user) {
toast(i18n.t('not_logged_in'), 'danger');
this.context.router.history.push(`/login`);
}
- this.subscription = WebSocketService.Instance.subject
- .pipe(retryWhen(errors => errors.pipe(delay(3000), take(10))))
- .subscribe(
- msg => this.parseMessage(msg),
- err => console.error(err),
- () => console.log('complete')
- );
-
- WebSocketService.Instance.getSite();
+ // Only fetch the data if coming from another route
+ if (this.isoData.path == this.context.router.route.match.url) {
+ this.state.categories = this.isoData.routeData[0].categories;
+ this.state.loading = false;
+ } else {
+ WebSocketService.Instance.listCategories();
+ }
}
componentWillUnmount() {
- this.subscription.unsubscribe();
+ if (isBrowser()) {
+ this.subscription.unsubscribe();
+ }
}
get documentTitle(): string {
- if (this.state.site.name) {
- return `${i18n.t('create_community')} - ${this.state.site.name}`;
- } else {
- return 'Lemmy';
- }
+ return `${i18n.t('create_community')} - ${this.state.site.name}`;
}
render() {
return (
<div class="container">
<Helmet title={this.documentTitle} />
- <div class="row">
- <div class="col-12 col-lg-6 offset-lg-3 mb-4">
- <h5>{i18n.t('create_community')}</h5>
- <CommunityForm
- onCreate={this.handleCommunityCreate}
- enableNsfw={this.state.site.enable_nsfw}
- />
+ {this.state.loading ? (
+ <h5>
+ <svg class="icon icon-spinner spin">
+ <use xlinkHref="#icon-spinner"></use>
+ </svg>
+ </h5>
+ ) : (
+ <div class="row">
+ <div class="col-12 col-lg-6 offset-lg-3 mb-4">
+ <h5>{i18n.t('create_community')}</h5>
+ <CommunityForm
+ categories={this.state.categories}
+ onCreate={this.handleCommunityCreate}
+ enableNsfw={this.state.site.enable_nsfw}
+ />
+ </div>
</div>
- </div>
+ )}
</div>
);
}
this.props.history.push(`/c/${community.name}`);
}
+ static fetchInitialData(_auth: string, _path: string): Promise<any>[] {
+ return [lemmyHttp.listCategories()];
+ }
+
parseMessage(msg: WebSocketJsonResponse) {
console.log(msg);
let res = wsJsonToRes(msg);
if (msg.error) {
// Toast errors are already handled by community-form
return;
- } else if (res.op == UserOperation.GetSite) {
- let data = res.data as GetSiteResponse;
- this.state.site = data.site;
+ } else if (res.op == UserOperation.ListCategories) {
+ let data = res.data as ListCategoriesResponse;
+ this.state.categories = data.categories;
+ this.state.loading = false;
this.setState(this.state);
}
}
import { Component } from 'inferno';
import { Helmet } from 'inferno-helmet';
import { Subscription } from 'rxjs';
-import { retryWhen, delay, take } from 'rxjs/operators';
import { PostForm } from './post-form';
-import { toast, wsJsonToRes } from '../utils';
-import { WebSocketService, UserService } from '../services';
+import {
+ lemmyHttp,
+ setAuth,
+ setIsoData,
+ toast,
+ wsJsonToRes,
+ wsSubscribe,
+} from '../utils';
+import { UserService, WebSocketService } from '../services';
import {
UserOperation,
PostFormParams,
WebSocketJsonResponse,
- GetSiteResponse,
+ ListCommunitiesResponse,
+ Community,
Site,
+ ListCommunitiesForm,
+ SortType,
} from 'lemmy-js-client';
import { i18n } from '../i18next';
interface CreatePostState {
site: Site;
+ communities: Community[];
+ loading: boolean;
}
export class CreatePost extends Component<any, CreatePostState> {
+ private isoData = setIsoData(this.context);
private subscription: Subscription;
private emptyState: CreatePostState = {
- site: {
- id: undefined,
- name: undefined,
- creator_id: undefined,
- published: undefined,
- creator_name: undefined,
- number_of_users: undefined,
- number_of_posts: undefined,
- number_of_comments: undefined,
- number_of_communities: undefined,
- enable_downvotes: undefined,
- open_registration: undefined,
- enable_nsfw: undefined,
- },
+ site: this.isoData.site.site,
+ communities: [],
+ loading: true,
};
constructor(props: any, context: any) {
this.context.router.history.push(`/login`);
}
- this.subscription = WebSocketService.Instance.subject
- .pipe(retryWhen(errors => errors.pipe(delay(3000), take(10))))
- .subscribe(
- msg => this.parseMessage(msg),
- err => console.error(err),
- () => console.log('complete')
- );
+ this.parseMessage = this.parseMessage.bind(this);
+ this.subscription = wsSubscribe(this.parseMessage);
+
+ // Only fetch the data if coming from another route
+ if (this.isoData.path == this.context.router.route.match.url) {
+ this.state.communities = this.isoData.routeData[0].communities;
+ this.state.loading = false;
+ } else {
+ this.refetch();
+ }
+ }
- WebSocketService.Instance.getSite();
+ refetch() {
+ let listCommunitiesForm: ListCommunitiesForm = {
+ sort: SortType.TopAll,
+ limit: 9999,
+ };
+ WebSocketService.Instance.listCommunities(listCommunitiesForm);
}
componentWillUnmount() {
}
get documentTitle(): string {
- if (this.state.site.name) {
- return `${i18n.t('create_post')} - ${this.state.site.name}`;
- } else {
- return 'Lemmy';
- }
+ return `${i18n.t('create_post')} - ${this.state.site.name}`;
}
render() {
return (
<div class="container">
<Helmet title={this.documentTitle} />
- <div class="row">
- <div class="col-12 col-lg-6 offset-lg-3 mb-4">
- <h5>{i18n.t('create_post')}</h5>
- <PostForm
- onCreate={this.handlePostCreate}
- params={this.params}
- enableDownvotes={this.state.site.enable_downvotes}
- enableNsfw={this.state.site.enable_nsfw}
- />
+ {this.state.loading ? (
+ <h5>
+ <svg class="icon icon-spinner spin">
+ <use xlinkHref="#icon-spinner"></use>
+ </svg>
+ </h5>
+ ) : (
+ <div class="row">
+ <div class="col-12 col-lg-6 offset-lg-3 mb-4">
+ <h5>{i18n.t('create_post')}</h5>
+ <PostForm
+ communities={this.state.communities}
+ onCreate={this.handlePostCreate}
+ params={this.params}
+ enableDownvotes={this.state.site.enable_downvotes}
+ enableNsfw={this.state.site.enable_nsfw}
+ />
+ </div>
</div>
- </div>
+ )}
</div>
);
}
return lastLocation.split('/c/')[1];
}
}
- return;
+ return null;
}
handlePostCreate(id: number) {
this.props.history.push(`/post/${id}`);
}
+ static fetchInitialData(auth: string, _path: string): Promise<any>[] {
+ let listCommunitiesForm: ListCommunitiesForm = {
+ sort: SortType.TopAll,
+ limit: 9999,
+ };
+ setAuth(listCommunitiesForm, auth);
+ return [lemmyHttp.listCommunities(listCommunitiesForm)];
+ }
+
parseMessage(msg: WebSocketJsonResponse) {
console.log(msg);
let res = wsJsonToRes(msg);
if (msg.error) {
toast(i18n.t(msg.error), 'danger');
return;
- } else if (res.op == UserOperation.GetSite) {
- let data = res.data as GetSiteResponse;
- this.state.site = data.site;
+ } else if (res.op == UserOperation.ListCommunities) {
+ let data = res.data as ListCommunitiesResponse;
+ this.state.communities = data.communities;
+ this.state.loading = false;
this.setState(this.state);
}
}
import { Component } from 'inferno';
import { Helmet } from 'inferno-helmet';
-import { Subscription } from 'rxjs';
-import { retryWhen, delay, take } from 'rxjs/operators';
-import {
- UserOperation,
- WebSocketJsonResponse,
- GetSiteResponse,
-} from 'lemmy-js-client';
-import { WebSocketService } from '../services';
-import { wsJsonToRes, toast, isBrowser } from '../utils';
+import { GetSiteResponse } from 'lemmy-js-client';
+import { setIsoData } from '../utils';
import { i18n } from '../i18next';
interface InstancesState {
- loading: boolean;
siteRes: GetSiteResponse;
}
export class Instances extends Component<any, InstancesState> {
- private subscription: Subscription;
+ private isoData = setIsoData(this.context);
private emptyState: InstancesState = {
- loading: true,
- siteRes: undefined,
+ siteRes: this.isoData.site,
};
constructor(props: any, context: any) {
super(props, context);
this.state = this.emptyState;
-
- if (isBrowser()) {
- this.subscription = WebSocketService.Instance.subject
- .pipe(retryWhen(errors => errors.pipe(delay(3000), take(10))))
- .subscribe(
- msg => this.parseMessage(msg),
- err => console.error(err),
- () => console.log('complete')
- );
-
- WebSocketService.Instance.getSite();
- }
- }
-
- componentWillUnmount() {
- this.subscription.unsubscribe();
}
get documentTitle(): string {
- if (this.state.siteRes) {
- return `${i18n.t('instances')} - ${this.state.siteRes.site.name}`;
- } else {
- return 'Lemmy';
- }
+ return `${i18n.t('instances')} - ${this.state.siteRes.site.name}`;
}
render() {
return (
<div class="container">
<Helmet title={this.documentTitle} />
- {this.state.loading ? (
- <h5 class="">
- <svg class="icon icon-spinner spin">
- <use xlinkHref="#icon-spinner"></use>
- </svg>
- </h5>
- ) : (
- <div>
- <h5>{i18n.t('linked_instances')}</h5>
- {this.state.siteRes &&
- this.state.siteRes.federated_instances.length ? (
- <ul>
- {this.state.siteRes.federated_instances.map(i => (
- <li>
- <a href={`https://${i}`} target="_blank" rel="noopener">
- {i}
- </a>
- </li>
- ))}
- </ul>
- ) : (
- <div>{i18n.t('none_found')}</div>
- )}
- </div>
- )}
+ <div>
+ <h5>{i18n.t('linked_instances')}</h5>
+ {this.state.siteRes &&
+ this.state.siteRes.federated_instances.length ? (
+ <ul>
+ {this.state.siteRes.federated_instances.map(i => (
+ <li>
+ <a href={`https://${i}`} target="_blank" rel="noopener">
+ {i}
+ </a>
+ </li>
+ ))}
+ </ul>
+ ) : (
+ <div>{i18n.t('none_found')}</div>
+ )}
+ </div>
</div>
);
}
-
- parseMessage(msg: WebSocketJsonResponse) {
- console.log(msg);
- let res = wsJsonToRes(msg);
- if (msg.error) {
- toast(i18n.t(msg.error), 'danger');
- return;
- } else if (res.op == UserOperation.GetSite) {
- let data = res.data as GetSiteResponse;
- this.state.siteRes = data;
- this.state.loading = false;
- this.setState(this.state);
- }
- }
}
setupTribute,
pictrsDeleteToast,
setupTippy,
+ isBrowser,
} from '../utils';
import { UserService } from '../services';
import autosize from 'autosize';
-import Tribute from 'tributejs/src/Tribute.js';
import { i18n } from '../i18next';
interface MarkdownTextAreaProps {
> {
private id = `comment-textarea-${randomStr()}`;
private formId = `comment-form-${randomStr()}`;
- private tribute: Tribute;
+ private tribute: any;
private emptyState: MarkdownTextAreaState = {
content: this.props.initialContent,
previewMode: false,
constructor(props: any, context: any) {
super(props, context);
- // TODO
- /* this.tribute = setupTribute(); */
+ if (isBrowser()) {
+ this.tribute = setupTribute();
+ }
this.state = this.emptyState;
}
import { PostListings } from './post-listings';
import { MarkdownTextArea } from './markdown-textarea';
import { Subscription } from 'rxjs';
-import { retryWhen, delay, take } from 'rxjs/operators';
import {
PostForm as PostFormI,
PostFormParams,
PostResponse,
UserOperation,
Community,
- ListCommunitiesResponse,
- ListCommunitiesForm,
SortType,
SearchForm,
SearchType,
hostname,
pictrsDeleteToast,
validTitle,
+ wsSubscribe,
+ isBrowser,
} from '../utils';
-import Choices from 'choices.js';
+
+var Choices;
+if (isBrowser()) {
+ Choices = require('choices.js');
+}
+
import { i18n } from '../i18next';
const MAX_POST_TITLE_LENGTH = 200;
interface PostFormProps {
post?: Post; // If a post is given, that means this is an edit
+ communities: Community[];
params?: PostFormParams;
onCancel?(): any;
onCreate?(id: number): any;
interface PostFormState {
postForm: PostFormI;
- communities: Community[];
loading: boolean;
imageLoading: boolean;
previewMode: boolean;
export class PostForm extends Component<PostFormProps, PostFormState> {
private id = `post-form-${randomStr()}`;
private subscription: Subscription;
- private choices: Choices;
+ private choices: any;
private emptyState: PostFormState = {
postForm: {
name: null,
auth: null,
community_id: null,
},
- communities: [],
loading: false,
imageLoading: false,
previewMode: false,
}
}
- this.subscription = WebSocketService.Instance.subject
- .pipe(retryWhen(errors => errors.pipe(delay(3000), take(10))))
- .subscribe(
- msg => this.parseMessage(msg),
- err => console.error(err),
- () => console.log('complete')
- );
-
- let listCommunitiesForm: ListCommunitiesForm = {
- sort: SortType.TopAll,
- limit: 9999,
- };
-
- WebSocketService.Instance.listCommunities(listCommunitiesForm);
+ this.subscription = wsSubscribe(this.parseMessage);
}
componentDidMount() {
setupTippy();
+ this.setupCommunities();
}
componentDidUpdate() {
onChange={linkEvent(this, this.handleImageUpload)}
/>
</form>
- {validURL(this.state.postForm.url) && (
+ {this.state.postForm.url && validURL(this.state.postForm.url) && (
<a
href={`${archiveUrl}/?run=1&url=${encodeURIComponent(
this.state.postForm.url
onInput={linkEvent(this, this.handlePostCommunityChange)}
>
<option>{i18n.t('select_a_community')}</option>
- {this.state.communities.map(community => (
+ {this.props.communities.map(community => (
<option value={community.id}>
{community.local
? community.name
});
}
- parseMessage(msg: WebSocketJsonResponse) {
- let res = wsJsonToRes(msg);
- if (msg.error) {
- toast(i18n.t(msg.error), 'danger');
- this.state.loading = false;
- this.setState(this.state);
- return;
- } else if (res.op == UserOperation.ListCommunities) {
- let data = res.data as ListCommunitiesResponse;
- this.state.communities = data.communities;
- if (this.props.post) {
- this.state.postForm.community_id = this.props.post.community_id;
- } else if (this.props.params && this.props.params.community) {
- let foundCommunityId = data.communities.find(
- r => r.name == this.props.params.community
- ).id;
- this.state.postForm.community_id = foundCommunityId;
- } else {
- // By default, the null valued 'Select a Community'
- }
- this.setState(this.state);
+ setupCommunities() {
+ if (this.props.post) {
+ this.state.postForm.community_id = this.props.post.community_id;
+ } else if (this.props.params && this.props.params.community) {
+ let foundCommunityId = this.props.communities.find(
+ r => r.name == this.props.params.community
+ ).id;
+ this.state.postForm.community_id = foundCommunityId;
+ } else {
+ // By default, the null valued 'Select a Community'
+ }
- // Set up select searching
+ // Set up select searching
+ if (isBrowser()) {
let selectId: any = document.getElementById('post-community');
if (selectId) {
- // TODO
- /* this.choices = new Choices(selectId, { */
- /* shouldSort: false, */
- /* classNames: { */
- /* containerOuter: 'choices', */
- /* containerInner: 'choices__inner bg-secondary border-0', */
- /* input: 'form-control', */
- /* inputCloned: 'choices__input--cloned', */
- /* list: 'choices__list', */
- /* listItems: 'choices__list--multiple', */
- /* listSingle: 'choices__list--single', */
- /* listDropdown: 'choices__list--dropdown', */
- /* item: 'choices__item bg-secondary', */
- /* itemSelectable: 'choices__item--selectable', */
- /* itemDisabled: 'choices__item--disabled', */
- /* itemChoice: 'choices__item--choice', */
- /* placeholder: 'choices__placeholder', */
- /* group: 'choices__group', */
- /* groupHeading: 'choices__heading', */
- /* button: 'choices__button', */
- /* activeState: 'is-active', */
- /* focusState: 'is-focused', */
- /* openState: 'is-open', */
- /* disabledState: 'is-disabled', */
- /* highlightedState: 'text-info', */
- /* selectedState: 'text-info', */
- /* flippedState: 'is-flipped', */
- /* loadingState: 'is-loading', */
- /* noResults: 'has-no-results', */
- /* noChoices: 'has-no-choices', */
- /* }, */
- /* }); */
+ this.choices = new Choices(selectId, {
+ shouldSort: false,
+ classNames: {
+ containerOuter: 'choices',
+ containerInner: 'choices__inner bg-secondary border-0',
+ input: 'form-control',
+ inputCloned: 'choices__input--cloned',
+ list: 'choices__list',
+ listItems: 'choices__list--multiple',
+ listSingle: 'choices__list--single',
+ listDropdown: 'choices__list--dropdown',
+ item: 'choices__item bg-secondary',
+ itemSelectable: 'choices__item--selectable',
+ itemDisabled: 'choices__item--disabled',
+ itemChoice: 'choices__item--choice',
+ placeholder: 'choices__placeholder',
+ group: 'choices__group',
+ groupHeading: 'choices__heading',
+ button: 'choices__button',
+ activeState: 'is-active',
+ focusState: 'is-focused',
+ openState: 'is-open',
+ disabledState: 'is-disabled',
+ highlightedState: 'text-info',
+ selectedState: 'text-info',
+ flippedState: 'is-flipped',
+ loadingState: 'is-loading',
+ noResults: 'has-no-results',
+ noChoices: 'has-no-choices',
+ },
+ });
this.choices.passedElement.element.addEventListener(
'choice',
(e: any) => {
false
);
}
+ }
+ }
+
+ parseMessage(msg: WebSocketJsonResponse) {
+ let res = wsJsonToRes(msg);
+ if (msg.error) {
+ toast(i18n.t(msg.error), 'danger');
+ this.state.loading = false;
+ this.setState(this.state);
+ return;
} else if (res.op == UserOperation.CreatePost) {
let data = res.data as PostResponse;
if (data.post.creator_id == UserService.Instance.user.id) {
component: Main,
},
{ path: `/login`, component: Login },
- { path: `/create_post`, component: CreatePost },
- { path: `/create_community`, component: CreateCommunity },
+ {
+ path: `/create_post`,
+ component: CreatePost,
+ fetchInitialData: (auth, path) => CreatePost.fetchInitialData(auth, path),
+ },
+ {
+ path: `/create_community`,
+ component: CreateCommunity,
+ fetchInitialData: (auth, path) =>
+ CreateCommunity.fetchInitialData(auth, path),
+ },
{
path: `/create_private_message`,
component: CreatePrivateMessage,
import { CommentSortType, DataType, IsoData } from './interfaces';
import { UserService, WebSocketService } from './services';
-// import Tribute from 'tributejs';
+var Tribute;
+if (isBrowser()) {
+ Tribute = require('tributejs');
+}
import markdown_it from 'markdown-it';
import markdown_it_sub from 'markdown-it-sub';
import markdown_it_sup from 'markdown-it-sup';
// TODO this broke
export function validURL(str: string) {
+ console.log(str);
// try {
return !!new URL(str);
// } catch {
}
}
-// export function setupTribute(): Tribute<{}> {
-// return new Tribute({
-// noMatchTemplate: function () {
-// return '';
-// },
-// collection: [
-// // Emojis
-// {
-// trigger: ':',
-// menuItemTemplate: (item: any) => {
-// let shortName = `:${item.original.key}:`;
-// return `${item.original.val} ${shortName}`;
-// },
-// selectTemplate: (item: any) => {
-// return `:${item.original.key}:`;
-// },
-// values: Object.entries(emojiShortName).map(e => {
-// return { key: e[1], val: e[0] };
-// }),
-// allowSpaces: false,
-// autocompleteMode: true,
-// // TODO
-// // menuItemLimit: mentionDropdownFetchLimit,
-// menuShowMinLength: 2,
-// },
-// // Users
-// {
-// trigger: '@',
-// selectTemplate: (item: any) => {
-// let link = item.original.local
-// ? `[${item.original.key}](/u/${item.original.name})`
-// : `[${item.original.key}](/user/${item.original.id})`;
-// return link;
-// },
-// values: (text: string, cb: any) => {
-// userSearch(text, (users: any) => cb(users));
-// },
-// allowSpaces: false,
-// autocompleteMode: true,
-// // TODO
-// // menuItemLimit: mentionDropdownFetchLimit,
-// menuShowMinLength: 2,
-// },
-
-// // Communities
-// {
-// trigger: '!',
-// selectTemplate: (item: any) => {
-// let link = item.original.local
-// ? `[${item.original.key}](/c/${item.original.name})`
-// : `[${item.original.key}](/community/${item.original.id})`;
-// return link;
-// },
-// values: (text: string, cb: any) => {
-// communitySearch(text, (communities: any) => cb(communities));
-// },
-// allowSpaces: false,
-// autocompleteMode: true,
-// // TODO
-// // menuItemLimit: mentionDropdownFetchLimit,
-// menuShowMinLength: 2,
-// },
-// ],
-// });
-// }
+export function setupTribute() {
+ return new Tribute({
+ noMatchTemplate: function () {
+ return '';
+ },
+ collection: [
+ // Emojis
+ {
+ trigger: ':',
+ menuItemTemplate: (item: any) => {
+ let shortName = `:${item.original.key}:`;
+ return `${item.original.val} ${shortName}`;
+ },
+ selectTemplate: (item: any) => {
+ return `:${item.original.key}:`;
+ },
+ values: Object.entries(emojiShortName).map(e => {
+ return { key: e[1], val: e[0] };
+ }),
+ allowSpaces: false,
+ autocompleteMode: true,
+ // TODO
+ // menuItemLimit: mentionDropdownFetchLimit,
+ menuShowMinLength: 2,
+ },
+ // Users
+ {
+ trigger: '@',
+ selectTemplate: (item: any) => {
+ let link = item.original.local
+ ? `[${item.original.key}](/u/${item.original.name})`
+ : `[${item.original.key}](/user/${item.original.id})`;
+ return link;
+ },
+ values: (text: string, cb: any) => {
+ userSearch(text, (users: any) => cb(users));
+ },
+ allowSpaces: false,
+ autocompleteMode: true,
+ // TODO
+ // menuItemLimit: mentionDropdownFetchLimit,
+ menuShowMinLength: 2,
+ },
+
+ // Communities
+ {
+ trigger: '!',
+ selectTemplate: (item: any) => {
+ let link = item.original.local
+ ? `[${item.original.key}](/c/${item.original.name})`
+ : `[${item.original.key}](/community/${item.original.id})`;
+ return link;
+ },
+ values: (text: string, cb: any) => {
+ communitySearch(text, (communities: any) => cb(communities));
+ },
+ allowSpaces: false,
+ autocompleteMode: true,
+ // TODO
+ // menuItemLimit: mentionDropdownFetchLimit,
+ menuShowMinLength: 2,
+ },
+ ],
+ });
+}
// TODO
// let tippyInstance = tippy('[data-tippy-content]');