@@ -58,12 +58,14 @@ const Row = memo(({ index, style, data }: ListChildComponentProps
)
);
}, areEqual);
-function Logs({ dispatch, logLevel, apiConfig, logs }) {
- const [isRefreshPaused, setIsRefreshPaused] = useState(false);
+function Logs({ dispatch, logLevel, apiConfig, logs, logStreamingPaused }) {
+ const actions = useStoreActions();
const toggleIsRefreshPaused = useCallback(() => {
- isRefreshPaused ? reconnectLogs({ ...apiConfig, logLevel }) : stopLogs();
- setIsRefreshPaused((x) => !x);
- }, [isRefreshPaused, apiConfig, logLevel]);
+ logStreamingPaused ? reconnectLogs({ ...apiConfig, logLevel }) : stopLogs();
+ // being lazy here
+ // ideally we should check the result of previous operation before updating this
+ actions.app.updateAppConfig('logStreamingPaused', !logStreamingPaused);
+ }, [apiConfig, logLevel, logStreamingPaused, actions.app]);
const appendLogInternal = useCallback((log) => dispatch(appendLog(log)), [dispatch]);
useEffect(() => {
fetchLogs({ ...apiConfig, logLevel }, appendLogInternal);
@@ -97,10 +99,10 @@ function Logs({ dispatch, logLevel, apiConfig, logs }) {
: }
- mainButtonStyles={isRefreshPaused ? { background: '#e74c3c' } : {}}
+ icon={logStreamingPaused ? : }
+ mainButtonStyles={logStreamingPaused ? { background: '#e74c3c' } : {}}
style={fabPosition}
- text={isRefreshPaused ? 'Resume Refresh' : 'Pause Refresh'}
+ text={logStreamingPaused ? t('Resume Refresh') : t('Pause Refresh')}
onClick={toggleIsRefreshPaused}
>
@@ -114,6 +116,7 @@ const mapState = (s: State) => ({
logs: getLogsForDisplay(s),
logLevel: getLogLevel(s),
apiConfig: getClashAPIConfig(s),
+ logStreamingPaused: getLogStreamingPaused(s),
});
export default connect(mapState)(Logs);
diff --git a/src/components/shared/Basic.module.scss b/src/components/shared/Basic.module.scss
index 8e5a113..b8e0068 100644
--- a/src/components/shared/Basic.module.scss
+++ b/src/components/shared/Basic.module.scss
@@ -36,32 +36,30 @@ h2.sectionNameType {
*
*/
-:global {
- body.light {
- /*
+:root[data-theme='light'] {
+ /*
* --loading-dot-{dot-index}-{dot-keyframe-phase}
*/
- --loading-dot-1-1: rgba(0, 0, 0, 0.1);
- --loading-dot-1-2: rgba(0, 0, 0, 0.5);
- --loading-dot-1-3: rgba(0, 0, 0, 0.3);
- --loading-dot-2-1: rgba(0, 0, 0, 0.3);
- --loading-dot-2-2: rgba(0, 0, 0, 0.1);
- --loading-dot-2-3: rgba(0, 0, 0, 0.5);
- --loading-dot-3-1: rgba(0, 0, 0, 0.5);
- --loading-dot-3-2: rgba(0, 0, 0, 0.3);
- --loading-dot-3-3: rgba(0, 0, 0, 0.1);
- }
- body.dark {
- --loading-dot-1-1: rgba(255, 255, 255, 0.5);
- --loading-dot-1-2: rgba(255, 255, 255, 0.1);
- --loading-dot-1-3: rgba(255, 255, 255, 0.3);
- --loading-dot-2-1: rgba(255, 255, 255, 0.3);
- --loading-dot-2-2: rgba(255, 255, 255, 0.5);
- --loading-dot-2-3: rgba(255, 255, 255, 0.1);
- --loading-dot-3-1: rgba(255, 255, 255, 0.1);
- --loading-dot-3-2: rgba(255, 255, 255, 0.3);
- --loading-dot-3-3: rgba(255, 255, 255, 0.5);
- }
+ --loading-dot-1-1: rgba(0, 0, 0, 0.1);
+ --loading-dot-1-2: rgba(0, 0, 0, 0.5);
+ --loading-dot-1-3: rgba(0, 0, 0, 0.3);
+ --loading-dot-2-1: rgba(0, 0, 0, 0.3);
+ --loading-dot-2-2: rgba(0, 0, 0, 0.1);
+ --loading-dot-2-3: rgba(0, 0, 0, 0.5);
+ --loading-dot-3-1: rgba(0, 0, 0, 0.5);
+ --loading-dot-3-2: rgba(0, 0, 0, 0.3);
+ --loading-dot-3-3: rgba(0, 0, 0, 0.1);
+}
+:root[data-theme='dark'] {
+ --loading-dot-1-1: rgba(255, 255, 255, 0.5);
+ --loading-dot-1-2: rgba(255, 255, 255, 0.1);
+ --loading-dot-1-3: rgba(255, 255, 255, 0.3);
+ --loading-dot-2-1: rgba(255, 255, 255, 0.3);
+ --loading-dot-2-2: rgba(255, 255, 255, 0.5);
+ --loading-dot-2-3: rgba(255, 255, 255, 0.1);
+ --loading-dot-3-1: rgba(255, 255, 255, 0.1);
+ --loading-dot-3-2: rgba(255, 255, 255, 0.3);
+ --loading-dot-3-3: rgba(255, 255, 255, 0.5);
}
.loadingDot,
diff --git a/src/components/shared/rtf.css b/src/components/shared/rtf.css
index da439ee..574aad1 100644
--- a/src/components/shared/rtf.css
+++ b/src/components/shared/rtf.css
@@ -12,8 +12,8 @@
list-style: none;
}
.rtf.open .rtf--mb {
- box-shadow: 0px 5px 5px -3px rgba(0, 0, 0, 0.2),
- 0px 8px 10px 1px rgba(0, 0, 0, 0.14), 0px 3px 14px 2px rgba(0, 0, 0, 0.12);
+ box-shadow: 0px 5px 5px -3px rgba(0, 0, 0, 0.2), 0px 8px 10px 1px rgba(0, 0, 0, 0.14),
+ 0px 3px 14px 2px rgba(0, 0, 0, 0.12);
}
.rtf.open .rtf--mb > ul {
diff --git a/src/i18n/en.ts b/src/i18n/en.ts
index ac0aa6c..1991284 100644
--- a/src/i18n/en.ts
+++ b/src/i18n/en.ts
@@ -10,6 +10,8 @@ export const data = {
'Upload Total': 'Upload Total',
'Download Total': 'Download Total',
'Active Connections': 'Active Connections',
+ 'Pause Refresh': 'Pause Refresh',
+ 'Resume Refresh': 'Resume Refresh',
Up: 'Up',
Down: 'Down',
'Test Latency': 'Test Latency',
diff --git a/src/i18n/zh.ts b/src/i18n/zh.ts
index a8f4c05..bd035ef 100644
--- a/src/i18n/zh.ts
+++ b/src/i18n/zh.ts
@@ -10,6 +10,8 @@ export const data = {
'Upload Total': '上传总量',
'Download Total': '下载总量',
'Active Connections': '活动连接',
+ 'Pause Refresh': '暂停刷新',
+ 'Resume Refresh': '继续刷新',
Up: '上传',
Down: '下载',
'Test Latency': '延迟测速',
diff --git a/src/store/app.ts b/src/store/app.ts
index c6a455e..ea14e84 100644
--- a/src/store/app.ts
+++ b/src/store/app.ts
@@ -9,18 +9,16 @@ export const getClashAPIConfig = (s: State) => {
const idx = s.app.selectedClashAPIConfigIndex;
return s.app.clashAPIConfigs[idx];
};
-export const getSelectedClashAPIConfigIndex = (s: State) =>
- s.app.selectedClashAPIConfigIndex;
+export const getSelectedClashAPIConfigIndex = (s: State) => s.app.selectedClashAPIConfigIndex;
export const getClashAPIConfigs = (s: State) => s.app.clashAPIConfigs;
export const getTheme = (s: State) => s.app.theme;
-export const getSelectedChartStyleIndex = (s: State) =>
- s.app.selectedChartStyleIndex;
+export const getSelectedChartStyleIndex = (s: State) => s.app.selectedChartStyleIndex;
export const getLatencyTestUrl = (s: State) => s.app.latencyTestUrl;
export const getCollapsibleIsOpen = (s: State) => s.app.collapsibleIsOpen;
export const getProxySortBy = (s: State) => s.app.proxySortBy;
-export const getHideUnavailableProxies = (s: State) =>
- s.app.hideUnavailableProxies;
+export const getHideUnavailableProxies = (s: State) => s.app.hideUnavailableProxies;
export const getAutoCloseOldConns = (s: State) => s.app.autoCloseOldConns;
+export const getLogStreamingPaused = (s: State) => s.app.logStreamingPaused;
const saveStateDebounced = debounce(saveState, 600);
@@ -103,7 +101,7 @@ function setTheme(theme = 'dark') {
themeColorMeta.setAttribute('content', '#202020');
} else {
rootEl.setAttribute('data-theme', 'light');
- themeColorMeta.setAttribute('content', '#eeeeee');
+ themeColorMeta.setAttribute('content', '#f7f7f7');
}
}
@@ -121,9 +119,7 @@ export function switchTheme() {
};
}
-export function selectChartStyleIndex(
- selectedChartStyleIndex: number | string
-) {
+export function selectChartStyleIndex(selectedChartStyleIndex: number | string) {
return (dispatch: DispatchFn, getState: GetStateFn) => {
dispatch('appSelectChartStyleIndex', (s) => {
s.app.selectedChartStyleIndex = Number(selectedChartStyleIndex);
@@ -143,11 +139,7 @@ export function updateAppConfig(name: string, value: unknown) {
};
}
-export function updateCollapsibleIsOpen(
- prefix: string,
- name: string,
- v: boolean
-) {
+export function updateCollapsibleIsOpen(prefix: string, name: string, v: boolean) {
return (dispatch: DispatchFn, getState: GetStateFn) => {
dispatch('updateCollapsibleIsOpen', (s: State) => {
s.app.collapsibleIsOpen[`${prefix}:${name}`] = v;
@@ -158,9 +150,7 @@ export function updateCollapsibleIsOpen(
}
const defaultClashAPIConfig = {
- baseURL:
- document.getElementById('app')?.getAttribute('data-base-url') ??
- 'http://127.0.0.1:9090',
+ baseURL: document.getElementById('app')?.getAttribute('data-base-url') ?? 'http://127.0.0.1:9090',
secret: '',
addedAt: 0,
};
@@ -179,6 +169,7 @@ const defaultState: StateApp = {
proxySortBy: 'Natural',
hideUnavailableProxies: false,
autoCloseOldConns: false,
+ logStreamingPaused: false,
};
function parseConfigQueryString() {
diff --git a/src/store/types.ts b/src/store/types.ts
index 7e6a39d..b9141ac 100644
--- a/src/store/types.ts
+++ b/src/store/types.ts
@@ -13,6 +13,7 @@ export type StateApp = {
proxySortBy: string;
hideUnavailableProxies: boolean;
autoCloseOldConns: boolean;
+ logStreamingPaused: boolean;
};
export type ClashGeneralConfig = {