Skip to content

Commit

Permalink
[Release] Hotfix 2.18.2 => 2.18.3 (patch) (#9143)
Browse files Browse the repository at this point in the history
* chore: bump version to 2.18.3

* chore: pick simple hash (#9147)

* chore: pick simple hash

* chore: sync simplehash (#9083)

* refactor: gray simple hash (#9104)

* refactor: add canvas fingerprinting (#9012)

* refactor: opt fp

* test: add createDeviceSeed

* fix: lint errors

* feat: add isDeviceOnWhitelist

* test: isDeviceOnWhitelist

* fix: ci errors

* refactor: update comment

* fix: type error

* fix: type error

* feat: A/B simplehash (#9019)

* refactor: set tag

* chore: add ab tags

* feat: debug A/B

* chore: type

* fix: type

---------

Co-authored-by: guanbinrui <52657989+guanbinrui@users.noreply.github.com>

* fix: bugfix for invalid gas (#9127)

* fix: simple hash img fallback (#9155)

* refactor: adjust sample rate (#9159)

* refactor: events as transactions (#9160)

* refactor: events as transactions

* refactor: send events as transactions

* refactor: update lock file

* fix: mf-3718 NFTScan gnosis host is incorrect (#9118)

* fix: mf-3719 image size in dashboard assets

* fix: mf-3718 NFTScan gnosis host is incorrect

* fix: several bugs (#9171)

* fix: several bugs

* fix: type

* fix: mf-3717 pass plugin id to collectible card (#9168)

* fix: mf-3717 pass plugin id to collectible card

* fixup! fix: mf-3717 pass plugin id to collectible card

* feat: remote flags (#9176)

* refactor: add @masknet/flags (#9053)

* chore: simplehash_ab_percentage

* feat: remote flags

* refactor: comment

* refactor: error handling

* fix: cspell

* fix: logic errors

* fix: simple hash rp history nft (#9177)

---------

Co-authored-by: Hancheng Zhou <z308114274@gmail.com>
Co-authored-by: nuanyang233 <nuanyang233@gmail.com>
Co-authored-by: UncleBill <billbill290@gmail.com>
  • Loading branch information
4 people committed Mar 28, 2023
1 parent d039d37 commit 98dbced
Show file tree
Hide file tree
Showing 81 changed files with 1,084 additions and 298 deletions.
1 change: 1 addition & 0 deletions cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,7 @@
"rehype",
"renfil",
"shapeclip",
"simplehash",
"ssrb",
"steth",
"swaptoken",
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"yarn": ">=999.0.0",
"npm": ">=999.0.0"
},
"version": "2.18.2",
"version": "2.18.3",
"private": true,
"license": "AGPL-3.0-or-later",
"scripts": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ const useStyles = makeStyles()((theme) => ({
width: '100%',
height: 186,
backgroundColor: theme.palette.mode === 'dark' ? MaskColorVar.lineLight : '#f6f6f7',
img: {
objectFit: 'contain !important' as 'contain',
},
},
description: {
flex: 1,
Expand Down Expand Up @@ -102,14 +105,17 @@ export const CollectibleCard = memo<CollectibleCardProps>(({ asset, onSend }) =>
return Others?.explorerResolver.nonFungibleTokenLink(asset.chainId, asset.address, asset.tokenId)
}, [currentPluginId, asset.chainId, asset.address, asset.tokenId])

// NFTScan can't recognize address uppercase
const link = (asset.link ?? nftLink)?.toLowerCase()

return (
<Box className={`${classes.container} ${isHovering || isHoveringTooltip ? classes.hover : ''}`} ref={ref}>
<div className={classes.card}>
<Link
target={asset.link ?? nftLink ? '_blank' : '_self'}
rel="noopener noreferrer"
className={classes.linkWrapper}
href={asset.link ?? nftLink}>
href={link}>
<div className={classes.blocker} />
<div className={classes.mediaContainer}>
<AssetPreviewer
Expand Down Expand Up @@ -156,3 +162,5 @@ export const CollectibleCard = memo<CollectibleCardProps>(({ asset, onSend }) =>
</Box>
)
})

CollectibleCard.displayName = 'CollectibleCard'
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export const CollectibleList = memo<CollectibleListProps>(({ selectedChain }) =>
[...trustedOwnNonFungibleTokens, ...value],
(x) => x?.contract?.address.toLowerCase() + x?.tokenId,
).filter((x) => (selectedChain ? x.chainId === selectedChain.chainId : true))
}, [value.length, trustedNonFungibleTokens.length, selectedChain?.chainId])
}, [value.length, trustedNonFungibleTokens, selectedChain?.chainId])

useEffect(() => {
if (next) next()
Expand Down
16 changes: 16 additions & 0 deletions packages/flags/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"name": "@masknet/flags",
"private": true,
"type": "module",
"exports": {
".": {
"types": "./dist/index.d.ts",
"mask-src": "./src/index.ts",
"default": "./dist/index.js"
}
},
"types": "./dist/index.d.ts",
"devDependencies": {
"urlcat": "^2.0.4"
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export const is_iOSApp = process.env.engine === 'safari' && process.env.architecture === 'app'
export const isAndroidApp = process.env.architecture === 'app' && process.env.engine === 'firefox'
const is_iOSApp = process.env.engine === 'safari' && process.env.architecture === 'app'
const isAndroidApp = process.env.architecture === 'app' && process.env.engine === 'firefox'

const appOnly = process.env.architecture === 'app'
const devOnly = process.env.NODE_ENV === 'development'
Expand All @@ -8,7 +8,7 @@ const insiderOnly = process.env.channel === 'insider' || devOnly
const betaOrInsiderOnly = insiderOnly || process.env.channel === 'beta'

// TODO: In future, we can turn this object into a Proxy to receive flags from remote
export const Flags = {
export const flags = {
/** @deprecated */
userGuideLevel: 'v2',
isolated_dashboard_bridge_enabled: false,
Expand Down Expand Up @@ -57,8 +57,10 @@ export const Flags = {
v37PayloadDefaultEnabled: false, // new Date() > new Date('2022-07-01'),
i18nTranslationHotUpdate: true,
sandboxedPluginRuntime: insiderOnly,

simplehash_ab_percentage: 50,
} as const

if (process.env.NODE_ENV === 'development') {
console.log('Mask Network starts with flags:', Flags)
console.log('Mask Network starts with flags:', flags)
}
9 changes: 9 additions & 0 deletions packages/flags/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { flags as defaultFlags } from './flags/index.js'
import { RemoteFlags } from './libs/RemoteFlags.js'

const flags = new RemoteFlags('https://mask-flags.r2d2.to/', defaultFlags)

// fetch each time starts the app, updates will be enabled
flags.fetchAndActive()

export const Flags = flags.accessor
14 changes: 14 additions & 0 deletions packages/flags/src/libs/Flags.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export class Flags<T extends object> {
constructor(protected defaults: T) {}

get accessor(): Readonly<T> {
return new Proxy(this.defaults, {
get(target, key, receiver) {
return Reflect.get(target, key, receiver)
},
set(target, key, value, receiver) {
throw new Error('Not allowed')
},
})
}
}
130 changes: 130 additions & 0 deletions packages/flags/src/libs/RemoteFlags.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import urlcat from 'urlcat'
import { has } from 'lodash-es'
import { Flags } from './Flags.js'

interface FetchResult<T extends Record<string, unknown>> {
flags?: T
timestamp: number
}

export class RemoteFlags<T extends Record<string, unknown>> extends Flags<T> {
private readonly KEY = 'mask-last-fetch-result'

private lastFetchResult: FetchResult<T> | null = null

private get lastStorageResult() {
try {
const json = localStorage.getItem(this.KEY)
const result: FetchResult<T> | null = json ? JSON.parse(json) : null
return result
} catch (error) {
return null
}
}

constructor(
private remoteFlagsURL: string,
defaults: T,
private initials?: {
// the valid duration for remote fetched flags
fetchTTL?: number
// the valid duration for local storage flags
storageTTL?: number
},
) {
super(defaults)

this.sync()
}

get options() {
return {
fetchTTL: 60 * 60 * 1000, // 1hr
storageTTL: 2 * 60 * 60 * 1000, // 2hr
...this.initials,
}
}

get isLastFetchResultFresh() {
return Date.now() - this.lastFetchTimestamp < this.options.fetchTTL
}

get isLastStorageResultFresh() {
return Date.now() - this.lastStorageTimestamp < this.options.storageTTL
}

get lastFetchTimestamp() {
return this.lastFetchResult?.timestamp ?? 0
}

get lastStorageTimestamp() {
return this.lastStorageResult?.timestamp ?? 0
}

override get accessor(): Readonly<T> {
return new Proxy(this.defaults, {
get: (target, key, receiver) => {
if (has(this.lastFetchResult?.flags, key)) return this.lastFetchResult?.flags?.[key as string]
return Reflect.get(target, key, receiver)
},
set: (target, key, value, receiver) => {
throw new Error('Not allowed')
},
})
}

/**
* Sync with the local storage.
*/
sync() {
if (!this.isLastStorageResultFresh) {
localStorage.removeItem(this.KEY)
}

const lastFetchResult = this.lastFetchResult
const lastStorageResult = this.lastStorageResult

if (
(lastFetchResult?.timestamp && !lastStorageResult?.timestamp) ||
(lastFetchResult?.timestamp &&
lastStorageResult?.timestamp &&
lastStorageResult.timestamp < lastFetchResult.timestamp)
) {
console.log('[RemoteFlags] sync from remote')
localStorage.setItem(this.KEY, JSON.stringify(lastFetchResult))
} else if (lastStorageResult?.timestamp) {
console.log('[RemoteFlags] sync from storage')
this.lastFetchResult = lastStorageResult
}
}

/**
* Fetch flags from the remote server.
*/
async fetch() {
const response = await fetch(
urlcat(this.remoteFlagsURL, {
architecture: process.env.architecture,
channel: process.env.channel,
engine: process.env.engine,
NODE_ENV: process.env.NODE_ENV,
}),
)
const flags: T = await response.json()
return flags
}

/**
* Fetch flags from the remote server and patch updates right after fetched.
*/
async fetchAndActive() {
// Prevent fetching too frequently
if (this.isLastFetchResultFresh) return

this.lastFetchResult = {
flags: await this.fetch(),
timestamp: Date.now(),
}
this.sync()
}
}
10 changes: 10 additions & 0 deletions packages/flags/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"rootDir": "./src/",
"outDir": "./dist/",
"tsBuildInfoFile": "./dist/.tsbuildinfo"
},
"include": ["./src"],
"references": []
}
Binary file added packages/icons/brands/SimpleHash.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Flags } from '../../../shared/flags.js'
import { Flags } from '@masknet/flags'
import list from './i18n-cache-query-list.js'

export type Bundle = [namespace: string, lang: string, json: object]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import type { Permissions } from 'webextension-polyfill'
import { Flags } from '@masknet/flags'
import { getPermissionRequestURL } from '../../../shared/definitions/routes.js'
import { Flags } from '../../../shared/flags.js'
import { MaskMessages } from '../../../shared/messages.js'
import type { SiteAdaptor } from '../../../shared/site-adaptors/types.js'
import type { Permissions } from 'webextension-polyfill'

export async function requestExtensionPermission(permission: Permissions.Permissions): Promise<boolean> {
if (Flags.no_web_extension_dynamic_permission_request) return true
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { noop } from 'lodash-es'
import { Flags } from '../../../shared/flags.js'
import { Flags } from '@masknet/flags'
import { hmr } from '../../../utils-pure/index.js'
import {
fetchInjectContentScriptList,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { noop } from 'lodash-es'
import { MaskMessages } from '../../../shared/messages.js'
import { Flags } from '../../../shared/flags.js'
import { Flags } from '@masknet/flags'
import { hmr } from '../../../utils-pure/index.js'
import type { ExtensionTypes, WebNavigation } from 'webextension-polyfill'

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Environment, WebExtensionMessage } from '@dimensiondev/holoflows-kit'
import { Flags } from '../../../shared/flags.js'
import { Flags } from '@masknet/flags'
import { hmr } from '../../../utils-pure/index.js'

let disconnected = false
Expand Down
4 changes: 2 additions & 2 deletions packages/mask/background/tasks/Cancellable/NewInstalled.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { DashboardRoutes } from '@masknet/shared-base'
import type { Runtime } from 'webextension-polyfill'
import { Flags } from '../../../shared/flags.js'
import { Flags } from '@masknet/flags'
import { DashboardRoutes } from '@masknet/shared-base'
import { hmr } from '../../../utils-pure/index.js'
import { getOriginsWithoutPermission } from '../../services/site-adaptors/connect.js'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { PluginID } from '@masknet/shared-base'
import { Plugin, registerPlugin } from '@masknet/plugin-infra'
import { BackgroundInstance, BackgroundPluginHost } from '@masknet/sandboxed-plugin-runtime/background'
import { hmr } from '../../../utils-pure/index.js'
import { Flags } from '../../../shared/flags.js'
import { Flags } from '@masknet/flags'
import { createPluginDatabase } from '../../database/plugin-db/index.js'
import { createHostAPIs } from '../../../shared/sandboxed-plugin/host-api.js'

Expand Down
1 change: 1 addition & 0 deletions packages/mask/background/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
{ "path": "../../encryption" },
{ "path": "../../backup-format" },
{ "path": "../../gun-utils" },
{ "path": "../../flags" },
{ "path": "../../web3-providers" },
{ "path": "../../sandboxed-plugin-runtime/src/background" }
]
Expand Down
1 change: 1 addition & 0 deletions packages/mask/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"@masknet/dashboard": "workspace:^",
"@masknet/encryption": "workspace:^",
"@masknet/external-plugin-previewer": "workspace:^",
"@masknet/flags": "workspace:^",
"@masknet/gun-utils": "workspace:^",
"@masknet/icons": "workspace:^",
"@masknet/injected-script": "workspace:^",
Expand Down
1 change: 0 additions & 1 deletion packages/mask/shared/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
export * from './messages.js'
export * from './flags.js'
export { InMemoryStorages, PersistentStorages } from './kv-storage.js'
export * from './helpers/index.js'
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { useCallback, useEffect, useRef, useState } from 'react'
import { useAsync } from 'react-use'
import type { CompositionType } from '@masknet/plugin-infra/content-script'
import { InjectedDialog, useCurrentPersonaConnectStatus } from '@masknet/shared'
import { CrossIsolationMessages, EMPTY_OBJECT } from '@masknet/shared-base'
import { makeStyles } from '@masknet/theme'
import { DialogActions, DialogContent } from '@mui/material'
import { useCallback, useEffect, useRef, useState } from 'react'
import { useAsync } from 'react-use'
import { Flags } from '../../../shared/index.js'
import { Flags } from '@masknet/flags'
import Services from '../../extension/service.js'
import { activatedSocialNetworkUI } from '../../social-network/index.js'
import { MaskMessages, useI18N } from '../../utils/index.js'
Expand Down
2 changes: 1 addition & 1 deletion packages/mask/src/content-script.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Flags } from '@masknet/flags'
import './setup.ui.js'
import { Flags } from '../shared/index.js'

if (Flags.mask_SDK_ready) {
import('./extension/mask-sdk/index.js')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,13 @@ export const CollectibleCard = memo(function CollectibleCard({
const networkDescriptor = useNetworkDescriptor(pluginID)

const networkIcon = useMemo(() => {
// None is better than incorrect.
if (!pluginID) return
if (pluginID === NetworkPluginID.PLUGIN_EVM) {
return NETWORK_DESCRIPTORS.find((network) => network?.chainId === asset.chainId)?.icon
}
return networkDescriptor?.icon
}, [asset.chainId, pluginID])
}, [asset.chainId, pluginID, networkDescriptor?.icon])

const content = (
<>
Expand Down Expand Up @@ -123,3 +125,5 @@ export const CollectibleCard = memo(function CollectibleCard({
</Link>
)
})

CollectibleCard.displayName = 'CollectibleCard'
Loading

0 comments on commit 98dbced

Please sign in to comment.