@waline/client
Version:
client for waline comment system
137 lines (123 loc) • 2.98 kB
text/typescript
import { getUserList, WalineUser } from '../api';
import { defaultLang, defaultLocales } from '../config';
import { WalineLocale } from '../typings';
import { getRoot } from '../utils';
export interface WalineUserListOptions {
/**
* Waline 服务端地址
*
* Waline serverURL
*/
serverURL: string;
/**
* 获取用户列表的数量
*
* fetch number of user list
*/
count: number;
/**
* 需要挂载的元素
*
* Element to be mounted
*/
el?: string | HTMLElement;
/**
* 错误提示消息所使用的语言
*
* Language of error message
*
* @default navigator.language
*/
lang?: string;
/**
* 自定义 waline 语言显示
*
* @see [自定义语言](https://waline.js.org/client/i18n.html)
*
* Custom display language in waline
*
* @see [I18n](https://waline.js.org/en/client/i18n.html)
*/
locale?: WalineLocale;
/**
* 列表模式还是头像墙模式
*
* list mode or avatar wall mode
*/
mode: 'list' | 'wall';
}
export interface WalineUserListResult {
/**
* 用户数据
*
* User Data
*/
users: WalineUser[];
/**
* 取消挂载挂件
*
* Umount widget
*/
destroy: () => void;
}
export const UserList = ({
el,
serverURL,
count,
locale,
lang = navigator.language,
mode = 'list',
}: WalineUserListOptions): Promise<WalineUserListResult> => {
const root = getRoot(el);
const controller = new AbortController();
return getUserList({
serverURL,
pageSize: count,
lang,
signal: controller.signal,
}).then((users) => {
if (!root || !users.length)
return {
users,
destroy: (): void => controller.abort(),
};
locale = {
...(defaultLocales[lang] || defaultLocales[defaultLang]),
...(typeof locale === 'object' ? locale : {}),
} as WalineLocale;
root.innerHTML = `<ul class="wl-user-${mode}">${users
.map((user, index) =>
[
`<li class="wl-user-item" aria-label="${user.nick}">`,
user.link && `<a href="${user.link}" target="_blank">`,
'<div class="wl-user-avatar">',
`<img src="${user.avatar}" alt="${user.nick}">`,
`<span class="wl-user-badge">${index + 1}</span>`,
'</div>',
'<div class="wl-user-meta">',
'<div class="wl-user-name">',
user.nick,
user.level &&
`<span class="wl-badge">${
locale ? locale[`level${user.level}`] : `Level ${user.level}`
}</span>`,
user.label && `<span class="wl-badge">${user.label}</span>`,
'</div>',
user.link && user.link,
'</div>',
user.link && '</a>',
'</li>',
]
.filter((v) => v)
.join('')
)
.join('')}</ul>`;
return {
users,
destroy: (): void => {
controller.abort();
root.innerHTML = '';
},
};
});
};