From a295613595a19c7d452e5e0214b626e31f260184 Mon Sep 17 00:00:00 2001 From: czy0729 <402731062@qq.com> Date: Tue, 10 May 2022 07:29:34 +0800 Subject: [PATCH] =?UTF-8?q?-=20=E6=94=AF=E6=8C=81=20@magma=20=E6=8F=90?= =?UTF-8?q?=E4=BE=9B=E7=9A=84=E7=AC=AC=E4=B8=89=E6=96=B9OSS=E5=9F=9F?= =?UTF-8?q?=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- android/app/build.gradle | 10 +- config.js | 20 +- .../@/react-native-render-html/src/HTML.js | 81 +++--- src/components/image/index.tsx | 80 ++++-- src/components/switch-pro/index.tsx | 39 ++- src/constants/cdn.js | 27 +- src/constants/model.js | 6 +- src/screens/home/subject/header-title.js | 6 +- src/screens/user/qiafan/index.js | 4 +- src/screens/user/setting/cdn.js | 270 ++++++++++++------ src/screens/user/setting/styles.js | 6 +- src/utils/app.ts | 11 +- src/utils/crypto.ts | 22 ++ tsconfig.json | 90 ++---- 14 files changed, 404 insertions(+), 268 deletions(-) create mode 100644 src/utils/crypto.ts diff --git a/android/app/build.gradle b/android/app/build.gradle index 631b6abcb..b10edf59e 100755 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -222,15 +222,11 @@ dependencies { implementation 'com.umeng.umsdk:analytics:8.0.0' // 统计 // 如果你需要支持GIF动图 - // implementation "com.facebook.fresco:animated-gif:2.0.0" + implementation "com.facebook.fresco:animated-gif:2.0.0" // 如果你需要支持WebP格式,包括WebP动图 - // implementation "com.facebook.fresco:animated-webp:2.1.0" - // implementation "com.facebook.fresco:webpsupport:2.0.0" - - // implementation project(':react-native-fs') - // implementation project(':rn-fetch-blob') - // implementation project(':@react-native-community_cameraroll') + implementation "com.facebook.fresco:animated-webp:2.1.0" + implementation "com.facebook.fresco:webpsupport:2.0.0" debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") { exclude group:'com.facebook.fbjni' diff --git a/config.js b/config.js index 33eaf5686..4dd73ae4e 100755 --- a/config.js +++ b/config.js @@ -1,18 +1,26 @@ /* + * 开发调试时用配置 * @Author: czy0729 * @Date: 2019-06-02 14:42:28 * @Last Modified by: czy0729 - * @Last Modified time: 2022-04-28 19:45:57 + * @Last Modified time: 2022-05-10 07:25:34 */ -export const INIT_DEV_DARK = '' // '' 不控制 | true 强制黑暗 | false 强制白天 +/** 强制主题模式: '' => 不控制 | true => 强制黑暗 | false => 强制白天 */ +export const INIT_DEV_DARK = '' + +/** 初始路由 */ export const INIT_ROUTE = 'Home' -export const RERENDER_SHOW = /ZZZ/ -// export const RERENDER_SHOW = /Rakuen\.(.+?)\.Main/ -// 是否开发模式 +/** 观察组件 re-render 用 */ +export const RERENDER_SHOW = /ZZZ/ // /Rakuen\.(.+?)\.Main/ + +/** 是否开发模式 */ export const DEV = global.__DEV__ -export const TEXT_ONLY = DEV +/** 开发模式中是否不显示图片 */ +export const TEXT_ONLY = DEV ? !DEV : false + +/** 路由覆盖配置 */ export default { initialRouteName: 'HomeTab', // HomeTab Discovery Subject Tinygrail BilibiliSync initialRouteParams: { diff --git a/src/components/@/react-native-render-html/src/HTML.js b/src/components/@/react-native-render-html/src/HTML.js index c5394f094..69705f21c 100755 --- a/src/components/@/react-native-render-html/src/HTML.js +++ b/src/components/@/react-native-render-html/src/HTML.js @@ -3,11 +3,10 @@ * @Author: czy0729 * @Date: 2019-08-14 16:25:55 * @Last Modified by: czy0729 - * @Last Modified time: 2021-10-23 10:51:02 + * @Last Modified time: 2022-05-09 13:27:11 */ import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' -import { View, Text, ViewPropTypes, ActivityIndicator, Dimensions } from 'react-native' +import { View, Text, ActivityIndicator, Dimensions } from 'react-native' import { cssStringToRNStyle, _getElementClassStyles, @@ -34,39 +33,39 @@ import { IOS } from '@constants' import * as HTMLRenderers from './HTMLRenderers' export default class HTML extends PureComponent { - static propTypes = { - renderers: PropTypes.object.isRequired, - ignoredTags: PropTypes.array.isRequired, - ignoredStyles: PropTypes.array.isRequired, - allowedStyles: PropTypes.array, - decodeEntities: PropTypes.bool.isRequired, - debug: PropTypes.bool.isRequired, - listsPrefixesRenderers: PropTypes.object, - ignoreNodesFunction: PropTypes.func, - alterData: PropTypes.func, - alterChildren: PropTypes.func, - alterNode: PropTypes.func, - html: PropTypes.string, - uri: PropTypes.string, - tagsStyles: PropTypes.object, - classesStyles: PropTypes.object, - containerStyle: ViewPropTypes ? ViewPropTypes.style : View.propTypes.style, - customWrapper: PropTypes.func, - onLinkPress: PropTypes.func, - onParsed: PropTypes.func, - imagesMaxWidth: PropTypes.number, - staticContentMaxWidth: PropTypes.number, - imagesInitialDimensions: PropTypes.shape({ - width: PropTypes.number, - height: PropTypes.number - }), - emSize: PropTypes.number.isRequired, - ptSize: PropTypes.number.isRequired, - baseFontStyle: PropTypes.object.isRequired, - textSelectable: PropTypes.bool, - renderersProps: PropTypes.object, - allowFontScaling: PropTypes.bool - } + // static propTypes = { + // renderers: PropTypes.object.isRequired, + // ignoredTags: PropTypes.array.isRequired, + // ignoredStyles: PropTypes.array.isRequired, + // allowedStyles: PropTypes.array, + // decodeEntities: PropTypes.bool.isRequired, + // debug: PropTypes.bool.isRequired, + // listsPrefixesRenderers: PropTypes.object, + // ignoreNodesFunction: PropTypes.func, + // alterData: PropTypes.func, + // alterChildren: PropTypes.func, + // alterNode: PropTypes.func, + // html: PropTypes.string, + // uri: PropTypes.string, + // tagsStyles: PropTypes.object, + // classesStyles: PropTypes.object, + // containerStyle: ViewPropTypes ? ViewPropTypes.style : View.propTypes.style, + // customWrapper: PropTypes.func, + // onLinkPress: PropTypes.func, + // onParsed: PropTypes.func, + // imagesMaxWidth: PropTypes.number, + // staticContentMaxWidth: PropTypes.number, + // imagesInitialDimensions: PropTypes.shape({ + // width: PropTypes.number, + // height: PropTypes.number + // }), + // emSize: PropTypes.number.isRequired, + // ptSize: PropTypes.number.isRequired, + // baseFontStyle: PropTypes.object.isRequired, + // textSelectable: PropTypes.bool, + // renderersProps: PropTypes.object, + // allowFontScaling: PropTypes.bool + // } static defaultProps = { renderers: HTMLRenderers, @@ -142,7 +141,7 @@ export default class HTML extends PureComponent { loadingRemoteURL: true, errorLoadingRemoteURL: false }) - let response = await fetch(uri) + const response = await fetch(uri) this.setState({ dom: response._bodyText, loadingRemoteURL: false }) } catch (err) { console.warn(err) @@ -238,11 +237,11 @@ export default class HTML extends PureComponent { TEXT_TAGS_IGNORING_ASSOCIATION.indexOf(child.parent.name) === -1) ) { // Texts outside

or not

themselves (with siblings) - let wrappedTexts = [] + const wrappedTexts = [] for (let j = i; j < children.length; j++) { // Loop on its next siblings and store them in an array // until we encounter a block or a

- let nextSibling = children[j] + const nextSibling = children[j] if ( nextSibling.wrapper !== 'Text' || TEXT_TAGS_IGNORING_ASSOCIATION.indexOf(nextSibling.tagName) !== -1 @@ -292,7 +291,7 @@ export default class HTML extends PureComponent { tagsStyles, classesStyles } = props - let RNElements = DOMNodes.map((node, nodeIndex) => { + const RNElements = DOMNodes.map((node, nodeIndex) => { let { children, data } = node if (ignoreNodesFunction && ignoreNodesFunction(node, parentTag) === true) { return false @@ -436,7 +435,7 @@ export default class HTML extends PureComponent { ...cssStringToObject(attribs.style || '') } - let textChildrenInheritedStyles = {} + const textChildrenInheritedStyles = {} Object.keys(wrapperStyles).forEach(styleKey => { // Extract text-only styles if (TextOnlyPropTypes.indexOf(styleKey) !== -1) { diff --git a/src/components/image/index.tsx b/src/components/image/index.tsx index 9d04397a5..8022391e9 100644 --- a/src/components/image/index.tsx +++ b/src/components/image/index.tsx @@ -7,10 +7,12 @@ * 5. 错误处理 * 6. 自动选择Bangumi图片质量 * 7. 联动ImageViewer + * 8. 支持 @magma 提供的 [bgm_poster] 后缀 + * * @Author: czy0729 * @Date: 2019-03-15 06:17:18 * @Last Modified by: czy0729 - * @Last Modified time: 2022-05-08 01:41:21 + * @Last Modified time: 2022-05-09 17:08:02 */ import React from 'react' import { View, Image as RNImage } from 'react-native' @@ -31,11 +33,13 @@ import { Text } from '../text' import CompImage from './image' import { memoStyles } from './styles' import { Props } from './types' +import { getTimestamp } from '@utils' -const defaultHeaders = { +const DEFAULT_HEADERS = { Referer: `${HOST}/` } -const maxErrorCount = 2 // 最大失败重试次数 +const MAX_ERROR_COUNT = 4 // 最大失败重试次数 +const RETRY_DISTANCE = 4000 // 重试间隔 export const Image = observer( class extends React.Component { @@ -153,24 +157,32 @@ export const Image = observer( } res = CacheManager.get(_src, { + // @ts-ignore headers: this.headers }).getPath() const path = await res - this.setState({ - uri: path || _src - }) + + /** + * magma的cdn要单独对第一次对象存储镜像做延迟处理 + * 需要再重新请求一遍 + * @date 202205009 + */ + if ( + typeof _src === 'string' && + _src.includes('/bgm_poster') && + path === undefined + ) { + setTimeout(() => { + this.retry(src) + }, RETRY_DISTANCE) + } else { + this.setState({ + uri: path || _src + }) + } } } catch (error) { - // 图片是不是会下载失败, 当错误次数大于maxErrorCount就认为是错误 - if (this.errorCount < maxErrorCount) { - this.timeoutId = setTimeout(() => { - this.errorCount += 1 - this.cache(src) - }, 400) - } else { - this.timeoutId = null - this.onError() - } + this.retry(src) } } else { uri = src @@ -192,6 +204,21 @@ export const Image = observer( return res } + /** + * 图片是不是会下载失败, 当错误次数大于MAX_ERROR_COUNT就认为是错误 + */ + retry = src => { + if (this.errorCount < MAX_ERROR_COUNT) { + this.timeoutId = setTimeout(() => { + this.errorCount += 1 + this.cache(src) + }, 400) + } else { + this.timeoutId = null + this.onError() + } + } + /** * 选择图片质量 */ @@ -236,6 +263,14 @@ export const Image = observer( * 加载失败 */ onError = () => { + const { src } = this.props + if (!IOS && typeof src === 'string' && src.includes('/bgm_poster')) { + setTimeout(() => { + this.retry(`${src}?ts=${getTimestamp()}`) + }, RETRY_DISTANCE) + return + } + this.setState( { error: true @@ -247,17 +282,20 @@ export const Image = observer( ) } - get headers() { + get headers(): {} { const { src, headers } = this.props if (headers) { - return { - ...defaultHeaders, - ...headers + if (typeof src === 'string' && src.includes('lain.')) { + return { + ...DEFAULT_HEADERS, + ...(headers || {}) + } } + return headers } if (typeof src === 'string' && src.includes('lain.')) { - return defaultHeaders + return DEFAULT_HEADERS } return {} diff --git a/src/components/switch-pro/index.tsx b/src/components/switch-pro/index.tsx index 725ee97d7..9607c684a 100755 --- a/src/components/switch-pro/index.tsx +++ b/src/components/switch-pro/index.tsx @@ -4,37 +4,30 @@ * @Author: czy0729 * @Date: 2020-06-24 22:32:09 * @Last Modified by: czy0729 - * @Last Modified time: 2022-05-07 13:06:06 + * @Last Modified time: 2022-05-09 13:26:17 */ import React, { Component } from 'react' -import PropTypes from 'prop-types' -import { - ViewPropTypes, - ColorPropType, - Animated, - Easing, - PanResponder -} from 'react-native' +import { Animated, Easing, PanResponder } from 'react-native' import { observer } from 'mobx-react' import { _ } from '@stores' const SCALE = 6 / 5 class SwitchProComp extends Component { - static propTypes = { - style: ViewPropTypes.style, - circleStyle: ViewPropTypes.style, - width: PropTypes.number, - height: PropTypes.number, - value: PropTypes.bool, - disabled: PropTypes.bool, - circleColorActive: ColorPropType, - circleColorInactive: ColorPropType, - backgroundActive: ColorPropType, - backgroundInactive: ColorPropType, - onAsyncPress: PropTypes.func, - onSyncPress: PropTypes.func - } + // static propTypes = { + // style: ViewPropTypes.style, + // circleStyle: ViewPropTypes.style, + // width: PropTypes.number, + // height: PropTypes.number, + // value: PropTypes.bool, + // disabled: PropTypes.bool, + // circleColorActive: ColorPropType, + // circleColorInactive: ColorPropType, + // backgroundActive: ColorPropType, + // backgroundInactive: ColorPropType, + // onAsyncPress: PropTypes.func, + // onSyncPress: PropTypes.func + // } static defaultProps = { width: 52, diff --git a/src/constants/cdn.js b/src/constants/cdn.js index ab09a749a..792881f94 100755 --- a/src/constants/cdn.js +++ b/src/constants/cdn.js @@ -9,12 +9,13 @@ * @Author: czy0729 * @Date: 2020-01-17 11:59:14 * @Last Modified by: czy0729 - * @Last Modified time: 2022-04-14 10:26:44 + * @Last Modified time: 2022-05-10 05:17:28 */ import { getTimestamp } from '@utils/utils' import { getStorage, setStorage } from '@utils/storage' import { getSystemStoreAsync } from '@utils/async' import { xhrCustom } from '@utils/fetch' +import Crypto from '@utils/crypto' import _hash from '@utils/thirdParty/hash' import hashSubject from '@constants/json/hash/subject.min.json' import hashAvatar from '@constants/json/hash/avatar.min.json' @@ -462,6 +463,30 @@ export const CDN_OSS_SUBJECT = (src, cdnOrigin) => { return src } +let CDN_MAGMA +export const CDN_OSS_MAGMA_POSTER = (mediumSrc = '') => { + if ( + typeof mediumSrc !== 'string' || + mediumSrc === '' || + !mediumSrc.includes('/c/') || + /\/(photo|user|icon)\/|_(crt|prsn)_/.test(mediumSrc) + ) { + return mediumSrc + } + + const poster = mediumSrc.split('/c/')?.[1] || '' + if (!poster) return mediumSrc + + if (!CDN_MAGMA) { + CDN_MAGMA = Crypto.get( + 'U2FsdGVkX19ijFHqvLmjqk2TrA/nstbTOXP4RBMFgmACzrGwUBW4kFpYB8QBtsh5' + ) + } + if (!CDN_MAGMA) return mediumSrc + + return `${CDN_MAGMA}/pic/cover/l/${poster.split('?')[0]}/bgm_poster` +} + /* ==================== tinygrail xsb relation ==================== */ let xsbRelationOTA = { name: {}, diff --git a/src/constants/model.js b/src/constants/model.js index 4ff7baa3a..aa94a78f8 100755 --- a/src/constants/model.js +++ b/src/constants/model.js @@ -4,7 +4,7 @@ * @Author: czy0729 * @Date: 2019-03-17 02:45:37 * @Last Modified by: czy0729 - * @Last Modified time: 2022-04-10 12:03:36 + * @Last Modified time: 2022-05-09 14:15:41 */ class Model { constructor(data) { @@ -564,6 +564,10 @@ export const MODEL_SETTING_CDN_ORIGIN = new Model([ { label: 'OneDrive', value: 'OneDrive' + }, + { + label: 'magma', + value: 'magma' } ]) diff --git a/src/screens/home/subject/header-title.js b/src/screens/home/subject/header-title.js index db89a0a6c..66279c7d5 100755 --- a/src/screens/home/subject/header-title.js +++ b/src/screens/home/subject/header-title.js @@ -2,15 +2,13 @@ * @Author: czy0729 * @Date: 2020-06-12 10:43:32 * @Last Modified by: czy0729 - * @Last Modified time: 2022-04-11 11:48:40 + * @Last Modified time: 2022-05-09 15:46:34 */ import React from 'react' import { Flex, Text } from '@components' import { Cover, Stars } from '@_' import { _ } from '@stores' import { memo, ob } from '@utils/decorators' -import { getCoverMedium } from '@utils/app' -import { CDN_OSS_SUBJECT } from '@constants/cdn' const imgWidth = 28 const imgHeight = imgWidth * 1.28 @@ -28,7 +26,7 @@ const HeaderTitle = memo(({ common, score, type, cn, titleLabel }) => { return ( {   还是那句话,用户的支持就是作者继续开发下去的动力,觉得好用的不忘到github上给星星或分发平台(如酷安)上打分,这些无形的资产也许会对作者日后的职业生涯产生重要的帮助。 -   2022年以来,因为网络上面的各种你懂的原因,维护App的正常使用变得异常的困难,目前有打算使用一点资金,在后续的版本中提供更加快速稳定的内容访问服务。话我就说白了,后续会开发更多的专属于会员的服务,因为实在需要米作为开发的动力。 +   2022年以来,因各种你懂的原因,且不说开发新功能,有时候因很多突发的问题,维护App的正常使用就已经使人心力交瘁。目前有打算使用一点资金,在后续的版本中提供更加快速稳定的内容访问服务。话我就说白了,后续会开发更多的专属于会员的服务,因为实在需要米作为开发的动力。   2022/04/20 diff --git a/src/screens/user/setting/cdn.js b/src/screens/user/setting/cdn.js index 57ef87346..546777e77 100644 --- a/src/screens/user/setting/cdn.js +++ b/src/screens/user/setting/cdn.js @@ -2,17 +2,20 @@ * @Author: czy0729 * @Date: 2022-01-19 10:32:18 * @Last Modified by: czy0729 - * @Last Modified time: 2022-04-10 12:22:06 + * @Last Modified time: 2022-05-10 07:24:24 */ import React, { useState, useEffect } from 'react' +import { View } from 'react-native' import { ActionSheet, Flex, Text, SwitchPro, Heatmap } from '@components' import { clearCache } from '@components/image/image' +import { IconTouchable } from '@_' import { ItemSetting, ItemSettingBlock, Cover } from '@_' import { _, systemStore } from '@stores' import { useObserver, useBoolean } from '@utils/hooks' import { t, ping } from '@utils/fetch' -import { info } from '@utils/ui' +import { info, alert } from '@utils/ui' import { MODEL_SETTING_CDN_ORIGIN } from '@constants/model' +import { CDN_OSS_MAGMA_POSTER } from '@constants/cdn' import styles from './styles' const URL_LAIN = 'https://lain.bgm.tv/pic/cover/c/fa/1d/25833_kZIjD.jpg' @@ -20,26 +23,30 @@ const URL_JSDELIVR = 'https://cdn.jsdelivr.net/gh/czy0729/Bangumi-OSS@master/data/subject/c/t/TfOdAB.jpg' const URL_FASTLY = URL_JSDELIVR.replace('cdn', 'fastly') const URL_ONEDRIVE = 'https://bangumi.stdcdn.com/subject/c/t/TfOdAB.jpg' -const IMG_WIDTH = parseInt((_.window.contentWidth - 2 * _.md) / 4) +const IMG_WIDTH = parseInt((_.window.contentWidth - 2 * _.md) / 3) const IMG_HEIGHT = parseInt(IMG_WIDTH * 1.44) function CDN() { const { state, setTrue, setFalse } = useBoolean(false) const [test, setTest] = useState(false) - const [pings, setPings] = useState([]) + const [deprecated, setDeprecated] = useState(false) + const [pings, setPings] = useState({}) + useEffect(() => { if (test && !pings.length) { - const data = [] + const data = {} async function cb() { - data.push(await ping(URL_LAIN)) - data.push(await ping(URL_FASTLY)) - data.push(await ping(URL_JSDELIVR)) - if (systemStore.advance) data.push(await ping(URL_ONEDRIVE)) + data.lain = await ping(URL_LAIN) + data.magma = await ping(CDN_OSS_MAGMA_POSTER(URL_LAIN)) + data.onedrive = await ping(URL_ONEDRIVE) + data.jsdelivr = await ping(URL_JSDELIVR) + data.fastly = await ping(URL_FASTLY) setPings(data) } cb() } - }, [test, pings]) + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [test]) return useObserver(() => { const { cdn, cdnOrigin, cdnAvatar } = systemStore.setting @@ -61,7 +68,7 @@ function CDN() { onPress={setTrue} /> - + {/* 封面加速 */} { if (!cdn) return @@ -89,23 +96,24 @@ function CDN() { }} /> { - if (cdn && origin === 'fastly') return + if (cdn && origin === 'OneDrive') return + if (!systemStore.advance) return info('此域名仅对高级会员开放') t('设置.切换', { title: 'CDN加速', checked: !cdn, - origin: 'fastly' + origin: 'OneDrive' }) if (!cdn) systemStore.switchSetting('cdn') systemStore.setSetting( 'cdnOrigin', - MODEL_SETTING_CDN_ORIGIN.getValue('fastly') + MODEL_SETTING_CDN_ORIGIN.getValue('OneDrive') ) setTimeout(() => { @@ -113,50 +121,29 @@ function CDN() { }, 0) }} /> - { - if (cdn && origin === 'jsDelivr') return - - t('设置.切换', { - title: 'CDN加速', - checked: !cdn, - origin: 'jsDelivr' - }) - - if (!cdn) systemStore.switchSetting('cdn') - systemStore.setSetting( - 'cdnOrigin', - MODEL_SETTING_CDN_ORIGIN.getValue('jsDelivr') - ) + + - setTimeout(() => { - clearCache() - }, 0) - }} - /> + {/* Magma */} + { - if (cdn && origin === 'OneDrive') return + if (cdn && origin === 'magma') return if (!systemStore.advance) return info('此域名仅对高级会员开放') t('设置.切换', { title: 'CDN加速', checked: !cdn, - origin: 'OneDrive' + origin: 'magma' }) if (!cdn) systemStore.switchSetting('cdn') systemStore.setSetting( 'cdnOrigin', - MODEL_SETTING_CDN_ORIGIN.getValue('OneDrive') + MODEL_SETTING_CDN_ORIGIN.getValue('magma') ) setTimeout(() => { @@ -164,32 +151,32 @@ function CDN() { }, 0) }} /> - + + + + alert( + `此域名为用户 @magma 提供,支持所有封面图,并自带缩放压缩、webp、稳定CDN加速 + \n作者与其达成了某种约定,因流量是需要自费的,目前仅对历史打赏达到10元的高级会员开放,恳请谅解 + \n后续会观察使用的流量数据,可能会放宽限制 + \n更多使用详情说明,目前OSS 1G的费用大概是0.2元,1个用户首次访问10-20个路径的页面,封面图可能会产生50-100MB的流量 + \n若漏算了历史打赏金额的,可以私信作者`, + '关于Magma' + ) + } + /> + + - {/* 头像加速 */} - { - t('设置.切换', { - title: '头像加速', - checked: !cdnAvatar - }) - - systemStore.switchSetting('cdnAvatar') - }} - /> - } - information='其他用户头像使用清晰快照,但不会实时更新' - /> - {/* 测试 */} - + {test ? ( <> @@ -202,20 +189,7 @@ function CDN() { radius /> - lain.bgm.tv: {pings[0] || 0}ms - - - - - - - - fastly: {pings[1] || 0}ms + lain.bgm.tv: {pings.lain || 0}ms @@ -224,11 +198,11 @@ function CDN() { - jsDelivr: {pings[1] || 0}ms + Magma: {pings.magma || 0}ms @@ -241,7 +215,7 @@ function CDN() { radius /> - OneDrive: {pings[2] || 0}ms + OneDrive: {pings.onedrive || 0}ms @@ -260,6 +234,122 @@ function CDN() { )} + {test && ( + + + + + + jsDelivr: {pings.jsdelivr || 0}ms + + + + + + + + fastly: {pings.fastly || 0}ms + + + + + + )} + + {/* 旧版本域 */} + + setDeprecated(!deprecated)} + > + [待废弃] + 因国内访问困难无法恢复,v6.2.5以后不再维护,功能保留,若你的网络依然能访问可以考虑使用 + + ,点击{deprecated ? '收起' : '展开'} + + + + {deprecated && ( + + { + if (cdn && origin === 'jsDelivr') return + + t('设置.切换', { + title: 'CDN加速', + checked: !cdn, + origin: 'jsDelivr' + }) + + if (!cdn) systemStore.switchSetting('cdn') + systemStore.setSetting( + 'cdnOrigin', + MODEL_SETTING_CDN_ORIGIN.getValue('jsDelivr') + ) + + setTimeout(() => { + clearCache() + }, 0) + }} + /> + { + if (cdn && origin === 'fastly') return + + t('设置.切换', { + title: 'CDN加速', + checked: !cdn, + origin: 'fastly' + }) + + if (!cdn) systemStore.switchSetting('cdn') + systemStore.setSetting( + 'cdnOrigin', + MODEL_SETTING_CDN_ORIGIN.getValue('fastly') + ) + + setTimeout(() => { + clearCache() + }, 0) + }} + /> + + )} + + {/* 头像加速 */} + { + t('设置.切换', { + title: '头像加速', + checked: !cdnAvatar + }) + + systemStore.switchSetting('cdnAvatar') + }} + /> + } + information={'[待废弃] 其他用户头像使用清晰快照,但不会实时更新'} + /> ) diff --git a/src/screens/user/setting/styles.js b/src/screens/user/setting/styles.js index 1cad32d57..f11e0f10b 100644 --- a/src/screens/user/setting/styles.js +++ b/src/screens/user/setting/styles.js @@ -2,7 +2,7 @@ * @Author: czy0729 * @Date: 2022-01-21 16:35:16 * @Last Modified by: czy0729 - * @Last Modified time: 2022-03-17 15:48:05 + * @Last Modified time: 2022-05-10 06:05:33 */ import { _ } from '@stores' @@ -21,5 +21,9 @@ export default _.create({ }, test: { marginTop: -8 + }, + infor: { + paddingTop: 56, + marginLeft: -_.sm } }) diff --git a/src/utils/app.ts b/src/utils/app.ts index 3fbb0f3e4..2a58bf007 100755 --- a/src/utils/app.ts +++ b/src/utils/app.ts @@ -3,12 +3,17 @@ * @Author: czy0729 * @Date: 2019-03-23 09:21:16 * @Last Modified by: czy0729 - * @Last Modified time: 2022-05-03 23:04:47 + * @Last Modified time: 2022-05-09 16:14:05 */ import * as WebBrowser from 'expo-web-browser' import { HTMLDecode } from '@utils/html' import { DEV, HOST, HOST_2, EVENT, IMG_DEFAULT } from '@constants' -import { initHashSubjectOTA, initHashAvatarOTA, CDN_OSS_SUBJECT } from '@constants/cdn' +import { + initHashSubjectOTA, + initHashAvatarOTA, + CDN_OSS_SUBJECT, + CDN_OSS_MAGMA_POSTER +} from '@constants/cdn' import cnData from '@constants/json/cn.json' import x18data from '@constants/json/18x.json' import bangumiData from '@constants/json/thirdParty/bangumiData.min.json' @@ -470,6 +475,8 @@ export function matchCoverUrl(src: string, noDefault?: boolean) { // 有些情况图片地址分析错误, 排除掉 if (noImg.includes(src)) return IMG_DEFAULT || fallback + if (cdn && cdnOrigin === 'magma') + return CDN_OSS_MAGMA_POSTER(getCoverMedium(src)) || fallback if (cdn) return CDN_OSS_SUBJECT(getCoverMedium(src), cdnOrigin) || fallback // 大图不替换成低质量图 diff --git a/src/utils/crypto.ts b/src/utils/crypto.ts new file mode 100644 index 000000000..e093ee470 --- /dev/null +++ b/src/utils/crypto.ts @@ -0,0 +1,22 @@ +/* + * @Author: czy0729 + * @Date: 2022-05-10 04:54:33 + * @Last Modified by: czy0729 + * @Last Modified time: 2022-05-10 05:15:54 + */ +import CryptoJS from 'crypto-js' +import { APP_ID } from '@constants' + +export function set(data: object | string) { + return CryptoJS.AES.encrypt(JSON.stringify(data), APP_ID).toString() +} + +export function get(content: string): object | string { + const bytes = CryptoJS.AES.decrypt(content.toString(), APP_ID) + return JSON.parse(bytes.toString(CryptoJS.enc.Utf8)) +} + +export default { + set, + get +} diff --git a/tsconfig.json b/tsconfig.json index 68595bd12..f972244f4 100755 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,72 +2,30 @@ "compilerOptions": { "baseUrl": ".", "paths": { - "@_": [ - "src/screens/_" - ], - "@_/*": [ - "src/screens/_/*" - ], - "@components": [ - "src/components" - ], - "@components/*": [ - "src/components/*" - ], - "@constants": [ - "src/constants" - ], - "@constants/*": [ - "src/constants/*" - ], - "@screens": [ - "src/screens" - ], - "@screens/*": [ - "src/screens/*" - ], - "@stores": [ - "src/stores" - ], - "@stores/*": [ - "src/stores/*" - ], - "@styles": [ - "src/styles" - ], - "@styles/*": [ - "src/styles/*" - ], - "@tinygrail": [ - "src/screens/tinygrail" - ], - "@tinygrail/*": [ - "src/screens/tinygrail/*" - ], - "@utils": [ - "src/utils" - ], - "@utils/*": [ - "src/utils/*" - ], - "@types": [ - "src/types" - ], - "@types/*": [ - "src/types/*" - ] + "@_": ["src/screens/_"], + "@_/*": ["src/screens/_/*"], + "@components": ["src/components"], + "@components/*": ["src/components/*"], + "@constants": ["src/constants"], + "@constants/*": ["src/constants/*"], + "@screens": ["src/screens"], + "@screens/*": ["src/screens/*"], + "@stores": ["src/stores"], + "@stores/*": ["src/stores/*"], + "@styles": ["src/styles"], + "@styles/*": ["src/styles/*"], + "@tinygrail": ["src/screens/tinygrail"], + "@tinygrail/*": ["src/screens/tinygrail/*"], + "@utils": ["src/utils"], + "@utils/*": ["src/utils/*"], + "@types": ["src/types"], + "@types/*": ["src/types/*"] }, "allowJs": true, "esModuleInterop": true, "jsx": "react-native", - "types": [ - "react", - "react-native" - ], - "lib": [ - "DOM", - "ESNext" - ], + "types": ["react", "react-native"], + "lib": ["DOM", "ESNext"], "moduleResolution": "node", "noEmit": true, "resolveJsonModule": true, @@ -77,12 +35,6 @@ "emitDecoratorMetadata": true, "target": "ESNext" }, - "exclude": [ - "node_modules", - "dist", - "android", - "src/assets", - "web" - ], + "exclude": ["node_modules", "dist", "android", "src/assets", "web"], "extends": "expo/tsconfig.base" }