Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert common helpers to Typescript #2541

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,26 +1,28 @@
import * as Mithril from 'mithril';
import User from '../models/User';

/**
* The `avatar` helper displays a user's avatar.
*
* @param {User} user
* @param {Object} attrs Attributes to apply to the avatar element
* @return {Object}
* @param user
* @param attrs Attributes to apply to the avatar element
Copy link
Sponsor Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wouldn't want to have one param documented but the other not

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The other is still documented in the typehinting. Attrs only remains for the description in the JSDoc. I don't know if we want to do that or keep tham all, howeverr 🤷

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should leave all parameters in JSDoc if there's any with description and get rid of all parameters if none of them have any description. By the way this should resolve PHPStorm's warning "Parameter is not described in JSDoc".

*/
export default function avatar(user, attrs = {}) {
export default function avatar(user: User, attrs: Object = {}): Mithril.Vnode {
attrs.className = 'Avatar ' + (attrs.className || '');
let content = '';
let content: string = '';

// If the `title` attribute is set to null or false, we don't want to give the
// avatar a title. On the other hand, if it hasn't been given at all, we can
// safely default it to the user's username.
const hasTitle = attrs.title === 'undefined' || attrs.title;
const hasTitle: boolean | string = attrs.title === 'undefined' || attrs.title;
if (!hasTitle) delete attrs.title;

// If a user has been passed, then we will set up an avatar using their
// uploaded image, or the first letter of their username if they haven't
// uploaded one.
if (user) {
const username = user.displayName() || '?';
const avatarUrl = user.avatarUrl();
const username: string = user.displayName() || '?';
const avatarUrl: string = user.avatarUrl();

if (hasTitle) attrs.title = attrs.title || username;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import * as Mithril from 'mithril';
import Separator from '../components/Separator';
import classList from '../utils/classList';

function isSeparator(item) {
function isSeparator(item): boolean {
return item.tag === Separator;
}

function withoutUnnecessarySeparators(items) {
function withoutUnnecessarySeparators(items: Array<Mithril.Vnode>): Array<Mithril.Vnode> {
const newItems = [];
let prevItem;

items.filter(Boolean).forEach((item, i) => {
items.filter(Boolean).forEach((item: Mithril.Vnode, i: number) => {
if (!isSeparator(item) || (prevItem && !isSeparator(prevItem) && i !== items.length - 1)) {
prevItem = item;
newItems.push(item);
Expand All @@ -22,14 +23,11 @@ function withoutUnnecessarySeparators(items) {
/**
* The `listItems` helper wraps a collection of components in <li> tags,
* stripping out any unnecessary `Separator` components.
*
* @param {*} items
* @return {Array}
*/
export default function listItems(items) {
export default function listItems(items: Mithril.Vnode | Array<Mithril.Vnode>): Array<Mithril.Vnode> {
if (!(items instanceof Array)) items = [items];

return withoutUnnecessarySeparators(items).map((item) => {
return withoutUnnecessarySeparators(items).map((item: Mithril.Vnode) => {
const isListItem = item.tag && item.tag.isListItem;
const active = item.tag && item.tag.isActive && item.tag.isActive(item.attrs);
const className = (item.attrs && item.attrs.itemClassName) || item.itemClassName;
Expand All @@ -40,7 +38,7 @@ export default function listItems(items) {
item.key = item.attrs.key;
}

const node = isListItem ? (
const node: Mithril.Vnode = isListItem ? (
item
) : (
<li
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import * as Mithril from 'mithril';
import User from '../models/User';
import icon from './icon';

/**
* The `useronline` helper displays a green circle if the user is online
*
* @param {User} user
* @return {Object}
*/
export default function userOnline(user) {
export default function userOnline(user: User): Mithril.Vnode {
if (user.lastSeenAt() && user.isOnline()) {
return <span className="UserOnline">{icon('fas fa-circle')}</span>;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import * as Mithril from 'mithril';
import User from '../models/User';

/**
* The `username` helper displays a user's username in a <span class="username">
* tag. If the user doesn't exist, the username will be displayed as [deleted].
*
* @param {User} user
* @return {Object}
*/
export default function username(user) {
export default function username(user: User): Mithril.Vnode {
const name = (user && user.displayName()) || app.translator.trans('core.lib.username.deleted_text');

return <span className="username">{name}</span>;
Expand Down