diff --git a/README-en.md b/README-en.md index d7089a5f4..52ed0250b 100644 --- a/README-en.md +++ b/README-en.md @@ -43,4 +43,4 @@ See the project, _[RoadMap](https://github.com/sheepzh/timer/projects/1)_, pls. ## Thanks -Timer - Count your browse time and visits on every sites | Product Hunt +Timer - Count your browsing time and visits on every sites | Product Hunt diff --git a/README.md b/README.md index 69c00cc4b..08fcc3277 100644 --- a/README.md +++ b/README.md @@ -16,9 +16,11 @@ - 统计用户阅读本地文件的时间 - 限制每天浏览指定网站的时间 - 网站白名单,过滤不需要统计的网站 -- 自定义域名合并统计的规则 -- 分时段统计分析用户的上网行为并以直方图展示 +- 支持多个域名合并统计,用户自定义合并规则 +- 分时段统计用户的上网行为并以直方图展示 +- 仪表盘全局数据 - 报表导出 +- 支持夜间模式 ## 下载地址 @@ -34,6 +36,8 @@ [![](https://img.shields.io/amo/rating/2690100?color=green)](https://addons.mozilla.org/en-US/firefox/addon/2690100) [![Mozilla Add-on](https://img.shields.io/amo/users/2690100?color=green)](https://addons.mozilla.org/en-US/firefox/addon/2690100) +![User Count](./script/output/user_count.svg) + ## 截图 > 弹窗页展示今日数据 diff --git a/doc/dev-guide.md b/doc/dev-guide.md index d53b69eba..447dc0472 100644 --- a/doc/dev-guide.md +++ b/doc/dev-guide.md @@ -35,6 +35,8 @@ yarn install npm run dev # or yarn run dev +# Optional to fix some error caused by node-sass +npm rebuild node-sass ``` 项目根目录下会输出两个文件夹,dist_dev 和 firefox_dev。 diff --git a/global.d.ts b/global.d.ts index fd3305f68..6d510ba59 100644 --- a/global.d.ts +++ b/global.d.ts @@ -4,114 +4,402 @@ * * @since 0.3.0 */ -declare namespace Timer { - type DataDimension = 'total' | 'focus' | 'time' - type PopupDuration = "today" | "thisWeek" | "thisMonth" - /** - * Options used for the popup page - */ - type PopupOption = { +declare namespace timer { + namespace option { + /** - * The max count of today's data to display in popup page + * Options used for the popup page */ - popupMax: number + type PopupOption = { + /** + * The max count of today's data to display in popup page + */ + popupMax: number + /** + * The default type to display + */ + defaultType: stat.Dimension + /** + * The default duration to search + * @since 0.6.0 + */ + defaultDuration: popup.Duration + /** + * Replace the host name with site name which is detected automatically from the title of site homepages, + * or modified manually by the user + * + * @since 0.5.0 + */ + displaySiteName: boolean + } + + type DarkMode = + // Always on + | "on" + // Always off + | "off" + // Timed on + | "timed" + + type AppearanceOption = { + /** + * Whether to display the whitelist button in the context menu + * + * @since 0.3.2 + */ + displayWhitelistMenu: boolean + /** + * Whether to display the badge text of focus time + * + * @since 0.3.3 + */ + displayBadgeText: boolean + /** + * The language of this extension + * + * @since 0.8.0 + */ + locale: LocaleOption + /** + * Whether to print the info in the console + * + * @since 0.8.6 + */ + printInConsole: boolean + /** + * The state of dark mode + * + * @since 1.1.0 + */ + darkMode: DarkMode + + /** + * The range of seconds to turn on dark mode. Required if {@param darkMode} is 'timed' + * + * @since 1.1.0 + */ + darkModeTimeStart?: number + darkModeTimeEnd?: number + } + + type StatisticsOption = { + /** + * Count when idle + */ + countWhenIdle: boolean + /** + * Whether to collect the site name + * + * @since 0.5.0 + */ + collectSiteName: boolean + /** + * Whether to count the local files + * @since 0.7.0 + */ + countLocalFiles: boolean + } + /** - * The default type to display + * The options of backup + * + * @since 1.2.0 */ - defaultType: DataDimension + type BackupOption = { + /** + * The type 2 backup + */ + backupType: backup.Type + /** + * The auth of types, maybe ak/sk or static token + */ + backupAuths: { [type in backup.Type]?: string } + /** + * The name of this client + */ + clientName: string + } + + type AllOption = PopupOption & AppearanceOption & StatisticsOption & BackupOption /** - * The default duration to search - * @since 0.6.0 + * @since 0.8.0 */ - defaultDuration: PopupDuration + type LocaleOption = Locale | "default" + } + + namespace meta { + type ExtensionMeta = { + installTime?: number + appCounter?: { [routePath: string]: number } + popupCounter?: { + _total?: number + } + /** + * The id of this client + * + * @since 1.2.0 + */ + cid?: string + } + } + + /** + * @since 0.8.0 + */ + type Locale = + | 'zh_CN' + | 'en' + | 'ja' + // @since 0.9.0 + | 'zh_TW' + + namespace stat { /** - * Replace the host name with site name which is detected automatically from the title of site homepages, - * or modified manually by the user - * - * @since 0.5.0 + * The dimension to statistics */ - displaySiteName: boolean - } + type Dimension = + // Running time + | 'total' + // Focus time + | 'focus' + // Visit count + | 'time' - type AppearanceOptionDarkMode = - // Always on - | "on" - // Always off - | "off" - // Timed on - | "timed" - type AppearanceOption = { /** - * Whether to display the whitelist button in the context menu + * Time waste per day * - * @since 0.3.2 + * @since 0.0.1 */ - displayWhitelistMenu: boolean + type Result = { [item in timer.stat.Dimension]: number } + /** - * Whether to display the badge text of focus time + * Waste data * * @since 0.3.3 */ - displayBadgeText: boolean + type ResultSet = { [host: string]: Result } + /** - * The language of this extension - * - * @since 0.8.0 + * The unique key of each data row */ - locale: LocaleOption + type RowKey = { + host: string + // Absent if date merged + date?: string + } + + type RowBase = RowKey & Result + /** - * Whether to print the info in the console - * - * @since 0.8.6 + * Row of each statistics result */ - printInConsole: boolean + type Row = RowBase & { + /** + * The merged domains + * + * Can't be empty if merged + * + * @since 0.1.5 + */ + mergedHosts: Row[] + /** + * Icon url + * + * Must be undefined if merged + */ + iconUrl?: string + /** + * The alias name of this Site, always is the title of its homepage by detected + */ + alias?: string + } /** - * The state of dark mode - * - * @since 1.1.0 + * @since 1.2.0 */ - darkMode: AppearanceOptionDarkMode + type RemoteRow = RowBase & { + /** + * The name of client where the remote data is storaged + */ + clientName?: string + } + } + namespace limit { /** - * The range of seconds to turn on dark mode. Required if {@param darkMode} is 'timed' - * - * @since 1.1.0 + * @since 0.8.4 */ - darkModeTimeStart?: number - darkModeTimeEnd?: number + type Item = { + /** + * Condition, can be regular expression with star signs + */ + cond: string + regular: RegExp + /** + * Time limit, seconds + */ + time: number + enabled: boolean + allowDelay: boolean + /** + * Waste today, milliseconds + */ + waste?: number + } + type Rule = { + /** + * Condition, can be regular expression with star signs + */ + cond: string + /** + * Time limit, seconds + */ + time: number + enabled: boolean + /** + * Allow to delay 5 minutes if time over + */ + allowDelay: boolean + } + type Record = Rule & { + /** + * The latest record date + */ + latestDate: string + /** + * Time wasted in the latest record date + */ + wasteTime: number + } + } + + namespace common { + type Pagination = { + size: number + num: number + total: number + } + type PageQuery = { + num?: number + size?: number + } + type PageResult = { + list: T[] + total: number + } } - type StatisticsOption = { + namespace popup { + type Duration = "today" | "thisWeek" | "thisMonth" + type Row = timer.stat.Row & { isOther?: boolean } + type QueryResult = { + type: timer.stat.Dimension + mergeHost: boolean + data: Row[] + // Filter items + chartTitle: string + date: Date | Date[] + } + type QueryResultHandler = (result: QueryResult) => void + type ChartProps = QueryResult & { + displaySiteName: boolean + } + } + + namespace app { /** - * Count when idle + * @since 1.1.7 */ - countWhenIdle: boolean + type TimeFormat = + | "default" + | "second" + | "minute" + | "hour" + + namespace trend { + type HostInfo = { + host: string + merged: boolean + } + + type FilterOption = { + host: HostInfo, + dateRange: Date[], + timeFormat: TimeFormat + } + + type RenderOption = FilterOption & { + /** + * Whether render firstly + */ + isFirst: boolean + } + } + + namespace report { + /** + * The query param of report page + */ + type QueryParam = { + /** + * Merge host + */ + mh?: string + /** + * Date start + */ + ds?: string + /** + * Date end + */ + de?: string + /** + * Sorted column + */ + sc?: timer.stat.Dimension + } + type FilterOption = { + host: string + dateRange: Date[] + mergeDate: boolean + mergeHost: boolean + /** + * @since 1.1.7 + */ + timeFormat: TimeFormat + } + } + } + + /** + * @since 1.2.0 + */ + namespace backup { + + type Type = + | 'none' + | 'gist' + /** - * Whether to collect the site name - * - * @since 0.5.0 + * Snapshot of last backup */ - collectSiteName: boolean + type Snapshot = { + /** + * Timestamp + */ + ts: number + /** + * The date of the ts + */ + date: string + } + /** - * Whether to count the local files - * @since 0.7.0 + * Snapshot cache */ - countLocalFiles: boolean - } + type SnaptshotCache = Partial<{ + [type in Type]: Snapshot + }> - type Option = PopupOption & AppearanceOption & StatisticsOption - - /** - * @since 0.8.0 - */ - type Locale = - | 'zh_CN' - | 'en' - | 'ja' - // @since 0.9.0 - | 'zh_TW' - /** - * @since 0.8.0 - */ - type LocaleOption = Locale | "default" + type MetaCache = Partial> + } } \ No newline at end of file diff --git a/package.json b/package.json index 8fc6d1eab..19f24451b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "timer", - "version": "1.1.0", + "version": "1.2.0", "description": "Web timer", "homepage": "https://github.com/sheepzh/timer", "scripts": { diff --git a/public/popup.html b/public/popup.html index 0af46d1b6..8f929eff0 100644 --- a/public/popup.html +++ b/public/popup.html @@ -85,7 +85,7 @@ -