1
0
mirror of https://github.com/flarum/core.git synced 2025-08-07 08:56:38 +02:00

Added some more type hinting, changed arguments for computed util

This commit is contained in:
David Sevilla Martin
2020-01-03 16:28:15 -05:00
parent b47ba94a9b
commit 49d2539aef
20 changed files with 58 additions and 53 deletions

View File

@@ -12,6 +12,8 @@
- `app.bus` for some event hooking - `app.bus` for some event hooking
* Translator * Translator
- Added `app.translator.transText`, automatically extracts text from `translator.trans` output - Added `app.translator.transText`, automatically extracts text from `translator.trans` output
* Utils
- Changed `computed` util to require multiple keys to be passed as an array
#### Forum #### Forum
* Forum Application * Forum Application

12
js/dist/admin.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

8
js/dist/forum.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -65,7 +65,9 @@ export default abstract class Application {
* A local cache that can be used to store data at the application level, so * A local cache that can be used to store data at the application level, so
* that is persists between different routes. * that is persists between different routes.
*/ */
cache = {}; cache = {
notifications: null,
};
routes = {}; routes = {};

View File

@@ -107,7 +107,7 @@ export default class Model {
* @param [options] * @param [options]
* @return {Promise} * @return {Promise}
*/ */
save(attributes: any, options: any = {}): Promise { save(attributes: any, options: any = {}): Promise<Model|Model[]> {
const data = { const data = {
type: this.data.type, type: this.data.type,
id: this.data.id, id: this.data.id,
@@ -162,7 +162,7 @@ export default class Model {
// old data! We'll revert to that and let others handle the error. // old data! We'll revert to that and let others handle the error.
response => { response => {
this.pushData(oldData); this.pushData(oldData);
m.lazyRedraw(); m.redraw();
throw response; throw response;
} }
); );
@@ -171,13 +171,13 @@ export default class Model {
/** /**
* Send a request to delete the resource. * Send a request to delete the resource.
* *
* @param {Object} data Data to send along with the DELETE request. * @param {Object} body Data to send along with the DELETE request.
* @param {Object} [options] * @param {Object} [options]
* @return {Promise} * @return {Promise}
* @public * @public
*/ */
delete(body, options = {}) { delete(body = {}, options = {}) {
if (!this.exists) return m.deferred.resolve().promise; if (!this.exists) return Promise.resolve();
return app.request(Object.assign({ return app.request(Object.assign({
method: 'DELETE', method: 'DELETE',

View File

@@ -24,7 +24,7 @@ export default class Session {
/** /**
* Attempt to log in a user. * Attempt to log in a user.
*/ */
login(body: { identification: string, password: string }, options = {}) { login(body: { identification: string, password: string, remember?: string }, options = {}) {
return app.request(Object.assign({ return app.request(Object.assign({
method: 'POST', method: 'POST',
url: `${app.forum.attribute('baseUrl')}/login`, url: `${app.forum.attribute('baseUrl')}/login`,

View File

@@ -9,7 +9,7 @@ export default class Store {
* The local data store. A tree of resource types to IDs, such that * The local data store. A tree of resource types to IDs, such that
* accessing data[type][id] will return the model for that type/ID. * accessing data[type][id] will return the model for that type/ID.
*/ */
protected data: { [key: string]: { [key: number]: Model }} = {}; data: { [key: string]: { [key: number]: Model }} = {};
/** /**
* The model registry. A map of resource types to the model class that * The model registry. A map of resource types to the model class that

View File

@@ -1,3 +1,5 @@
import Mithril from 'mithril';
import Component, {ComponentProps} from '../Component'; import Component, {ComponentProps} from '../Component';
import Button from './Button'; import Button from './Button';
import RequestError from "../utils/RequestError"; import RequestError from "../utils/RequestError";

View File

@@ -17,8 +17,6 @@ export default class ModalManager extends Component {
super.oncreate(vnode); super.oncreate(vnode);
app.modal = this; app.modal = this;
window.vnode = vnode;
} }
view() { view() {
@@ -44,7 +42,7 @@ export default class ModalManager extends Component {
// if (app.current) app.current.retain = true; // if (app.current) app.current.retain = true;
m.redraw(true); m.redraw();
if (!$('.modal-backdrop').length) { if (!$('.modal-backdrop').length) {
$('<div />').addClass('modal-backdrop') $('<div />').addClass('modal-backdrop')
@@ -99,7 +97,7 @@ export default class ModalManager extends Component {
app.current.retain = false; app.current.retain = false;
m.lazyRedraw(); m.redraw();
} }
/** /**
@@ -109,7 +107,7 @@ export default class ModalManager extends Component {
*/ */
onready() { onready() {
if (this.component && this.component.onready) { if (this.component && this.component.onready) {
this.component.onready(this.$()); this.component.onready();
} }
} }
} }

View File

@@ -30,7 +30,7 @@ export default class User extends Model {
canDelete = Model.attribute('canDelete') as () => boolean; canDelete = Model.attribute('canDelete') as () => boolean;
avatarColor = null; avatarColor = null;
color = computed('username', 'avatarUrl', 'avatarColor', function(username, avatarUrl, avatarColor) { color = computed(['username', 'avatarUrl', 'avatarColor'], function(username, avatarUrl, avatarColor) {
// If we've already calculated and cached the dominant color of the user's // If we've already calculated and cached the dominant color of the user's
// avatar, then we can return that in RGB format. If we haven't, we'll want // avatar, then we can return that in RGB format. If we haven't, we'll want
// to calculate it. Unless the user doesn't have an avatar, in which case // to calculate it. Unless the user doesn't have an avatar, in which case
@@ -92,6 +92,6 @@ export default class User extends Model {
Object.assign(preferences, newPreferences); Object.assign(preferences, newPreferences);
return this.save({preferences}); return <Promise<User>> this.save({preferences});
} }
} }

View File

@@ -6,9 +6,8 @@
* @param {function} compute The function which computes the value using the * @param {function} compute The function which computes the value using the
* dependent values. * dependent values.
*/ */
export default function computed(...dependentKeys: string[]|Function[]): () => any { export default function computed(dependentKeys: string|string[], compute: Function): () => any {
const keys = <string[]> dependentKeys.slice(0, -1); const keys = Array.from(dependentKeys);
const compute = <Function> dependentKeys.slice(-1)[0];
const dependentValues = {}; const dependentValues = {};
let computedValue; let computedValue;

View File

@@ -1,9 +1,10 @@
import m from 'mithril';
import prop from 'mithril/stream'; import prop from 'mithril/stream';
export default () => { export default () => {
const mo = global.m; const mo = window['m'];
const m = function (comp, ...args) { const _m = function (comp, ...args) {
const node = mo.apply(this, arguments); const node = mo.apply(this, arguments);
if (!node.attrs) node.attrs = {}; if (!node.attrs) node.attrs = {};
@@ -22,13 +23,13 @@ export default () => {
return node; return node;
}; };
Object.keys(mo).forEach(key => m[key] = mo[key]); Object.keys(mo).forEach(key => _m[key] = mo[key]);
m.withAttr = (key: string, cb: Function) => function () { _m.withAttr = (key: string, cb: Function) => function () {
cb(this.getAttribute(key) || this[key]); cb(this.getAttribute(key) || this[key]);
}; };
m.prop = prop; _m.prop = prop;
global.m = m; window['m'] = _m;
} }

View File

@@ -4,8 +4,12 @@ import History from './utils/History';
import HeaderPrimary from './components/HeaderPrimary'; import HeaderPrimary from './components/HeaderPrimary';
import HeaderSecondary from './components/HeaderSecondary'; import HeaderSecondary from './components/HeaderSecondary';
import Page from './components/Page';
import IndexPage from './components/IndexPage'; import IndexPage from './components/IndexPage';
import PostsUserPage from './components/PostsUserPage'; import PostsUserPage from './components/PostsUserPage';
import User from "../common/models/User";
import Post from "../common/models/Post";
import Discussion from "../common/models/Discussion";
export default class Forum extends Application { export default class Forum extends Application {
routes = { routes = {
@@ -26,6 +30,9 @@ export default class Forum extends Application {
*/ */
history: History = new History(); history: History = new History();
previous: Page;
current: Page;
mount() { mount() {
// Get the configured default route and update that route's path to be '/'. // Get the configured default route and update that route's path to be '/'.
// Push the homepage as the first route, so that the user will always be // Push the homepage as the first route, so that the user will always be
@@ -72,7 +79,7 @@ export default class Forum extends Application {
setupRoutes() { setupRoutes() {
super.setupRoutes(); super.setupRoutes();
this.route.discussion = (discussion, near) => { this.route.discussion = (discussion: Discussion, near?: number): string => {
const slug = discussion.slug(); const slug = discussion.slug();
return this.route(near && near !== 1 ? 'discussion.near' : 'discussion', { return this.route(near && near !== 1 ? 'discussion.near' : 'discussion', {
id: discussion.id() + (slug.trim() ? '-' + slug : ''), id: discussion.id() + (slug.trim() ? '-' + slug : ''),
@@ -82,21 +89,15 @@ export default class Forum extends Application {
/** /**
* Generate a URL to a post. * Generate a URL to a post.
*
* @param {Post} post
* @return {String}
*/ */
this.route.post = post => { this.route.post = (post: Post): string => {
return this.route.discussion(post.discussion(), post.number()); return this.route.discussion(post.discussion(), post.number());
}; };
/** /**
* Generate a URL to a user. * Generate a URL to a user.
*
* @param {User} user
* @return {String}
*/ */
this.route.user = user => { this.route.user = (user: User): string => {
return this.route('user', { return this.route('user', {
username: user.username() username: user.username()
}); });

View File

@@ -21,7 +21,7 @@ export default class DiscussionsSearchSource extends SearchSource {
include: 'mostRelevantPost' include: 'mostRelevantPost'
}; };
return app.store.find('discussions', params).then(results => this.results[query] = results); return app.store.find<Discussion>('discussions', params).then(results => this.results[query] = results);
} }
view(query: string) { view(query: string) {

View File

@@ -158,7 +158,7 @@ export default class NotificationList extends Component {
const params = app.cache.notifications ? {page: {offset: app.cache.notifications.length * 10}} : null; const params = app.cache.notifications ? {page: {offset: app.cache.notifications.length * 10}} : null;
return app.store.find('notifications', params) return app.store.find<Notification>('notifications', params)
.then(this.parseResults.bind(this)) .then(this.parseResults.bind(this))
.catch(() => {}) .catch(() => {})
.then(() => { .then(() => {
@@ -170,7 +170,7 @@ export default class NotificationList extends Component {
/** /**
* Parse results and append them to the notification list. * Parse results and append them to the notification list.
*/ */
parseResults(results: Notification[]|any): Notification[]|any { parseResults(results: Notification[]): Notification[] {
app.cache.notifications = app.cache.notifications || []; app.cache.notifications = app.cache.notifications || [];
if (results.length) app.cache.notifications.push(results); if (results.length) app.cache.notifications.push(results);

View File

@@ -82,7 +82,7 @@ export default abstract class UserPage extends Page {
this.username = lowercaseUsername; this.username = lowercaseUsername;
app.store.all('users').some(user => { app.store.all<User>('users').some(user => {
if (user.username().toLowerCase() === lowercaseUsername && user.joinTime()) { if (user.username().toLowerCase() === lowercaseUsername && user.joinTime()) {
this.show(user); this.show(user);
return true; return true;

View File

@@ -27,7 +27,7 @@ export default class UsersSearchSource extends SearchSource {
query = query.toLowerCase(); query = query.toLowerCase();
const results = (this.results[query] || []) const results = (this.results[query] || [])
.concat(app.store.all<User>('users').filter((user: User) => [user.username(), user.displayName()].some(value => value.toLowerCase().substr(0, query.length) === query))) .concat(app.store.all<User>('users').filter(user => [user.username(), user.displayName()].some(value => value.toLowerCase().substr(0, query.length) === query)))
.filter((e, i, arr) => arr.lastIndexOf(e) === i) .filter((e, i, arr) => arr.lastIndexOf(e) === i)
.sort((a, b) => a.displayName().localeCompare(b.displayName())); .sort((a, b) => a.displayName().localeCompare(b.displayName()));

View File

@@ -75,8 +75,8 @@ export default {
/** /**
* Delete the user. * Delete the user.
*/ */
deleteAction() { deleteAction(this: User) {
if (confirm(app.translator.trans('core.forum.user_controls.delete_confirmation'))) { if (confirm(app.translator.transText('core.forum.user_controls.delete_confirmation'))) {
this.delete().then(() => { this.delete().then(() => {
if (app.current instanceof UserPage && app.current.user === this) { if (app.current instanceof UserPage && app.current.user === this) {
app.history.back(); app.history.back();
@@ -90,7 +90,7 @@ export default {
/** /**
* Edit the user. * Edit the user.
*/ */
editAction() { editAction(this: User) {
app.modal.show(new EditUserModal({user: this})); app.modal.show(new EditUserModal({user: this}));
} }
}; };