Merge branch 'master' into firefox-api-permissions
This commit is contained in:
@@ -1,11 +1,12 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
import { useDispatch, useSelector } from 'react-redux';
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
|
|
||||||
import React from 'react';
|
|
||||||
import { configLogout, setLoggingEnabled } from '../reducers/configReducer';
|
import { configLogout, setLoggingEnabled } from '../reducers/configReducer';
|
||||||
import { userLogout } from '../reducers/currentUser';
|
|
||||||
import { ReduxSelector } from '../types/store';
|
import { ReduxSelector } from '../types/store';
|
||||||
import { User } from '../types/user';
|
import { User } from '../types/user';
|
||||||
import changeExtensionState from '../utils/changeExtensionStatus';
|
import changeExtensionState from '../utils/changeExtensionStatus';
|
||||||
|
import { userLogout } from '../reducers/currentUser';
|
||||||
|
|
||||||
export interface MainListProps {
|
export interface MainListProps {
|
||||||
loggingEnabled: boolean;
|
loggingEnabled: boolean;
|
||||||
|
|||||||
@@ -22,11 +22,12 @@ export default function NavBar(): JSX.Element {
|
|||||||
|
|
||||||
const customRules = () => {
|
const customRules = () => {
|
||||||
if (user) {
|
if (user) {
|
||||||
|
const url = 'https://wakatime.com';
|
||||||
return (
|
return (
|
||||||
<li className="mb-2">
|
<li className="mb-2">
|
||||||
<a
|
<a
|
||||||
target="_blank"
|
target="_blank"
|
||||||
href="https://wakatime.com/settings/rules"
|
href={`${url}/settings/rules`}
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
className="text-body-secondary link-underline link-underline-opacity-0 d-flex w-100 align-items-center"
|
className="text-body-secondary link-underline link-underline-opacity-0 d-flex w-100 align-items-center"
|
||||||
>
|
>
|
||||||
@@ -42,11 +43,12 @@ export default function NavBar(): JSX.Element {
|
|||||||
|
|
||||||
const dashboard = () => {
|
const dashboard = () => {
|
||||||
if (user) {
|
if (user) {
|
||||||
|
const url = 'https://wakatime.com';
|
||||||
return (
|
return (
|
||||||
<li className="mb-2">
|
<li className="mb-2">
|
||||||
<a
|
<a
|
||||||
target="_blank"
|
target="_blank"
|
||||||
href="https://wakatime.com/dashboard"
|
href={url}
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
className="text-body-secondary link-underline link-underline-opacity-0 d-flex w-100 align-items-center"
|
className="text-body-secondary link-underline link-underline-opacity-0 d-flex w-100 align-items-center"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
import { openDB } from 'idb';
|
|
||||||
import browser, { Tabs } from 'webextension-polyfill';
|
import browser, { Tabs } from 'webextension-polyfill';
|
||||||
/* eslint-disable no-fallthrough */
|
import { openDB } from 'idb';
|
||||||
/* eslint-disable default-case */
|
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import { v4 as uuid4 } from 'uuid';
|
import { v4 as uuid4 } from 'uuid';
|
||||||
import { OptionalHeartbeat } from '../types/sites';
|
|
||||||
import { changeExtensionStatus } from '../utils/changeExtensionStatus';
|
|
||||||
import getDomainFromUrl, { getDomain } from '../utils/getDomainFromUrl';
|
|
||||||
import { getOperatingSystem, IS_EDGE, IS_FIREFOX } from '../utils/operatingSystem';
|
|
||||||
import { getSettings, Settings } from '../utils/settings';
|
|
||||||
import { getApiUrl } from '../utils/user';
|
|
||||||
|
|
||||||
import config, { ExtensionStatus } from '../config/config';
|
import config, { ExtensionStatus } from '../config/config';
|
||||||
import { EntityType, Heartbeat, HeartbeatsBulkResponse } from '../types/heartbeats';
|
import { EntityType, Heartbeat, HeartbeatsBulkResponse } from '../types/heartbeats';
|
||||||
|
import getDomainFromUrl, { getDomain } from '../utils/getDomainFromUrl';
|
||||||
|
import { IS_EDGE, IS_FIREFOX, getOperatingSystem } from '../utils/operatingSystem';
|
||||||
|
import { Settings, getApiUrl, getSettings } from '../utils/settings';
|
||||||
|
|
||||||
|
import { OptionalHeartbeat } from '../types/sites';
|
||||||
|
import { changeExtensionStatus } from '../utils/changeExtensionStatus';
|
||||||
|
|
||||||
|
/* eslint-disable no-fallthrough */
|
||||||
|
/* eslint-disable default-case */
|
||||||
|
|
||||||
class WakaTimeCore {
|
class WakaTimeCore {
|
||||||
tabsWithDevtoolsOpen: Tabs.Tab[];
|
tabsWithDevtoolsOpen: Tabs.Tab[];
|
||||||
@@ -185,7 +185,7 @@ class WakaTimeCore {
|
|||||||
const request: RequestInit = {
|
const request: RequestInit = {
|
||||||
body: JSON.stringify(
|
body: JSON.stringify(
|
||||||
heartbeats.map((heartbeat) => {
|
heartbeats.map((heartbeat) => {
|
||||||
return { ...heartbeat, userAgent };
|
return { ...heartbeat, plugin: userAgent };
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
credentials: 'omit',
|
credentials: 'omit',
|
||||||
|
|||||||
@@ -33,5 +33,5 @@
|
|||||||
"page": "options.html"
|
"page": "options.html"
|
||||||
},
|
},
|
||||||
"permissions": ["alarms", "tabs", "storage", "activeTab"],
|
"permissions": ["alarms", "tabs", "storage", "activeTab"],
|
||||||
"version": "4.0.9"
|
"version": "4.0.12"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,5 +33,5 @@
|
|||||||
"page": "options.html"
|
"page": "options.html"
|
||||||
},
|
},
|
||||||
"permissions": ["alarms", "tabs", "storage", "activeTab"],
|
"permissions": ["alarms", "tabs", "storage", "activeTab"],
|
||||||
"version": "4.0.9"
|
"version": "4.0.12"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,5 +40,5 @@
|
|||||||
},
|
},
|
||||||
"permissions": ["alarms", "tabs", "storage", "activeTab", "https://api.wakatime.com/*", "https://wakatime.com/*"],
|
"permissions": ["alarms", "tabs", "storage", "activeTab", "https://api.wakatime.com/*", "https://wakatime.com/*"],
|
||||||
"optional_permissions": ["<all_urls>"],
|
"optional_permissions": ["<all_urls>"],
|
||||||
"version": "4.0.9"
|
"version": "4.0.12"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
import { createAsyncThunk, createSlice } from '@reduxjs/toolkit';
|
import { createAsyncThunk, createSlice } from '@reduxjs/toolkit';
|
||||||
import axios, { AxiosResponse } from 'axios';
|
import axios, { AxiosResponse } from 'axios';
|
||||||
import browser from 'webextension-polyfill';
|
import browser from 'webextension-polyfill';
|
||||||
import config from '../config/config';
|
|
||||||
import { CurrentUser, User, UserPayload } from '../types/user';
|
import { CurrentUser, User, UserPayload } from '../types/user';
|
||||||
import { getApiUrl } from '../utils/user';
|
|
||||||
|
import config from '../config/config';
|
||||||
|
import { getApiUrl } from '../utils/settings';
|
||||||
|
|
||||||
interface setUserAction {
|
interface setUserAction {
|
||||||
payload: User | undefined;
|
payload: User | undefined;
|
||||||
|
|||||||
@@ -88,3 +88,21 @@ export const saveSettings = async (settings: Settings): Promise<void> => {
|
|||||||
});
|
});
|
||||||
await browser.storage.sync.set(settings);
|
await browser.storage.sync.set(settings);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getApiUrl = async () => {
|
||||||
|
const settings = await browser.storage.sync.get({
|
||||||
|
apiUrl: config.apiUrl,
|
||||||
|
});
|
||||||
|
let apiUrl = (settings.apiUrl as string) || config.apiUrl;
|
||||||
|
const suffixes = ['/', '.bulk', '/users/current/heartbeats', '/heartbeats', '/heartbeat'];
|
||||||
|
for (const suffix of suffixes) {
|
||||||
|
if (apiUrl.endsWith(suffix)) {
|
||||||
|
apiUrl = apiUrl.slice(0, -suffix.length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return apiUrl;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getWebsiteUrl = async () => {
|
||||||
|
return (await getApiUrl()).replace('/api/v1', '').replace('://api.', '://');
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,28 +1,15 @@
|
|||||||
import { AnyAction, Dispatch } from '@reduxjs/toolkit';
|
import { AnyAction, Dispatch } from '@reduxjs/toolkit';
|
||||||
import axios, { AxiosResponse } from 'axios';
|
import axios, { AxiosResponse } from 'axios';
|
||||||
import browser from 'webextension-polyfill';
|
|
||||||
|
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import config from '../config/config';
|
import browser from 'webextension-polyfill';
|
||||||
import { setApiKey, setLoggingEnabled, setTotalTimeLoggedToday } from '../reducers/configReducer';
|
import { setApiKey, setLoggingEnabled, setTotalTimeLoggedToday } from '../reducers/configReducer';
|
||||||
import { setUser } from '../reducers/currentUser';
|
|
||||||
import { GrandTotal, Summaries } from '../types/summaries';
|
import { GrandTotal, Summaries } from '../types/summaries';
|
||||||
import { ApiKeyPayload, AxiosUserResponse, User } from '../types/user';
|
import { ApiKeyPayload, AxiosUserResponse, User } from '../types/user';
|
||||||
import changeExtensionState from './changeExtensionStatus';
|
|
||||||
|
|
||||||
export const getApiUrl = async () => {
|
import config from '../config/config';
|
||||||
const settings = await browser.storage.sync.get({
|
import { setUser } from '../reducers/currentUser';
|
||||||
apiUrl: config.apiUrl,
|
import changeExtensionState from './changeExtensionStatus';
|
||||||
});
|
import { getApiUrl } from './settings';
|
||||||
let apiUrl = (settings.apiUrl as string) || config.apiUrl;
|
|
||||||
const suffixes = ['/', '.bulk', '/users/current/heartbeats', '/heartbeats', '/heartbeat'];
|
|
||||||
for (const suffix of suffixes) {
|
|
||||||
if (apiUrl.endsWith(suffix)) {
|
|
||||||
apiUrl = apiUrl.slice(0, -suffix.length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return apiUrl;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the user is logged in.
|
* Checks if the user is logged in.
|
||||||
|
|||||||
Reference in New Issue
Block a user