mirror of
https://github.com/LemmyNet/lemmy-ui.git
synced 2024-11-21 22:27:11 +00:00
Community page done.
This commit is contained in:
parent
8f44607956
commit
6562b6f4f0
|
@ -74,7 +74,7 @@
|
||||||
"eslint-plugin-jane": "^8.0.4",
|
"eslint-plugin-jane": "^8.0.4",
|
||||||
"husky": "^4.2.5",
|
"husky": "^4.2.5",
|
||||||
"jest": "^26.4.2",
|
"jest": "^26.4.2",
|
||||||
"lemmy-js-client": "^1.0.9",
|
"lemmy-js-client": "^1.0.11",
|
||||||
"lint-staged": "^10.1.3",
|
"lint-staged": "^10.1.3",
|
||||||
"mini-css-extract-plugin": "^0.11.0",
|
"mini-css-extract-plugin": "^0.11.0",
|
||||||
"node-sass": "^4.12.0",
|
"node-sass": "^4.12.0",
|
||||||
|
|
|
@ -1,15 +1,11 @@
|
||||||
import { Component, linkEvent } from 'inferno';
|
import { Component, linkEvent } from 'inferno';
|
||||||
import { Helmet } from 'inferno-helmet';
|
import { Helmet } from 'inferno-helmet';
|
||||||
import { Subscription } from 'rxjs';
|
import { Subscription } from 'rxjs';
|
||||||
import { retryWhen, delay, take } from 'rxjs/operators';
|
|
||||||
import { DataType } from '../interfaces';
|
import { DataType } from '../interfaces';
|
||||||
import {
|
import {
|
||||||
UserOperation,
|
UserOperation,
|
||||||
Community as CommunityI,
|
|
||||||
GetCommunityResponse,
|
GetCommunityResponse,
|
||||||
CommunityResponse,
|
CommunityResponse,
|
||||||
CommunityUser,
|
|
||||||
UserView,
|
|
||||||
SortType,
|
SortType,
|
||||||
Post,
|
Post,
|
||||||
GetPostsForm,
|
GetPostsForm,
|
||||||
|
@ -25,9 +21,8 @@ import {
|
||||||
CommentResponse,
|
CommentResponse,
|
||||||
WebSocketJsonResponse,
|
WebSocketJsonResponse,
|
||||||
GetSiteResponse,
|
GetSiteResponse,
|
||||||
Site,
|
|
||||||
} from 'lemmy-js-client';
|
} from 'lemmy-js-client';
|
||||||
import { WebSocketService } from '../services';
|
import { UserService, WebSocketService } from '../services';
|
||||||
import { PostListings } from './post-listings';
|
import { PostListings } from './post-listings';
|
||||||
import { CommentNodes } from './comment-nodes';
|
import { CommentNodes } from './comment-nodes';
|
||||||
import { SortSelect } from './sort-select';
|
import { SortSelect } from './sort-select';
|
||||||
|
@ -51,23 +46,25 @@ import {
|
||||||
setupTippy,
|
setupTippy,
|
||||||
favIconUrl,
|
favIconUrl,
|
||||||
notifyPost,
|
notifyPost,
|
||||||
|
setIsoData,
|
||||||
|
wsSubscribe,
|
||||||
|
isBrowser,
|
||||||
|
lemmyHttp,
|
||||||
|
setAuth,
|
||||||
} from '../utils';
|
} from '../utils';
|
||||||
import { i18n } from '../i18next';
|
import { i18n } from '../i18next';
|
||||||
|
|
||||||
interface State {
|
interface State {
|
||||||
community: CommunityI;
|
communityRes: GetCommunityResponse;
|
||||||
|
siteRes: GetSiteResponse;
|
||||||
communityId: number;
|
communityId: number;
|
||||||
communityName: string;
|
communityName: string;
|
||||||
moderators: CommunityUser[];
|
|
||||||
admins: UserView[];
|
|
||||||
online: number;
|
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
posts: Post[];
|
posts: Post[];
|
||||||
comments: Comment[];
|
comments: Comment[];
|
||||||
dataType: DataType;
|
dataType: DataType;
|
||||||
sort: SortType;
|
sort: SortType;
|
||||||
page: number;
|
page: number;
|
||||||
site: Site;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface CommunityProps {
|
interface CommunityProps {
|
||||||
|
@ -83,57 +80,19 @@ interface UrlParams {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Community extends Component<any, State> {
|
export class Community extends Component<any, State> {
|
||||||
|
private isoData = setIsoData(this.context);
|
||||||
private subscription: Subscription;
|
private subscription: Subscription;
|
||||||
private emptyState: State = {
|
private emptyState: State = {
|
||||||
community: {
|
communityRes: undefined,
|
||||||
id: null,
|
|
||||||
name: null,
|
|
||||||
title: null,
|
|
||||||
category_id: null,
|
|
||||||
category_name: null,
|
|
||||||
creator_id: null,
|
|
||||||
creator_name: null,
|
|
||||||
number_of_subscribers: null,
|
|
||||||
number_of_posts: null,
|
|
||||||
number_of_comments: null,
|
|
||||||
published: null,
|
|
||||||
removed: null,
|
|
||||||
nsfw: false,
|
|
||||||
deleted: null,
|
|
||||||
local: null,
|
|
||||||
actor_id: null,
|
|
||||||
last_refreshed_at: null,
|
|
||||||
creator_actor_id: null,
|
|
||||||
creator_local: null,
|
|
||||||
},
|
|
||||||
moderators: [],
|
|
||||||
admins: [],
|
|
||||||
communityId: Number(this.props.match.params.id),
|
communityId: Number(this.props.match.params.id),
|
||||||
communityName: this.props.match.params.name,
|
communityName: this.props.match.params.name,
|
||||||
online: null,
|
|
||||||
loading: true,
|
loading: true,
|
||||||
posts: [],
|
posts: [],
|
||||||
comments: [],
|
comments: [],
|
||||||
dataType: getDataTypeFromProps(this.props),
|
dataType: getDataTypeFromProps(this.props),
|
||||||
sort: getSortTypeFromProps(this.props),
|
sort: getSortTypeFromProps(this.props),
|
||||||
page: getPageFromProps(this.props),
|
page: getPageFromProps(this.props),
|
||||||
site: {
|
siteRes: this.isoData.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,
|
|
||||||
icon: undefined,
|
|
||||||
banner: undefined,
|
|
||||||
creator_preferred_username: undefined,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(props: any, context: any) {
|
constructor(props: any, context: any) {
|
||||||
|
@ -143,24 +102,37 @@ export class Community extends Component<any, State> {
|
||||||
this.handleSortChange = this.handleSortChange.bind(this);
|
this.handleSortChange = this.handleSortChange.bind(this);
|
||||||
this.handleDataTypeChange = this.handleDataTypeChange.bind(this);
|
this.handleDataTypeChange = this.handleDataTypeChange.bind(this);
|
||||||
|
|
||||||
this.subscription = WebSocketService.Instance.subject
|
this.parseMessage = this.parseMessage.bind(this);
|
||||||
.pipe(retryWhen(errors => errors.pipe(delay(3000), take(10))))
|
this.subscription = wsSubscribe(this.parseMessage);
|
||||||
.subscribe(
|
|
||||||
msg => this.parseMessage(msg),
|
|
||||||
err => console.error(err),
|
|
||||||
() => console.log('complete')
|
|
||||||
);
|
|
||||||
|
|
||||||
|
// Only fetch the data if coming from another route
|
||||||
|
if (this.isoData.path == this.context.router.route.match.url) {
|
||||||
|
this.state.communityRes = this.isoData.routeData[0];
|
||||||
|
if (this.state.dataType == DataType.Post) {
|
||||||
|
this.state.posts = this.isoData.routeData[1].posts;
|
||||||
|
} else {
|
||||||
|
this.state.comments = this.isoData.routeData[1].comments;
|
||||||
|
}
|
||||||
|
this.state.loading = false;
|
||||||
|
} else {
|
||||||
|
this.fetchCommunity();
|
||||||
|
this.fetchData();
|
||||||
|
}
|
||||||
|
setupTippy();
|
||||||
|
}
|
||||||
|
|
||||||
|
fetchCommunity() {
|
||||||
let form: GetCommunityForm = {
|
let form: GetCommunityForm = {
|
||||||
id: this.state.communityId ? this.state.communityId : null,
|
id: this.state.communityId ? this.state.communityId : null,
|
||||||
name: this.state.communityName ? this.state.communityName : null,
|
name: this.state.communityName ? this.state.communityName : null,
|
||||||
};
|
};
|
||||||
WebSocketService.Instance.getCommunity(form);
|
WebSocketService.Instance.getCommunity(form);
|
||||||
WebSocketService.Instance.getSite();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
this.subscription.unsubscribe();
|
if (isBrowser()) {
|
||||||
|
this.subscription.unsubscribe();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static getDerivedStateFromProps(props: any): CommunityProps {
|
static getDerivedStateFromProps(props: any): CommunityProps {
|
||||||
|
@ -171,6 +143,69 @@ export class Community extends Component<any, State> {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static fetchInitialData(auth: string, path: string): Promise<any>[] {
|
||||||
|
let pathSplit = path.split('/');
|
||||||
|
let promises: Promise<any>[] = [];
|
||||||
|
|
||||||
|
// It can be /c/main, or /c/1
|
||||||
|
let idOrName = pathSplit[2];
|
||||||
|
let id: number;
|
||||||
|
let name_: string;
|
||||||
|
if (isNaN(Number(idOrName))) {
|
||||||
|
name_ = idOrName;
|
||||||
|
} else {
|
||||||
|
id = Number(idOrName);
|
||||||
|
}
|
||||||
|
|
||||||
|
let communityForm: GetCommunityForm = id ? { id } : { name: name_ };
|
||||||
|
setAuth(communityForm, auth);
|
||||||
|
promises.push(lemmyHttp.getCommunity(communityForm));
|
||||||
|
|
||||||
|
let dataType: DataType = pathSplit[4]
|
||||||
|
? DataType[pathSplit[4]]
|
||||||
|
: DataType.Post;
|
||||||
|
|
||||||
|
let sort: SortType = pathSplit[6]
|
||||||
|
? SortType[pathSplit[6]]
|
||||||
|
: UserService.Instance.user
|
||||||
|
? Object.values(SortType)[UserService.Instance.user.default_sort_type]
|
||||||
|
: SortType.Active;
|
||||||
|
|
||||||
|
let page = pathSplit[8] ? Number(pathSplit[8]) : 1;
|
||||||
|
|
||||||
|
if (dataType == DataType.Post) {
|
||||||
|
let getPostsForm: GetPostsForm = {
|
||||||
|
page,
|
||||||
|
limit: fetchLimit,
|
||||||
|
sort,
|
||||||
|
type_: ListingType.Community,
|
||||||
|
};
|
||||||
|
this.setIdOrName(getPostsForm, id, name_);
|
||||||
|
setAuth(getPostsForm, auth);
|
||||||
|
promises.push(lemmyHttp.getPosts(getPostsForm));
|
||||||
|
} else {
|
||||||
|
let getCommentsForm: GetCommentsForm = {
|
||||||
|
page,
|
||||||
|
limit: fetchLimit,
|
||||||
|
sort,
|
||||||
|
type_: ListingType.Community,
|
||||||
|
};
|
||||||
|
this.setIdOrName(getCommentsForm, id, name_);
|
||||||
|
setAuth(getCommentsForm, auth);
|
||||||
|
promises.push(lemmyHttp.getComments(getCommentsForm));
|
||||||
|
}
|
||||||
|
|
||||||
|
return promises;
|
||||||
|
}
|
||||||
|
|
||||||
|
static setIdOrName(obj: any, id: number, name_: string) {
|
||||||
|
if (id) {
|
||||||
|
obj.community_id = id;
|
||||||
|
} else {
|
||||||
|
obj.community_name = name_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
componentDidUpdate(_: any, lastState: State) {
|
componentDidUpdate(_: any, lastState: State) {
|
||||||
if (
|
if (
|
||||||
lastState.dataType !== this.state.dataType ||
|
lastState.dataType !== this.state.dataType ||
|
||||||
|
@ -183,15 +218,17 @@ export class Community extends Component<any, State> {
|
||||||
}
|
}
|
||||||
|
|
||||||
get documentTitle(): string {
|
get documentTitle(): string {
|
||||||
if (this.state.community.title) {
|
if (this.state.communityRes) {
|
||||||
return `${this.state.community.title} - ${this.state.site.name}`;
|
return `${this.state.communityRes.community.title} - ${this.state.siteRes.site.name}`;
|
||||||
} else {
|
} else {
|
||||||
return 'Lemmy';
|
return 'Lemmy';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get favIcon(): string {
|
get favIcon(): string {
|
||||||
return this.state.site.icon ? this.state.site.icon : favIconUrl;
|
return this.state.siteRes.site.icon
|
||||||
|
? this.state.siteRes.site.icon
|
||||||
|
: favIconUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
@ -221,11 +258,11 @@ export class Community extends Component<any, State> {
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12 col-md-4">
|
<div class="col-12 col-md-4">
|
||||||
<Sidebar
|
<Sidebar
|
||||||
community={this.state.community}
|
community={this.state.communityRes.community}
|
||||||
moderators={this.state.moderators}
|
moderators={this.state.communityRes.moderators}
|
||||||
admins={this.state.admins}
|
admins={this.state.siteRes.admins}
|
||||||
online={this.state.online}
|
online={this.state.communityRes.online}
|
||||||
enableNsfw={this.state.site.enable_nsfw}
|
enableNsfw={this.state.siteRes.site.enable_nsfw}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -240,8 +277,8 @@ export class Community extends Component<any, State> {
|
||||||
posts={this.state.posts}
|
posts={this.state.posts}
|
||||||
removeDuplicates
|
removeDuplicates
|
||||||
sort={this.state.sort}
|
sort={this.state.sort}
|
||||||
enableDownvotes={this.state.site.enable_downvotes}
|
enableDownvotes={this.state.siteRes.site.enable_downvotes}
|
||||||
enableNsfw={this.state.site.enable_nsfw}
|
enableNsfw={this.state.siteRes.site.enable_nsfw}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<CommentNodes
|
<CommentNodes
|
||||||
|
@ -249,7 +286,7 @@ export class Community extends Component<any, State> {
|
||||||
noIndent
|
noIndent
|
||||||
sortType={this.state.sort}
|
sortType={this.state.sort}
|
||||||
showContext
|
showContext
|
||||||
enableDownvotes={this.state.site.enable_downvotes}
|
enableDownvotes={this.state.siteRes.site.enable_downvotes}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -258,12 +295,12 @@ export class Community extends Component<any, State> {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<BannerIconHeader
|
<BannerIconHeader
|
||||||
banner={this.state.community.banner}
|
banner={this.state.communityRes.community.banner}
|
||||||
icon={this.state.community.icon}
|
icon={this.state.communityRes.community.icon}
|
||||||
/>
|
/>
|
||||||
<h5 class="mb-0">{this.state.community.title}</h5>
|
<h5 class="mb-0">{this.state.communityRes.community.title}</h5>
|
||||||
<CommunityLink
|
<CommunityLink
|
||||||
community={this.state.community}
|
community={this.state.communityRes.community}
|
||||||
realLink
|
realLink
|
||||||
useApubName
|
useApubName
|
||||||
muted
|
muted
|
||||||
|
@ -348,7 +385,7 @@ export class Community extends Component<any, State> {
|
||||||
const sortStr = paramUpdates.sort || this.state.sort;
|
const sortStr = paramUpdates.sort || this.state.sort;
|
||||||
const page = paramUpdates.page || this.state.page;
|
const page = paramUpdates.page || this.state.page;
|
||||||
this.props.history.push(
|
this.props.history.push(
|
||||||
`/c/${this.state.community.name}/data_type/${dataTypeStr}/sort/${sortStr}/page/${page}`
|
`/c/${this.state.communityRes.community.name}/data_type/${dataTypeStr}/sort/${sortStr}/page/${page}`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -359,7 +396,8 @@ export class Community extends Component<any, State> {
|
||||||
limit: fetchLimit,
|
limit: fetchLimit,
|
||||||
sort: this.state.sort,
|
sort: this.state.sort,
|
||||||
type_: ListingType.Community,
|
type_: ListingType.Community,
|
||||||
community_id: this.state.community.id,
|
community_id: this.state.communityId,
|
||||||
|
community_name: this.state.communityName,
|
||||||
};
|
};
|
||||||
WebSocketService.Instance.getPosts(getPostsForm);
|
WebSocketService.Instance.getPosts(getPostsForm);
|
||||||
} else {
|
} else {
|
||||||
|
@ -368,7 +406,8 @@ export class Community extends Component<any, State> {
|
||||||
limit: fetchLimit,
|
limit: fetchLimit,
|
||||||
sort: this.state.sort,
|
sort: this.state.sort,
|
||||||
type_: ListingType.Community,
|
type_: ListingType.Community,
|
||||||
community_id: this.state.community.id,
|
community_id: this.state.communityId,
|
||||||
|
community_name: this.state.communityName,
|
||||||
};
|
};
|
||||||
WebSocketService.Instance.getComments(getCommentsForm);
|
WebSocketService.Instance.getComments(getCommentsForm);
|
||||||
}
|
}
|
||||||
|
@ -385,23 +424,20 @@ export class Community extends Component<any, State> {
|
||||||
this.fetchData();
|
this.fetchData();
|
||||||
} else if (res.op == UserOperation.GetCommunity) {
|
} else if (res.op == UserOperation.GetCommunity) {
|
||||||
let data = res.data as GetCommunityResponse;
|
let data = res.data as GetCommunityResponse;
|
||||||
this.state.community = data.community;
|
this.state.communityRes = data;
|
||||||
this.state.moderators = data.moderators;
|
|
||||||
this.state.online = data.online;
|
|
||||||
this.setState(this.state);
|
this.setState(this.state);
|
||||||
this.fetchData();
|
|
||||||
} else if (
|
} else if (
|
||||||
res.op == UserOperation.EditCommunity ||
|
res.op == UserOperation.EditCommunity ||
|
||||||
res.op == UserOperation.DeleteCommunity ||
|
res.op == UserOperation.DeleteCommunity ||
|
||||||
res.op == UserOperation.RemoveCommunity
|
res.op == UserOperation.RemoveCommunity
|
||||||
) {
|
) {
|
||||||
let data = res.data as CommunityResponse;
|
let data = res.data as CommunityResponse;
|
||||||
this.state.community = data.community;
|
this.state.communityRes.community = data.community;
|
||||||
this.setState(this.state);
|
this.setState(this.state);
|
||||||
} else if (res.op == UserOperation.FollowCommunity) {
|
} else if (res.op == UserOperation.FollowCommunity) {
|
||||||
let data = res.data as CommunityResponse;
|
let data = res.data as CommunityResponse;
|
||||||
this.state.community.subscribed = data.community.subscribed;
|
this.state.communityRes.community.subscribed = data.community.subscribed;
|
||||||
this.state.community.number_of_subscribers =
|
this.state.communityRes.community.number_of_subscribers =
|
||||||
data.community.number_of_subscribers;
|
data.community.number_of_subscribers;
|
||||||
this.setState(this.state);
|
this.setState(this.state);
|
||||||
} else if (res.op == UserOperation.GetPosts) {
|
} else if (res.op == UserOperation.GetPosts) {
|
||||||
|
@ -431,7 +467,7 @@ export class Community extends Component<any, State> {
|
||||||
this.setState(this.state);
|
this.setState(this.state);
|
||||||
} else if (res.op == UserOperation.AddModToCommunity) {
|
} else if (res.op == UserOperation.AddModToCommunity) {
|
||||||
let data = res.data as AddModToCommunityResponse;
|
let data = res.data as AddModToCommunityResponse;
|
||||||
this.state.moderators = data.moderators;
|
this.state.communityRes.moderators = data.moderators;
|
||||||
this.setState(this.state);
|
this.setState(this.state);
|
||||||
} else if (res.op == UserOperation.BanFromCommunity) {
|
} else if (res.op == UserOperation.BanFromCommunity) {
|
||||||
let data = res.data as BanFromCommunityResponse;
|
let data = res.data as BanFromCommunityResponse;
|
||||||
|
@ -470,11 +506,6 @@ export class Community extends Component<any, State> {
|
||||||
let data = res.data as CommentResponse;
|
let data = res.data as CommentResponse;
|
||||||
createCommentLikeRes(data, this.state.comments);
|
createCommentLikeRes(data, this.state.comments);
|
||||||
this.setState(this.state);
|
this.setState(this.state);
|
||||||
} else if (res.op == UserOperation.GetSite) {
|
|
||||||
let data = res.data as GetSiteResponse;
|
|
||||||
this.state.site = data.site;
|
|
||||||
this.state.admins = data.admins;
|
|
||||||
this.setState(this.state);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,9 +67,18 @@ export const routes: IRoutePropsWithFetch[] = [
|
||||||
{
|
{
|
||||||
path: `/c/:name/data_type/:data_type/sort/:sort/page/:page`,
|
path: `/c/:name/data_type/:data_type/sort/:sort/page/:page`,
|
||||||
component: Community,
|
component: Community,
|
||||||
|
fetchInitialData: (auth, path) => Community.fetchInitialData(auth, path),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: `/community/:id`,
|
||||||
|
component: Community,
|
||||||
|
fetchInitialData: (auth, path) => Community.fetchInitialData(auth, path),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: `/c/:name`,
|
||||||
|
component: Community,
|
||||||
|
fetchInitialData: (auth, path) => Community.fetchInitialData(auth, path),
|
||||||
},
|
},
|
||||||
{ path: `/community/:id`, component: Community },
|
|
||||||
{ path: `/c/:name`, component: Community },
|
|
||||||
{
|
{
|
||||||
path: `/u/:username/view/:view/sort/:sort/page/:page`,
|
path: `/u/:username/view/:view/sort/:sort/page/:page`,
|
||||||
component: User,
|
component: User,
|
||||||
|
|
|
@ -7043,10 +7043,10 @@ lcid@^1.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
invert-kv "^1.0.0"
|
invert-kv "^1.0.0"
|
||||||
|
|
||||||
lemmy-js-client@^1.0.9:
|
lemmy-js-client@^1.0.11:
|
||||||
version "1.0.9"
|
version "1.0.11"
|
||||||
resolved "https://registry.yarnpkg.com/lemmy-js-client/-/lemmy-js-client-1.0.9.tgz#23cab713613612a524085d6bb3fc1d4042d262a8"
|
resolved "https://registry.yarnpkg.com/lemmy-js-client/-/lemmy-js-client-1.0.11.tgz#f6ccdd5f4bf60c9ec49a4337c92d91933c0d00c2"
|
||||||
integrity sha512-QJc4d1HkSxjv555yH3MAOYbTfgbhmmvvuC1uhFvPwBlL5B5MTry/fWPRbtLfkYTxdZWftE+PYvLVKPr3/dFmxw==
|
integrity sha512-bMvCKcP76YpSYhVSX0hGnhf9DQWpu7j4UQG2ektbpsmTi+yA4JiZKsLQXwgQH7hty42EHV0ZJVBNUpqlKnGFrA==
|
||||||
|
|
||||||
leven@^3.1.0:
|
leven@^3.1.0:
|
||||||
version "3.1.0"
|
version "3.1.0"
|
||||||
|
|
Loading…
Reference in a new issue