import * as Const from './const' ; import { default as Env } from './env' ; import * as Storage from './storage' ; import * as UI from './ui' ; import * as Version from './version' ; export { Const , Env , Storage , UI , Version } ; export function dictHasDiff < T extends Record < string , any > , U extends Record < string , any > > ( o1 , o2 ) { return Object . keys ( o1 ) . some ( k => o1 [ k ] !== o2 [ k ] ) ; } export function dictDiff < T extends Record < string , any > , U extends Record < string , any > , V = { } > ( o1 , o2 , fallback ? ) { const ret = { } ; const diff = Object . keys ( o1 ) . filter ( k => o1 [ k ] !== o2 [ k ] ) ; if ( ! diff . length ) return fallback ?? ret ; diff . forEach ( ( c ) => ( ret [ c ] = o1 [ c ] ) ) ; return ret ; } export function dictDiffPartial < T extends Record < string , any > , U extends Record < string , any > , V = Partial < T > > ( o1 , o2 , fallback ? ) { const ret = { } ; const diffKeys = dictDiffPartialKeys ( o1 , o2 ) ; if ( ! diffKeys . length ) return fallback ?? ret ; diffKeys . forEach ( ( c ) => ( ret [ c ] = o1 [ c ] ) ) ; return ret ; } export function dictDiffPartialKeys < T extends Record < string , any > , U extends Record < string , any > > ( o1 , o2 ) { return Object . keys ( o1 ) . filter ( k => k in o2 && o1 [ k ] !== o2 [ k ] ) as ( keyof T ) [ ] ; } export function monitorObject < T extends object > ( initValue , onChange ) { const value = { ... initValue } as T & { update : ( next : Partial < T > , stopCall ? : boolean ) => boolean ; reset : ( stopCall ? : boolean ) => boolean ; } ; Object . defineProperties ( value , { update : { value : function ( next , stopCall = false ) { const diff = dictDiffPartial ( next , value , initValue ) ; if ( diff === initValue ) return false ; Object . assign ( value , diff ) ; if ( ! stopCall ) onChange ( value , diff ) ; return true ; } , } , reset : { value : function ( stopCall = false ) { return value . update ( initValue , stopCall ) ; } , } , } ) ; return value ; } export function dictValues < T extends Record < string , any > > ( dict ) { return Object . keys ( dict ) . map ( k => dict [ k ] ) ; } export function navQueryNotFound ( content = '无法获取当前页面' ) { wx . showModal ( { content , confirmText : '返回' , showCancel : false , title : '提示' , complete : ( ) => wx . navigateBack ( { delta : 1 } ) , } ) ; } export function truncate ( str , len = 30 , wideChar = true , omission = '...' ) { str = str . slice ( 0 , len ) ; const { length : plusLen } = wideChar ? str . match ( /[^\u0000-\u0200]/g ) || [ ] : [ ] ; if ( str . length + plusLen < len ) return str ; if ( omission . length > len ) return omission . slice ( omission . length - len ) ; return `${ str . slice ( 0 , len - omission . length - plusLen / 2 ) }${ omission }` ; } export function timeBetween ( from , to = Date . now ( ) ) { const passed = from < to ; const suffix = passed ? '前' : '后' ; let diff = passed ? to - from : from - to ; return diff < 1000 ? '刚刚' : diff < 60000 ? `${ Math . trunc ( diff / 1000 ) } 秒${ suffix }` : diff < 3600000 ? `${ Math . trunc ( diff / 60000 ) } 分钟${ suffix }` : diff < 86400000 ? `${ Math . trunc ( diff / 3600000 ) } 小时${ suffix }` : diff < 2678400000 ? `${ Math . trunc ( diff / 86400000 ) } 天${ suffix }` : diff < 31536000000 ? `${ Math . trunc ( diff / 2678400000 ) } 个月${ suffix }` : `${ Math . trunc ( diff / 31536000000 ) } 年${ suffix }` ; } export function throttle < T extends ( ... args : any [ ] ) => void > ( func , timeFrame ) { let timeout = null ; let currentArgs ; return function ( ... args ) { currentArgs = args ; if ( timeout !== null ) return ; timeout = setTimeout ( ( ) => { timeout = null ; func ( ... currentArgs ) ; } , timeFrame ) ; } ; } export class BaseMutant < D = Record < string , any > > { protected next : Record < string , any > = { } ; protected onCommit ? : ( next : Record < string , any > ) => void ; constructor ( onCommit ? ) { this . onCommit = onCommit ; } update = < T extends string | keyof D | Record < string , any > | PowerPartial < D > > ( key , value ? ) => { if ( typeof key === 'string' ) this . next [ key ] = value ; Object . assign ( this . next , key ) ; return this ; } ; commit = ( ) => { if ( this . onCommit && this . onCommit ( { ... this . next } ) ) return this ; this . flush ( ) ; return this ; } ; flush = ( ) => { this . next = { } ; return this ; } ; } export class DataMutant < D > extends BaseMutant < D > { page : Page . PageThis < D > ; constructor ( page ) { super ( ) ; this . page = page ; } commit = ( callback ? ) => { if ( ! Object . keys ( this . next ) . length ) return this ; this . page . setData ( this . next , callback ) ; this . next = { } ; return this ; } ; } export function SUUID ( length = 32 ) { if ( length < 1 ) return '' ; const chunk = Math . random ( ) . toString ( 36 ) . slice ( 2 ) ; return `${ chunk }${ SUUID ( length - chunk . length ) }` . slice ( 0 , length ) ; } export const NavbarLoading = { set : new Set < string > ( ) , show : ( identifier , timeout = 10 ) => { NavbarLoading . set . add ( identifier ) ; wx . showNavigationBarLoading ( { } ) ; setTimeout ( ( ) => NavbarLoading . hide ( identifier ) , timeout * 1000 ) ; } , hide : ( identifier ) => { if ( ! NavbarLoading . set . delete ( identifier ) ) return ; if ( ! NavbarLoading . set . size ) wx . hideNavigationBarLoading ( { } ) ; } , } ; export function createTask < T > ( ) { const ref = { } as { resolve : ( _value : T | PromiseLike < T > ) => void ; result ? : T ; task : Promise < T > ; } ; ref . task = new Promise < T > ( resolve => ( ref . resolve = resolve ) ) ; return ref ; } export function querystring ( query = { } ) { const enc = encodeURIComponent ; const keys = Object . keys ( query ) ; return keys . reduce < string [ ] > ( ( prev , curr ) => { const key = enc ( curr ) ; if ( typeof query [ curr ] === 'boolean' && ! query [ curr ] ) return prev ; if ( typeof query [ curr ] === 'undefined' || query [ curr ] === null ) return prev ; if ( ! Array . isArray ( query [ curr ] ) ) return prev . concat ( `${ key }=${ enc ( query [ curr ] ) }` ) ; return prev . concat ( query [ curr ] . map ( ( value ) => `${ key }=${ enc ( `${ value }` ) }` ) ) ; } , [ ] ) . join ( '&' ) ; }