diff --git a/packages/dashboard/src/pages/Personas/api.ts b/packages/dashboard/src/pages/Personas/api.ts index 7d780bb70604..68ebdcbb975e 100644 --- a/packages/dashboard/src/pages/Personas/api.ts +++ b/packages/dashboard/src/pages/Personas/api.ts @@ -5,10 +5,7 @@ export type SocialNetwork = { networkIdentifier: string } -export const [useDefinedSocialNetworkUIs, revalidateSocialNetworkUIs] = createGlobalState( - Services.SocialNetwork.getDefinedSocialNetworkUIs, - () => () => {}, -) +export const [useSupportedSites] = createGlobalState(Services.SocialNetwork.getSupportedSites, () => () => {}) export const [useOwnedPersonas] = createGlobalState( () => Services.Identity.queryOwnedPersonaInformation(false), diff --git a/packages/dashboard/src/pages/Personas/hooks/useConnectSocialNetwork.ts b/packages/dashboard/src/pages/Personas/hooks/useConnectSite.ts similarity index 65% rename from packages/dashboard/src/pages/Personas/hooks/useConnectSocialNetwork.ts rename to packages/dashboard/src/pages/Personas/hooks/useConnectSite.ts index 4d288c7725fd..6425c747b8d1 100644 --- a/packages/dashboard/src/pages/Personas/hooks/useConnectSocialNetwork.ts +++ b/packages/dashboard/src/pages/Personas/hooks/useConnectSite.ts @@ -3,14 +3,14 @@ import { Services } from '../../../API' import type { ProfileIdentifier } from '@masknet/shared-base' import type { AsyncFnReturn } from 'react-use/lib/useAsyncFn' -export function useConnectSocialNetwork() { - return useAsyncFn(Services.SocialNetwork.connectSocialNetwork) +export function useConnectSite() { + return useAsyncFn(Services.SocialNetwork.connectSite) } export function useOpenProfilePage() { return useAsyncFn(Services.SocialNetwork.openProfilePage) } -export function useDisconnectSocialNetwork(): AsyncFnReturn<(identifier: ProfileIdentifier) => Promise> { +export function useDisconnectSite(): AsyncFnReturn<(identifier: ProfileIdentifier) => Promise> { return useAsyncFn((identifier: ProfileIdentifier) => Services.Identity.detachProfile(identifier)) } diff --git a/packages/dashboard/src/pages/Personas/hooks/usePersonaContext.ts b/packages/dashboard/src/pages/Personas/hooks/usePersonaContext.ts index 1c767f1007f0..ca2e1c613cda 100644 --- a/packages/dashboard/src/pages/Personas/hooks/usePersonaContext.ts +++ b/packages/dashboard/src/pages/Personas/hooks/usePersonaContext.ts @@ -1,21 +1,21 @@ import { createContainer } from 'unstated-next' import { useCallback, useState } from 'react' -import { useConnectSocialNetwork, useDisconnectSocialNetwork, useOpenProfilePage } from './useConnectSocialNetwork' +import { useConnectSite, useDisconnectSite, useOpenProfilePage } from './useConnectSite' import { Services } from '../../../API' -import { useOwnedPersonas, useDefinedSocialNetworkUIs, SocialNetwork, useCurrentPersonaIdentifier } from '../api' +import { useOwnedPersonas, useSupportedSites, SocialNetwork, useCurrentPersonaIdentifier } from '../api' import { useCreatePersona } from './useCreatePersona' import { useDeleteBound } from './useOperateBindingProof' function usePersonaContext() { const currentPersonaIdentifier = useCurrentPersonaIdentifier() - const definedSocialNetworks: SocialNetwork[] = useDefinedSocialNetworkUIs() + const definedSocialNetworks: SocialNetwork[] = useSupportedSites() const personas = useOwnedPersonas() const currentPersona = personas.find((x) => x.identifier === currentPersonaIdentifier) const [open, setOpen] = useState(false) - const [, connectPersona] = useConnectSocialNetwork() + const [, connectPersona] = useConnectSite() const [, openProfilePage] = useOpenProfilePage() - const [, disconnectPersona] = useDisconnectSocialNetwork() + const [, disconnectPersona] = useDisconnectSite() const [, createPersona] = useCreatePersona() const [, deleteBound] = useDeleteBound() const renamePersona = Services.Identity.renamePersona diff --git a/packages/dashboard/src/pages/Welcome/index.tsx b/packages/dashboard/src/pages/Welcome/index.tsx index bd570f27bdc3..db33ccb50eff 100644 --- a/packages/dashboard/src/pages/Welcome/index.tsx +++ b/packages/dashboard/src/pages/Welcome/index.tsx @@ -78,7 +78,7 @@ export default function Welcome() { privacyPolicyURL={agreementContentPageURL} iframeLoadHandler={handleIFrameLoad} agreeHandler={async () => { - const url = await Services.SocialNetwork.setupSocialNetwork('twitter.com', false) + const url = await Services.SocialNetwork.setupSite('twitter.com', false) if (url) location.assign(url) }} cancelHandler={() => window.close()} diff --git a/packages/encryption/src/index.ts b/packages/encryption/src/index.ts index b0a5894030f7..bcb3d9d94caa 100644 --- a/packages/encryption/src/index.ts +++ b/packages/encryption/src/index.ts @@ -47,12 +47,7 @@ export { appendEncryptionTarget, } from './encryption' -export { - socialNetworkEncoder, - socialNetworkDecoder, - TwitterDecoder, - __TwitterEncoder, -} from './social-network-encode-decode' +export { socialNetworkEncoder, socialNetworkDecoder, TwitterDecoder } from './social-network-encode-decode' export { type DecodeImageOptions, diff --git a/packages/mask/background/services/helper/request-permission.ts b/packages/mask/background/services/helper/request-permission.ts index 9db927ac77fd..d4100ad81876 100644 --- a/packages/mask/background/services/helper/request-permission.ts +++ b/packages/mask/background/services/helper/request-permission.ts @@ -1,5 +1,8 @@ import { getPermissionRequestURL } from '../../../shared/definitions/routes' +import { Flags } from '../../../shared/flags' +import type { SiteAdaptor } from '../../../shared/site-adaptors/types' export async function requestExtensionPermission(permission: browser.permissions.Permissions): Promise { + if (Flags.no_web_extension_dynamic_permission_request) return true if (await browser.permissions.contains(permission)) return true try { return await browser.permissions.request(permission) @@ -22,7 +25,7 @@ export async function requestExtensionPermission(permission: browser.permissions }) } -export async function requestHostPermission(origins: string[]) { +export async function requestHostPermission(origins: readonly string[]) { const currentOrigins = (await browser.permissions.getAll()).origins || [] const extra = origins.filter((i) => !currentOrigins?.includes(i)) if (!extra.length) return true @@ -32,3 +35,10 @@ export async function requestHostPermission(origins: string[]) { export function queryExtensionPermission(permission: browser.permissions.Permissions): Promise { return browser.permissions.contains(permission) } + +/** @internal */ +export function requestSiteAdaptorsPermission(defines: readonly SiteAdaptor.Definition[]) { + return requestExtensionPermission({ + origins: defines.map((x) => x.declarativePermissions.origins).flat(), + }) +} diff --git a/packages/mask/background/services/setup.ts b/packages/mask/background/services/setup.ts index e730e64cb031..e372d4a53d2a 100644 --- a/packages/mask/background/services/setup.ts +++ b/packages/mask/background/services/setup.ts @@ -18,15 +18,7 @@ setup('Crypto', () => import(/* webpackPreload: true */ './crypto')) setup('Identity', () => import(/* webpackPreload: true */ './identity')) setup('Backup', () => import(/* webpackPreload: true */ './backup')) setup('Helper', () => import(/* webpackPreload: true */ './helper')) -setup('SocialNetwork', () => - Promise.resolve({ - // TODO: migration in process - getDefinedSocialNetworkUIs() { - return [{ networkIdentifier: 'twitter.com' }] - }, - setupSocialNetwork() {}, - }), -) +setup('SocialNetwork', () => import(/* webpackPreload: true */ './site-adaptors')) setup('Settings', () => import(/* webpackPreload: true */ './settings')) setup('ThirdPartyPlugin', () => Promise.resolve({})) diff --git a/packages/mask/background/services/site-adaptors/connect.ts b/packages/mask/background/services/site-adaptors/connect.ts new file mode 100644 index 000000000000..7475ed114f52 --- /dev/null +++ b/packages/mask/background/services/site-adaptors/connect.ts @@ -0,0 +1,44 @@ +import { delay } from '@dimensiondev/kit' +import { definedSiteAdaptors } from '../../../shared/site-adaptors/definitions' +import { requestSiteAdaptorsPermission } from '../helper/request-permission' + +export async function getSupportedSites(): Promise> { + return [...definedSiteAdaptors.values()].map((x) => ({ networkIdentifier: x.networkIdentifier })) +} + +export async function migration_in_progress_setupSite( + network: string, + newTab: boolean, + setSettingsCallback: () => void, +) { + const worker = definedSiteAdaptors.get(network) + const home = worker?.homepage + + // request permission from all sites supported. + if (!(await requestSiteAdaptorsPermission([...definedSiteAdaptors.values()]))) return + + // TODO: move settings callback here. + setSettingsCallback() + await delay(100) + if (!home) return + if (!newTab) return home + + browser.tabs.create({ active: true, url: home }) + return +} + +export async function migration_in_progress_connectSite(network: string, setSettingsCallback: () => void) { + const worker = definedSiteAdaptors.get(network) + if (!worker) return + + if (!(await requestSiteAdaptorsPermission([worker]))) return + + // TODO: move settings callback here. + setSettingsCallback() + + await delay(100) + + if (worker.homepage) { + browser.tabs.create({ active: true, url: worker.homepage }) + } +} diff --git a/packages/mask/background/services/site-adaptors/index.ts b/packages/mask/background/services/site-adaptors/index.ts new file mode 100644 index 000000000000..eac1dc0b75d5 --- /dev/null +++ b/packages/mask/background/services/site-adaptors/index.ts @@ -0,0 +1,3 @@ +export { getDesignatedAutoStartPluginID, openSNSAndActivatePlugin } from './open-with-plugin' +export { getSupportedSites } from './connect' +export { openProfilePage, openShareLink } from './open-page' diff --git a/packages/mask/background/services/site-adaptors/open-page.ts b/packages/mask/background/services/site-adaptors/open-page.ts new file mode 100644 index 000000000000..daef5c88dfcc --- /dev/null +++ b/packages/mask/background/services/site-adaptors/open-page.ts @@ -0,0 +1,33 @@ +import { delay } from '@dimensiondev/kit' +import { ProfileIdentifier } from '@masknet/shared-base' +import { definedSiteAdaptors } from '../../../shared/site-adaptors/definitions' +import { requestSiteAdaptorsPermission } from '../helper/request-permission' + +export async function openProfilePage(network: string, userId?: string) { + const worker = definedSiteAdaptors.get(network) + if (!worker) return + + const url = worker?.getProfilePage?.(ProfileIdentifier.of(network, userId).unwrap()) + if (!url) return + + if (!(await requestSiteAdaptorsPermission([worker]))) return + + await delay(100) + browser.tabs.create({ active: true, url: url.toString() }) +} + +export async function openShareLink(network: string, post: string) { + const url = definedSiteAdaptors.get(network)?.getShareLinkURL?.(post) + + if (!url) return + const width = 700 + const height = 520 + browser.windows.create({ + url: url.toString(), + width, + height, + type: 'popup', + left: (screen.width - width) / 2, + top: (screen.height - height) / 2, + }) +} diff --git a/packages/mask/background/services/site-adaptors/open-with-plugin.ts b/packages/mask/background/services/site-adaptors/open-with-plugin.ts new file mode 100644 index 000000000000..46ffdfd5b68e --- /dev/null +++ b/packages/mask/background/services/site-adaptors/open-with-plugin.ts @@ -0,0 +1,15 @@ +const key = 'openSNSAndActivatePlugin' +/** + * This function will open a new web page, then open the composition dialog and activate the composition entry of the given plugin. + * @param url URL to open + * @param pluginID Plugin to activate + */ +export async function openSNSAndActivatePlugin(url: string, pluginID: string) { + await browser.tabs.create({ active: true, url }) + sessionStorage.setItem(key, pluginID) +} +export async function getDesignatedAutoStartPluginID() { + const val = sessionStorage.getItem(key) + sessionStorage.removeItem(key) + return val +} diff --git a/packages/mask/background/setup.ts b/packages/mask/background/setup.ts index 359b798972b8..932e91a8cf29 100644 --- a/packages/mask/background/setup.ts +++ b/packages/mask/background/setup.ts @@ -2,5 +2,7 @@ import { polyfill } from '@dimensiondev/secp256k1-webcrypto' import { setupMaskKVStorageBackend } from '../shared/kv-storage' import { inMemory_KVStorageBackend, indexedDB_KVStorageBackend } from './database/kv-storage' +import '../shared/site-adaptors' + polyfill() setupMaskKVStorageBackend(indexedDB_KVStorageBackend, inMemory_KVStorageBackend) diff --git a/packages/mask/shared/site-adaptors/definitions.ts b/packages/mask/shared/site-adaptors/definitions.ts new file mode 100644 index 000000000000..45f40e6eeeba --- /dev/null +++ b/packages/mask/shared/site-adaptors/definitions.ts @@ -0,0 +1,8 @@ +import type { SiteAdaptor } from './types' + +const defined = new Map() +export const definedSiteAdaptors: ReadonlyMap = defined + +export function defineSiteAdaptor(UI: SiteAdaptor.Definition) { + defined.set(UI.networkIdentifier, UI) +} diff --git a/packages/mask/shared/site-adaptors/implementations/facebook.com.ts b/packages/mask/shared/site-adaptors/implementations/facebook.com.ts new file mode 100644 index 000000000000..b1ba888df80b --- /dev/null +++ b/packages/mask/shared/site-adaptors/implementations/facebook.com.ts @@ -0,0 +1,23 @@ +import urlcat from 'urlcat' +import { EnhanceableSite } from '@masknet/shared-base' +import { defineSiteAdaptor } from '../definitions' +import type { SiteAdaptor } from '../types' + +if (import.meta.webpackHot) import.meta.webpackHot.accept() + +const origins = ['https://www.facebook.com/*', 'https://m.facebook.com/*', 'https://facebook.com/*'] +export const FacebookAdaptor: SiteAdaptor.Definition = { + networkIdentifier: EnhanceableSite.Facebook, + declarativePermissions: { origins }, + homepage: 'https://www.facebook.com', + + getProfilePage: () => new URL('https://www.facebook.com'), + getShareLinkURL(message) { + const url = urlcat('https://www.facebook.com/sharer/sharer.php', { + quote: message, + u: 'mask.io', + }) + return new URL(url) + }, +} +defineSiteAdaptor(FacebookAdaptor) diff --git a/packages/mask/shared/site-adaptors/implementations/instagram.com.ts b/packages/mask/shared/site-adaptors/implementations/instagram.com.ts new file mode 100644 index 000000000000..0bdcf6a8bfe6 --- /dev/null +++ b/packages/mask/shared/site-adaptors/implementations/instagram.com.ts @@ -0,0 +1,16 @@ +import { EnhanceableSite } from '@masknet/shared-base' +import { defineSiteAdaptor } from '../definitions' +import type { SiteAdaptor } from '../types' + +if (import.meta.webpackHot) import.meta.webpackHot.accept() + +const origins = ['https://www.instagram.com/*', 'https://m.instagram.com/*', 'https://instagram.com/*'] +export const InstagramAdaptor: SiteAdaptor.Definition = { + networkIdentifier: EnhanceableSite.Instagram, + declarativePermissions: { origins }, + homepage: 'https://www.instagram.com/', + + getProfilePage: () => new URL('https://www.instagram.com/'), + getShareLinkURL: null, +} +defineSiteAdaptor(InstagramAdaptor) diff --git a/packages/mask/shared/site-adaptors/implementations/minds.com.ts b/packages/mask/shared/site-adaptors/implementations/minds.com.ts new file mode 100644 index 000000000000..55a45f533c64 --- /dev/null +++ b/packages/mask/shared/site-adaptors/implementations/minds.com.ts @@ -0,0 +1,22 @@ +import { EnhanceableSite } from '@masknet/shared-base' +import urlcat from 'urlcat' +import { defineSiteAdaptor } from '../definitions' +import type { SiteAdaptor } from '../types' + +if (import.meta.webpackHot) import.meta.webpackHot.accept() + +const origins = ['https://www.minds.com/*', 'https://minds.com/*', 'https://cdn.minds.com/*'] +export const MindsAdaptor: SiteAdaptor.Definition = { + networkIdentifier: EnhanceableSite.Minds, + declarativePermissions: { origins }, + homepage: 'https://www.minds.com', + + getProfilePage: () => new URL('https://www.minds.com'), + getShareLinkURL(message) { + const url = urlcat('https://www.minds.com/newsfeed/subscriptions', { + intentUrl: message, + }) + return new URL(url) + }, +} +defineSiteAdaptor(MindsAdaptor) diff --git a/packages/mask/shared/site-adaptors/implementations/opensea.io.ts b/packages/mask/shared/site-adaptors/implementations/opensea.io.ts new file mode 100644 index 000000000000..0021d39c77e2 --- /dev/null +++ b/packages/mask/shared/site-adaptors/implementations/opensea.io.ts @@ -0,0 +1,22 @@ +import { EnhanceableSite } from '@masknet/shared-base' +import urlcat from 'urlcat' +import { defineSiteAdaptor } from '../definitions' +import type { SiteAdaptor } from '../types' + +if (import.meta.webpackHot) import.meta.webpackHot.accept() + +const origins = ['https://opensea.io/*'] +export const OpenSeaAdaptor: SiteAdaptor.Definition = { + networkIdentifier: EnhanceableSite.OpenSea, + declarativePermissions: { origins }, + homepage: 'https://opensea.io/', + + getProfilePage: () => new URL('https://opensea.io/account'), + getShareLinkURL(message) { + const url = urlcat('https://www.minds.com/newsfeed/subscriptions', { + intentUrl: message, + }) + return new URL(url) + }, +} +defineSiteAdaptor(OpenSeaAdaptor) diff --git a/packages/mask/shared/site-adaptors/implementations/twitter.com.ts b/packages/mask/shared/site-adaptors/implementations/twitter.com.ts new file mode 100644 index 000000000000..df41c4e0d8a4 --- /dev/null +++ b/packages/mask/shared/site-adaptors/implementations/twitter.com.ts @@ -0,0 +1,20 @@ +import urlcat from 'urlcat' +import { EnhanceableSite } from '@masknet/shared-base' +import { defineSiteAdaptor } from '../definitions' +import type { SiteAdaptor } from '../types' + +if (import.meta.webpackHot) import.meta.webpackHot.accept() + +const origins = ['https://mobile.twitter.com/*', 'https://twitter.com/*'] +export const TwitterAdaptor: SiteAdaptor.Definition = { + networkIdentifier: EnhanceableSite.Twitter, + declarativePermissions: { origins }, + homepage: 'https://twitter.com', + + getProfilePage: (userId) => new URL(`https://twitter.com/${userId.userId}`), + getShareLinkURL(message) { + const url = urlcat('https://twitter.com/intent/tweet', { text: message }) + return new URL(url) + }, +} +defineSiteAdaptor(TwitterAdaptor) diff --git a/packages/mask/shared/site-adaptors/index.ts b/packages/mask/shared/site-adaptors/index.ts new file mode 100644 index 000000000000..f85949604ff1 --- /dev/null +++ b/packages/mask/shared/site-adaptors/index.ts @@ -0,0 +1,7 @@ +if (import.meta.webpackHot) import.meta.webpackHot.accept() + +import './implementations/facebook.com' +import './implementations/twitter.com' +import './implementations/minds.com' +import './implementations/instagram.com' +import './implementations/opensea.io' diff --git a/packages/mask/shared/site-adaptors/types.ts b/packages/mask/shared/site-adaptors/types.ts new file mode 100644 index 000000000000..646353a6e945 --- /dev/null +++ b/packages/mask/shared/site-adaptors/types.ts @@ -0,0 +1,16 @@ +import type { ProfileIdentifier } from '@masknet/shared-base' + +export declare namespace SiteAdaptor { + export interface DeclarativePermissions { + origins: readonly string[] + } + export interface Definition { + networkIdentifier: string + // Note: if declarativePermissions is no longer sufficient, use "false" to indicate it need a load(). + declarativePermissions: DeclarativePermissions + homepage: undefined | string + getProfilePage: null | ((profile: ProfileIdentifier) => URL | null) + getShareLinkURL: null | ((text: string) => URL) + notReadyForProduction?: boolean + } +} diff --git a/packages/mask/src/components/InjectedComponents/ProfileSlider.tsx b/packages/mask/src/components/InjectedComponents/ProfileSlider.tsx deleted file mode 100644 index e04244d4dcbf..000000000000 --- a/packages/mask/src/components/InjectedComponents/ProfileSlider.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import { createInjectHooksRenderer, useActivatedPluginsSNSAdaptor } from '@masknet/plugin-infra/content-script' - -const PluginRenderer = createInjectHooksRenderer(useActivatedPluginsSNSAdaptor.visibility.useAnyMode, (x) => { - return () => { - return
Profile Slider
- } -}) - -export interface ProfileSliderProps {} - -export function ProfileSlider(props: ProfileSliderProps) { - return -} diff --git a/packages/mask/src/extension/background-script/SocialNetworkService.ts b/packages/mask/src/extension/background-script/SocialNetworkService.ts index 59931d5b45ed..49892d5645b8 100644 --- a/packages/mask/src/extension/background-script/SocialNetworkService.ts +++ b/packages/mask/src/extension/background-script/SocialNetworkService.ts @@ -2,112 +2,36 @@ import { currentSetupGuideStatus, userGuideStatus } from '../../settings/setting import stringify from 'json-stable-stringify' import { SetupGuideStep } from '../../components/InjectedComponents/SetupGuide/types' import type { PersonaIdentifier, ProfileIdentifier } from '@masknet/shared-base' -import { delay } from '@dimensiondev/kit' -import { requestExtensionPermission } from '../../../background/services/helper' import { - definedSocialNetworkUIs, - getNetworkWorker, - loadSocialNetworkUI, - loadSocialNetworkUIs, - SocialNetworkUI, -} from '../../social-network' -import { Flags } from '../../../shared' - -export async function getDefinedSocialNetworkUIs() { - return [...definedSocialNetworkUIs.values()].map(({ networkIdentifier }) => { - return { - networkIdentifier, - } - }) -} - -function requestSNSAdaptorPermission(ui: SocialNetworkUI.Definition) { - const req = ui.permission?.request() - if (req) return req - return requestExtensionPermission({ origins: [...ui.declarativePermissions.origins] }) -} - -function requestSNSAdaptorsPermission(uis: SocialNetworkUI.Definition[]) { - return requestExtensionPermission({ - origins: uis.map((x) => x.declarativePermissions.origins).flat(), + migration_in_progress_connectSite, + migration_in_progress_setupSite, +} from '../../../background/services/site-adaptors/connect' + +export { + getDesignatedAutoStartPluginID, + openSNSAndActivatePlugin, + openProfilePage, + getSupportedSites, + openShareLink, +} from '../../../background/services/site-adaptors' + +export async function setupSite(defaultNetwork: string, newTab = true) { + return migration_in_progress_setupSite(defaultNetwork, newTab, () => { + userGuideStatus[defaultNetwork].value = '1' }) } -export async function setupSocialNetwork(defaultNetwork: string, newTab = true) { - const ui = await loadSocialNetworkUI(defaultNetwork) - const home = ui.utils.getHomePage?.() - - const uis = await loadSocialNetworkUIs() - if (!Flags.no_web_extension_dynamic_permission_request) { - if (!(await requestSNSAdaptorsPermission(uis))) return - } - - userGuideStatus[defaultNetwork].value = '1' - await delay(100) - if (!home) return - if (!newTab) return home - - browser.tabs.create({ active: true, url: home }) - return -} - -export async function connectSocialNetwork( +export async function connectSite( identifier: PersonaIdentifier, network: string, type?: 'local' | 'nextID', profile?: ProfileIdentifier, ) { - const ui = await loadSocialNetworkUI(network) - const home = ui.utils.getHomePage?.() - if (!Flags.no_web_extension_dynamic_permission_request) { - if (!(await requestSNSAdaptorPermission(ui))) return - } - currentSetupGuideStatus[network].value = stringify({ - status: type === 'nextID' ? SetupGuideStep.VerifyOnNextID : SetupGuideStep.FindUsername, - persona: identifier.toText(), - username: profile?.userId, + return migration_in_progress_connectSite(network, () => { + currentSetupGuideStatus[network].value = stringify({ + status: type === 'nextID' ? SetupGuideStep.VerifyOnNextID : SetupGuideStep.FindUsername, + persona: identifier.toText(), + username: profile?.userId, + }) }) - await delay(100) - home && browser.tabs.create({ active: true, url: home }) -} - -export async function openProfilePage(network: string, userId?: string) { - const ui = await loadSocialNetworkUI(network) - const profile = ui.utils.getProfilePage?.(userId) - if (!Flags.no_web_extension_dynamic_permission_request) { - if (!(await requestSNSAdaptorPermission(ui))) return - } - await delay(100) - profile && browser.tabs.create({ active: true, url: profile }) -} - -export async function openShareLink(SNSIdentifier: string, post: string) { - const url = (await getNetworkWorker(SNSIdentifier)).utils.getShareLinkURL?.(post) - if (!url) return - const width = 700 - const height = 520 - browser.windows.create({ - url: url.toString(), - width, - height, - type: 'popup', - left: (screen.width - width) / 2, - top: (screen.height - height) / 2, - }) -} - -const key = 'openSNSAndActivatePlugin' -/** - * This function will open a new web page, then open the composition dialog and activate the composition entry of the given plugin. - * @param url URL to open - * @param pluginID Plugin to activate - */ -export async function openSNSAndActivatePlugin(url: string, pluginID: string) { - await browser.tabs.create({ active: true, url }) - sessionStorage.setItem(key, pluginID) -} -export async function getDesignatedAutoStartPluginID() { - const val = sessionStorage.getItem(key) - sessionStorage.removeItem(key) - return val } diff --git a/packages/mask/src/extension/popups/pages/Personas/AccountDetail/index.tsx b/packages/mask/src/extension/popups/pages/Personas/AccountDetail/index.tsx index c54b74ceec31..1f8063fb87ca 100644 --- a/packages/mask/src/extension/popups/pages/Personas/AccountDetail/index.tsx +++ b/packages/mask/src/extension/popups/pages/Personas/AccountDetail/index.tsx @@ -84,7 +84,7 @@ const AccountDetail = memo(() => { const [, onVerify] = useAsyncFn(async () => { if (!selectedAccount?.identifier || !currentPersona?.identifier) return - await Service.SocialNetwork.connectSocialNetwork( + await Service.SocialNetwork.connectSite( currentPersona.identifier, selectedAccount.identifier.network, 'nextID', diff --git a/packages/mask/src/extension/popups/pages/Personas/Accounts/index.tsx b/packages/mask/src/extension/popups/pages/Personas/Accounts/index.tsx index b6504acc870e..ffef97d25b9a 100644 --- a/packages/mask/src/extension/popups/pages/Personas/Accounts/index.tsx +++ b/packages/mask/src/extension/popups/pages/Personas/Accounts/index.tsx @@ -50,7 +50,7 @@ const Accounts = memo(() => { const [, onConnect] = useAsyncFn( async (networkIdentifier: EnhanceableSite) => { if (currentPersona) { - await Services.SocialNetwork.connectSocialNetwork(currentPersona.identifier, networkIdentifier, 'local') + await Services.SocialNetwork.connectSite(currentPersona.identifier, networkIdentifier, 'local') } }, [currentPersona], diff --git a/packages/mask/src/extension/popups/pages/Personas/components/ProfileList/index.tsx b/packages/mask/src/extension/popups/pages/Personas/components/ProfileList/index.tsx index ffafd726623d..e79d4e8f9084 100644 --- a/packages/mask/src/extension/popups/pages/Personas/components/ProfileList/index.tsx +++ b/packages/mask/src/extension/popups/pages/Personas/components/ProfileList/index.tsx @@ -117,12 +117,7 @@ export const ProfileList = memo(() => { const [, onConnect] = useAsyncFn( async (networkIdentifier: string, type?: 'local' | 'nextID', profile?: ProfileIdentifier) => { if (currentPersona) { - await Services.SocialNetwork.connectSocialNetwork( - currentPersona.identifier, - networkIdentifier, - type, - profile, - ) + await Services.SocialNetwork.connectSite(currentPersona.identifier, networkIdentifier, type, profile) } }, [currentPersona], diff --git a/packages/mask/src/extension/popups/pages/Wallet/TokenDetail/index.tsx b/packages/mask/src/extension/popups/pages/Wallet/TokenDetail/index.tsx index c4958b56612b..a84260055a5d 100644 --- a/packages/mask/src/extension/popups/pages/Wallet/TokenDetail/index.tsx +++ b/packages/mask/src/extension/popups/pages/Wallet/TokenDetail/index.tsx @@ -76,7 +76,7 @@ const TokenDetail = memo(() => { const { value: isActiveSocialNetwork } = useAsync(async () => { const urls = compact((await browser.tabs.query({ active: true })).map((tab) => tab.url)) - const definedSocialNetworkUrls = (await Services.SocialNetwork.getDefinedSocialNetworkUIs()).map( + const definedSocialNetworkUrls = (await Services.SocialNetwork.getSupportedSites()).map( ({ networkIdentifier }) => networkIdentifier, ) diff --git a/packages/mask/src/social-network-adaptor/browser-action/index.ts b/packages/mask/src/social-network-adaptor/browser-action/index.ts index 4e1c87b55cf3..5dc4d3180186 100644 --- a/packages/mask/src/social-network-adaptor/browser-action/index.ts +++ b/packages/mask/src/social-network-adaptor/browser-action/index.ts @@ -18,14 +18,6 @@ const define: SocialNetworkUI.Definition = { configuration: {}, customization: {}, injection: {}, - permission: { - async has() { - return true - }, - async request() { - return true - }, - }, utils: { createPostContext: null! }, async init(signal) { const state: Readonly = { @@ -40,7 +32,6 @@ const define: SocialNetworkUI.Definition = { if (signal.aborted) return state // TODO: heck, this is not what we expected. this.networkIdentifier = ui.networkIdentifier - this.permission = _.permission this.declarativePermissions = _.declarativePermissions this.utils = _.utils return _.init(signal) diff --git a/packages/mask/src/social-network-adaptor/facebook.com/base.ts b/packages/mask/src/social-network-adaptor/facebook.com/base.ts index 4dc26603c117..0659ac202e9f 100644 --- a/packages/mask/src/social-network-adaptor/facebook.com/base.ts +++ b/packages/mask/src/social-network-adaptor/facebook.com/base.ts @@ -1,6 +1,6 @@ import { SocialNetworkEnum } from '@masknet/encryption' import { EnhanceableSite } from '@masknet/shared-base' -import type { SocialNetwork, SocialNetworkWorker } from '../../social-network/types' +import type { SocialNetwork } from '../../social-network/types' const origins = ['https://www.facebook.com/*', 'https://m.facebook.com/*', 'https://facebook.com/*'] @@ -16,8 +16,3 @@ export const facebookBase: SocialNetwork.Base = { export function isFacebook(ui: SocialNetwork.Base) { return ui.networkIdentifier === EnhanceableSite.Facebook } - -export const facebookWorkerBase: SocialNetworkWorker.WorkerBase & SocialNetwork.Base = { - ...facebookBase, - gunNetworkHint: '', -} diff --git a/packages/mask/src/social-network-adaptor/facebook.com/index.ts b/packages/mask/src/social-network-adaptor/facebook.com/index.ts index 4f7472569e16..ca59e4b137e0 100644 --- a/packages/mask/src/social-network-adaptor/facebook.com/index.ts +++ b/packages/mask/src/social-network-adaptor/facebook.com/index.ts @@ -1,5 +1,5 @@ -import { defineSocialNetworkUI, defineSocialNetworkWorker } from '../../social-network' -import { facebookBase, facebookWorkerBase } from './base' +import { defineSocialNetworkUI } from '../../social-network' +import { facebookBase } from './base' defineSocialNetworkUI({ ...facebookBase, @@ -12,15 +12,3 @@ defineSocialNetworkUI({ } }, }) - -defineSocialNetworkWorker({ - ...facebookWorkerBase, - load: () => import('./worker-provider'), - hotModuleReload(callback) { - if (import.meta.webpackHot) { - import.meta.webpackHot.accept('./worker-provider.ts', async () => { - callback((await import('./worker-provider')).default) - }) - } - }, -}) diff --git a/packages/mask/src/social-network-adaptor/facebook.com/shared.ts b/packages/mask/src/social-network-adaptor/facebook.com/shared.ts index 01d1a725d53b..3a429392b662 100644 --- a/packages/mask/src/social-network-adaptor/facebook.com/shared.ts +++ b/packages/mask/src/social-network-adaptor/facebook.com/shared.ts @@ -5,7 +5,7 @@ import type { PostIdentifier } from '@masknet/shared-base' import { hasPayloadLike } from '../../utils' import { createSNSAdaptorSpecializedPostContext } from '../../social-network/utils/create-post-context' import { openWindow } from '@masknet/shared-base-ui' -import urlcat from 'urlcat' +import { FacebookAdaptor } from '../../../shared/site-adaptors/implementations/facebook.com' const getPostURL = (post: PostIdentifier): URL | null => { return new URL(getPostUrlAtFacebook(post)) @@ -13,20 +13,10 @@ const getPostURL = (post: PostIdentifier): URL | null => { export const facebookShared: SocialNetwork.Shared & SocialNetwork.Base = { ...facebookBase, utils: { - getHomePage: () => 'https://www.facebook.com', - getProfilePage: (userId: string) => 'https://www.facebook.com', isValidUsername: (v) => !!isValidFacebookUsername(v), - textPayloadPostProcessor: undefined, getPostURL, share(message) { - openWindow(this.getShareLinkURL?.(message)) - }, - getShareLinkURL(message) { - const url = urlcat('https://www.facebook.com/sharer/sharer.php', { - quote: message, - u: 'mask.io', - }) - return new URL(url) + openWindow(FacebookAdaptor.getShareLinkURL?.(message)) }, createPostContext: createSNSAdaptorSpecializedPostContext({ hasPayloadLike, diff --git a/packages/mask/src/social-network-adaptor/facebook.com/worker-provider.ts b/packages/mask/src/social-network-adaptor/facebook.com/worker-provider.ts deleted file mode 100644 index 72eab72c3dcf..000000000000 --- a/packages/mask/src/social-network-adaptor/facebook.com/worker-provider.ts +++ /dev/null @@ -1,9 +0,0 @@ -import type { SocialNetworkWorker } from '../../social-network' -import { facebookWorkerBase } from './base' -import { facebookShared } from './shared' - -const facebookWorker: SocialNetworkWorker.Definition = { - ...facebookWorkerBase, - ...facebookShared, -} -export default facebookWorker diff --git a/packages/mask/src/social-network-adaptor/instagram.com/base.ts b/packages/mask/src/social-network-adaptor/instagram.com/base.ts index 1c9441b11e06..a337eecfaf67 100644 --- a/packages/mask/src/social-network-adaptor/instagram.com/base.ts +++ b/packages/mask/src/social-network-adaptor/instagram.com/base.ts @@ -1,5 +1,5 @@ import { SocialNetworkEnum } from '@masknet/encryption' -import type { SocialNetwork, SocialNetworkWorker } from '../../social-network/types' +import type { SocialNetwork } from '../../social-network/types' import { EnhanceableSite } from '@masknet/shared-base' const origins = ['https://www.instagram.com/*', 'https://m.instagram.com/*', 'https://instagram.com/*'] @@ -11,7 +11,3 @@ export const instagramBase: SocialNetwork.Base = { return location.host.endsWith(EnhanceableSite.Instagram) }, } -export const instagramWorkerBase: SocialNetworkWorker.WorkerBase & SocialNetwork.Base = { - ...instagramBase, - gunNetworkHint: EnhanceableSite.Instagram, -} diff --git a/packages/mask/src/social-network-adaptor/instagram.com/index.ts b/packages/mask/src/social-network-adaptor/instagram.com/index.ts index 89488a5fac0d..441802b900d7 100644 --- a/packages/mask/src/social-network-adaptor/instagram.com/index.ts +++ b/packages/mask/src/social-network-adaptor/instagram.com/index.ts @@ -1,5 +1,5 @@ -import { defineSocialNetworkUI, defineSocialNetworkWorker } from '../../social-network' -import { instagramBase, instagramWorkerBase } from './base' +import { defineSocialNetworkUI } from '../../social-network' +import { instagramBase } from './base' defineSocialNetworkUI({ ...instagramBase, @@ -12,15 +12,3 @@ defineSocialNetworkUI({ } }, }) - -defineSocialNetworkWorker({ - ...instagramWorkerBase, - load: () => import('./worker-provider'), - hotModuleReload(callback) { - if (import.meta.webpackHot) { - import.meta.webpackHot.accept('./worker-provider.ts', async () => { - callback((await import('./worker-provider')).default) - }) - } - }, -}) diff --git a/packages/mask/src/social-network-adaptor/instagram.com/shared.ts b/packages/mask/src/social-network-adaptor/instagram.com/shared.ts index 3222763f8fc0..5466eaf391a0 100644 --- a/packages/mask/src/social-network-adaptor/instagram.com/shared.ts +++ b/packages/mask/src/social-network-adaptor/instagram.com/shared.ts @@ -6,8 +6,6 @@ import { instagramBase } from './base' export const instagramShared: SocialNetwork.Shared & SocialNetwork.Base = { ...instagramBase, utils: { - getHomePage: () => 'https://www.instagram.com/', - getProfilePage: () => 'https://www.instagram.com/', createPostContext: createSNSAdaptorSpecializedPostContext({ hasPayloadLike, }), diff --git a/packages/mask/src/social-network-adaptor/instagram.com/worker-provider.ts b/packages/mask/src/social-network-adaptor/instagram.com/worker-provider.ts deleted file mode 100644 index 98b9b18969f2..000000000000 --- a/packages/mask/src/social-network-adaptor/instagram.com/worker-provider.ts +++ /dev/null @@ -1,8 +0,0 @@ -import type { SocialNetworkWorker } from '../../social-network' -import { instagramWorkerBase } from './base' -import { instagramShared } from './shared' -const define: SocialNetworkWorker.Definition = { - ...instagramWorkerBase, - ...instagramShared, -} -export default define diff --git a/packages/mask/src/social-network-adaptor/minds.com/base.ts b/packages/mask/src/social-network-adaptor/minds.com/base.ts index 4d2175d8402c..866bb8accc79 100644 --- a/packages/mask/src/social-network-adaptor/minds.com/base.ts +++ b/packages/mask/src/social-network-adaptor/minds.com/base.ts @@ -1,5 +1,5 @@ import { SocialNetworkEnum } from '@masknet/encryption' -import type { SocialNetwork, SocialNetworkWorker } from '../../social-network/types' +import type { SocialNetwork } from '../../social-network/types' import { EnhanceableSite } from '@masknet/shared-base' const origins = ['https://www.minds.com/*', 'https://minds.com/*', 'https://cdn.minds.com/*'] @@ -15,8 +15,3 @@ export const mindsBase: SocialNetwork.Base = { export function isMinds(ui: SocialNetwork.Base) { return ui.networkIdentifier === EnhanceableSite.Minds } - -export const mindsWorkerBase: SocialNetworkWorker.WorkerBase & SocialNetwork.Base = { - ...mindsBase, - gunNetworkHint: 'minds-', -} diff --git a/packages/mask/src/social-network-adaptor/minds.com/index.ts b/packages/mask/src/social-network-adaptor/minds.com/index.ts index a12f93edbba3..bbc3fac5dd0a 100644 --- a/packages/mask/src/social-network-adaptor/minds.com/index.ts +++ b/packages/mask/src/social-network-adaptor/minds.com/index.ts @@ -1,5 +1,5 @@ -import { defineSocialNetworkUI, defineSocialNetworkWorker } from '../../social-network' -import { mindsBase, mindsWorkerBase } from './base' +import { defineSocialNetworkUI } from '../../social-network' +import { mindsBase } from './base' defineSocialNetworkUI({ ...mindsBase, @@ -12,15 +12,3 @@ defineSocialNetworkUI({ } }, }) - -defineSocialNetworkWorker({ - ...mindsWorkerBase, - load: () => import('./worker-provider'), - hotModuleReload(callback) { - if (import.meta.webpackHot) { - import.meta.webpackHot.accept('./worker-provider.ts', async () => { - callback((await import('./worker-provider')).default) - }) - } - }, -}) diff --git a/packages/mask/src/social-network-adaptor/minds.com/shared.ts b/packages/mask/src/social-network-adaptor/minds.com/shared.ts index 5032ef24edf7..a104fb243572 100644 --- a/packages/mask/src/social-network-adaptor/minds.com/shared.ts +++ b/packages/mask/src/social-network-adaptor/minds.com/shared.ts @@ -1,11 +1,11 @@ import type { PostIdentifier } from '@masknet/shared-base' import { openWindow } from '@masknet/shared-base-ui' -import urlcat from 'urlcat' import type { SocialNetwork } from '../../social-network/types' import { createSNSAdaptorSpecializedPostContext } from '../../social-network/utils/create-post-context' import { hasPayloadLike } from '../../utils' import { mindsBase } from './base' import { usernameValidator } from './utils/user' +import { MindsAdaptor } from '../../../shared/site-adaptors/implementations/minds.com' const getPostURL = (post: PostIdentifier): URL => { return new URL(`https://minds.com/newsfeed/${post.postId}`) @@ -13,19 +13,10 @@ const getPostURL = (post: PostIdentifier): URL => { export const mindsShared: SocialNetwork.Shared & SocialNetwork.Base = { ...mindsBase, utils: { - getHomePage: () => 'https://www.minds.com', - getProfilePage: () => 'https://www.minds.com', isValidUsername: usernameValidator, - textPayloadPostProcessor: undefined, getPostURL, share(message) { - openWindow(this.getShareLinkURL?.(message)) - }, - getShareLinkURL(message) { - const url = urlcat('https://www.minds.com/newsfeed/subscriptions', { - intentUrl: message, - }) - return new URL(url) + openWindow(MindsAdaptor.getShareLinkURL?.(message)) }, createPostContext: createSNSAdaptorSpecializedPostContext({ hasPayloadLike, diff --git a/packages/mask/src/social-network-adaptor/minds.com/worker-provider.ts b/packages/mask/src/social-network-adaptor/minds.com/worker-provider.ts deleted file mode 100644 index a15bb7709881..000000000000 --- a/packages/mask/src/social-network-adaptor/minds.com/worker-provider.ts +++ /dev/null @@ -1,9 +0,0 @@ -import type { SocialNetworkWorker } from '../../social-network' -import { mindsWorkerBase } from './base' -import { mindsShared } from './shared' - -const mindsWorker: SocialNetworkWorker.Definition = { - ...mindsWorkerBase, - ...mindsShared, -} -export default mindsWorker diff --git a/packages/mask/src/social-network-adaptor/opensea.io/base.ts b/packages/mask/src/social-network-adaptor/opensea.io/base.ts index dd3c9cee793b..f2a8b1cb4f3f 100644 --- a/packages/mask/src/social-network-adaptor/opensea.io/base.ts +++ b/packages/mask/src/social-network-adaptor/opensea.io/base.ts @@ -1,5 +1,5 @@ import { SocialNetworkEnum } from '@masknet/encryption' -import type { SocialNetwork, SocialNetworkWorker } from '../../social-network/types' +import type { SocialNetwork } from '../../social-network/types' import { EnhanceableSite } from '@masknet/shared-base' const origins = ['https://opensea.io/*'] @@ -12,7 +12,3 @@ export const openseaBase: SocialNetwork.Base = { }, notReadyForProduction: true, } -export const openseaWorkerBase: SocialNetworkWorker.WorkerBase & SocialNetwork.Base = { - ...openseaBase, - gunNetworkHint: '', -} diff --git a/packages/mask/src/social-network-adaptor/opensea.io/index.ts b/packages/mask/src/social-network-adaptor/opensea.io/index.ts index ed4dd79d8b70..cd8e95d18357 100644 --- a/packages/mask/src/social-network-adaptor/opensea.io/index.ts +++ b/packages/mask/src/social-network-adaptor/opensea.io/index.ts @@ -1,5 +1,5 @@ -import { defineSocialNetworkUI, defineSocialNetworkWorker } from '../../social-network' -import { openseaBase, openseaWorkerBase } from './base' +import { defineSocialNetworkUI } from '../../social-network' +import { openseaBase } from './base' defineSocialNetworkUI({ ...openseaBase, @@ -12,15 +12,3 @@ defineSocialNetworkUI({ } }, }) - -defineSocialNetworkWorker({ - ...openseaWorkerBase, - load: () => import('./worker-provider'), - hotModuleReload(callback) { - if (import.meta.webpackHot) { - import.meta.webpackHot.accept('./worker-provider.ts', async () => { - callback((await import('./worker-provider')).default) - }) - } - }, -}) diff --git a/packages/mask/src/social-network-adaptor/opensea.io/shared.ts b/packages/mask/src/social-network-adaptor/opensea.io/shared.ts index 751e289eb736..8c9e2efdbaef 100644 --- a/packages/mask/src/social-network-adaptor/opensea.io/shared.ts +++ b/packages/mask/src/social-network-adaptor/opensea.io/shared.ts @@ -6,8 +6,6 @@ import { openseaBase } from './base' export const openseaShared: SocialNetwork.Shared & SocialNetwork.Base = { ...openseaBase, utils: { - getHomePage: () => 'https://opensea.io/', - getProfilePage: () => 'https://opensea.io/account', createPostContext: createSNSAdaptorSpecializedPostContext({ hasPayloadLike, }), diff --git a/packages/mask/src/social-network-adaptor/opensea.io/worker-provider.ts b/packages/mask/src/social-network-adaptor/opensea.io/worker-provider.ts deleted file mode 100644 index ec4c524d2ee6..000000000000 --- a/packages/mask/src/social-network-adaptor/opensea.io/worker-provider.ts +++ /dev/null @@ -1,9 +0,0 @@ -import type { SocialNetworkWorker } from '../../social-network' -import { openseaWorkerBase } from './base' -import { openseaShared } from './shared' - -const openseaWorker: SocialNetworkWorker.Definition = { - ...openseaWorkerBase, - ...openseaShared, -} -export default openseaWorker diff --git a/packages/mask/src/social-network-adaptor/twitter.com/base.ts b/packages/mask/src/social-network-adaptor/twitter.com/base.ts index 961d7087a648..273193395c74 100644 --- a/packages/mask/src/social-network-adaptor/twitter.com/base.ts +++ b/packages/mask/src/social-network-adaptor/twitter.com/base.ts @@ -1,5 +1,5 @@ import { SocialNetworkEnum } from '@masknet/encryption' -import type { SocialNetwork, SocialNetworkWorker } from '../../social-network/types' +import type { SocialNetwork } from '../../social-network/types' import { EnhanceableSite } from '@masknet/shared-base' const origins = ['https://mobile.twitter.com/*', 'https://twitter.com/*'] @@ -15,8 +15,3 @@ export const twitterBase: SocialNetwork.Base = { export function isTwitter(ui: SocialNetwork.Base) { return ui.networkIdentifier === EnhanceableSite.Twitter } - -export const twitterWorkerBase: SocialNetworkWorker.WorkerBase & SocialNetwork.Base = { - ...twitterBase, - gunNetworkHint: 'twitter-', -} diff --git a/packages/mask/src/social-network-adaptor/twitter.com/index.ts b/packages/mask/src/social-network-adaptor/twitter.com/index.ts index b88804bb5998..feb6b9a6304e 100644 --- a/packages/mask/src/social-network-adaptor/twitter.com/index.ts +++ b/packages/mask/src/social-network-adaptor/twitter.com/index.ts @@ -1,5 +1,5 @@ -import { defineSocialNetworkUI, defineSocialNetworkWorker } from '../../social-network' -import { twitterBase, twitterWorkerBase } from './base' +import { defineSocialNetworkUI } from '../../social-network' +import { twitterBase } from './base' defineSocialNetworkUI({ ...twitterBase, @@ -12,15 +12,3 @@ defineSocialNetworkUI({ } }, }) - -defineSocialNetworkWorker({ - ...twitterWorkerBase, - load: () => import('./worker-provider'), - hotModuleReload(callback) { - if (import.meta.webpackHot) { - import.meta.webpackHot.accept('./worker-provider.ts', async () => { - callback((await import('./worker-provider')).default) - }) - } - }, -}) diff --git a/packages/mask/src/social-network-adaptor/twitter.com/injection/ProfileSlider.tsx b/packages/mask/src/social-network-adaptor/twitter.com/injection/ProfileSlider.tsx deleted file mode 100644 index 2040ca2cbd66..000000000000 --- a/packages/mask/src/social-network-adaptor/twitter.com/injection/ProfileSlider.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import { MutationObserverWatcher } from '@dimensiondev/holoflows-kit' -import { ProfileSlider } from '../../../components/InjectedComponents/ProfileSlider' -import { createReactRootShadowed } from '../../../utils/shadow-root/renderInShadowRoot' -import { startWatch } from '../../../utils/watcher' -import { searchResultHeadingSelector } from '../utils/selector' - -export function injectProfileSliderAtTwitter(signal: AbortSignal) { - const watcher = new MutationObserverWatcher(searchResultHeadingSelector()) - startWatch(watcher, signal) - createReactRootShadowed(watcher.firstDOMProxy.afterShadow, { signal }).render() -} diff --git a/packages/mask/src/social-network-adaptor/twitter.com/shared.ts b/packages/mask/src/social-network-adaptor/twitter.com/shared.ts index 67ef909e24e2..896ba29222da 100644 --- a/packages/mask/src/social-network-adaptor/twitter.com/shared.ts +++ b/packages/mask/src/social-network-adaptor/twitter.com/shared.ts @@ -1,12 +1,12 @@ import { PostIdentifier, ProfileIdentifier } from '@masknet/shared-base' import { openWindow } from '@masknet/shared-base-ui' -import urlcat from 'urlcat' import type { SocialNetwork } from '../../social-network/types' import { createSNSAdaptorSpecializedPostContext } from '../../social-network/utils/create-post-context' import { hasPayloadLike } from '../../utils' import { twitterBase } from './base' -import { TwitterDecoder, __TwitterEncoder } from '@masknet/encryption' +import { TwitterDecoder } from '@masknet/encryption' import { usernameValidator } from './utils/user' +import { TwitterAdaptor } from '../../../shared/site-adaptors/implementations/twitter.com' const getPostURL = (post: PostIdentifier): URL | null => { if (!(post.identifier instanceof ProfileIdentifier)) return null @@ -15,20 +15,10 @@ const getPostURL = (post: PostIdentifier): URL | null => { export const twitterShared: SocialNetwork.Shared & SocialNetwork.Base = { ...twitterBase, utils: { - getHomePage: () => 'https://twitter.com', - getProfilePage: (userId) => `https://twitter.com/${userId}`, isValidUsername: usernameValidator, - textPayloadPostProcessor: { - encoder: __TwitterEncoder, - decoder(text) { - return TwitterDecoder(text) - .map((x) => [x]) - .unwrapOr([]) - }, - }, getPostURL, share(text) { - const url = this.getShareLinkURL!(text) + const url = TwitterAdaptor.getShareLinkURL!(text) const width = 700 const height = 520 const openedWindow = openWindow(url, 'share', { @@ -49,10 +39,6 @@ export const twitterShared: SocialNetwork.Shared & SocialNetwork.Base = { location.assign(url) } }, - getShareLinkURL(message) { - const url = urlcat('https://twitter.com/intent/tweet', { text: message }) - return new URL(url) - }, createPostContext: createSNSAdaptorSpecializedPostContext({ hasPayloadLike: (text) => { return TwitterDecoder(text).map(hasPayloadLike).unwrapOr(false) diff --git a/packages/mask/src/social-network-adaptor/twitter.com/ui-provider.ts b/packages/mask/src/social-network-adaptor/twitter.com/ui-provider.ts index a3e1c4fb8a7b..02f4f9d39d10 100644 --- a/packages/mask/src/social-network-adaptor/twitter.com/ui-provider.ts +++ b/packages/mask/src/social-network-adaptor/twitter.com/ui-provider.ts @@ -13,7 +13,6 @@ import { PaletteModeProviderTwitter, useThemeTwitterVariant } from './customizat import { injectToolboxHintAtTwitter } from './injection/ToolboxHint' import { i18NOverwriteTwitter } from './customization/i18n' import { injectSearchResultBoxAtTwitter } from './injection/SearchResultBox' -import { injectProfileSliderAtTwitter } from './injection/ProfileSlider' import { injectProfileTabAtTwitter } from './injection/ProfileTab' import { injectProfileTabContentAtTwitter } from './injection/ProfileTabContent' import { injectPostReplacerAtTwitter } from './injection/PostReplacer' @@ -156,7 +155,6 @@ const twitterUI: SocialNetworkUI.Definition = { searchResult: injectSearchResultBoxAtTwitter, profileTab: injectProfileTabAtTwitter, profileTabContent: injectProfileTabContentAtTwitter, - profileSlider: injectProfileSliderAtTwitter, enhancedPostRenderer: injectPostReplacerAtTwitter, pageInspector: injectPageInspectorDefault(), postInspector: injectPostInspectorAtTwitter, diff --git a/packages/mask/src/social-network-adaptor/twitter.com/worker-provider.ts b/packages/mask/src/social-network-adaptor/twitter.com/worker-provider.ts deleted file mode 100644 index 93c64a1aa6bb..000000000000 --- a/packages/mask/src/social-network-adaptor/twitter.com/worker-provider.ts +++ /dev/null @@ -1,9 +0,0 @@ -import type { SocialNetworkWorker } from '../../social-network' -import { twitterWorkerBase } from './base' -import { twitterShared } from './shared' - -const twitterWorker: SocialNetworkWorker.Definition = { - ...twitterWorkerBase, - ...twitterShared, -} -export default twitterWorker diff --git a/packages/mask/src/social-network/define.ts b/packages/mask/src/social-network/define.ts index 4c1739f7f09a..2e14b4faa6d5 100644 --- a/packages/mask/src/social-network/define.ts +++ b/packages/mask/src/social-network/define.ts @@ -1,4 +1,4 @@ -import type { SocialNetworkUI, SocialNetworkWorker } from './types' +import type { SocialNetworkUI } from './types' const definedSocialNetworkUIsLocal = new Map() export const definedSocialNetworkUIs: ReadonlyMap = @@ -16,11 +16,3 @@ export function defineSocialNetworkUI(UI: SocialNetworkUI.DeferredDefinition) { definedSocialNetworkUIsLocal.set(UI.networkIdentifier, UI) return UI } - -export const definedSocialNetworkWorkers = new Set() -export function defineSocialNetworkWorker(worker: SocialNetworkWorker.DeferredDefinition) { - if (worker.notReadyForProduction) { - if (process.env.channel === 'stable' && process.env.NODE_ENV === 'production') return - } - definedSocialNetworkWorkers.add(worker) -} diff --git a/packages/mask/src/social-network/index.ts b/packages/mask/src/social-network/index.ts index 06b102fd72e8..ffb3f38c326c 100644 --- a/packages/mask/src/social-network/index.ts +++ b/packages/mask/src/social-network/index.ts @@ -2,4 +2,3 @@ export * from './types' export * from './utils' export * from './ui' export * from './define' -export * from './worker' diff --git a/packages/mask/src/social-network/types.ts b/packages/mask/src/social-network/types.ts index ccce3795ddb5..f0fb79f35272 100644 --- a/packages/mask/src/social-network/types.ts +++ b/packages/mask/src/social-network/types.ts @@ -16,29 +16,12 @@ import type { PaletteMode, Theme } from '@mui/material' import type { Subscription } from 'use-subscription' import type { createSNSAdaptorSpecializedPostContext } from './utils/create-post-context' -// Don't define values in namespaces -export namespace SocialNetwork { - export interface PayloadEncoding { - encoder(text: string): string - /** - * the result is candidates - */ - decoder(text: string): string[] - } - +export declare namespace SocialNetwork { export interface Utils { - /** @returns the homepage url. e.g.: https://twitter.com/ */ - getHomePage?(): string - /** @returns the profile url. e.g.: https://twitter.com/realMaskNetwork */ - getProfilePage?(userId?: string): string /** @returns post URL from PostIdentifier */ getPostURL?(post: PostIdentifier): URL | null /** Is this username valid in this network */ isValidUsername?(username: string): boolean - /** How to encode/decode text payload (e.g. make it into a link so it will be shortened by SNS). */ - textPayloadPostProcessor?: PayloadEncoding - /** Given a text, return a URL that will allow user to share this text */ - getShareLinkURL?(text: string): URL /** Handle share */ share?(text: string): void createPostContext: ReturnType @@ -80,7 +63,6 @@ export namespace SocialNetworkUI { export interface Definition extends SocialNetwork.Base, SocialNetwork.Shared { /** @returns the states */ init(signal: AbortSignal): Readonly | Promise> - permission?: RuntimePermission injection: InjectingCapabilities.Define automation: AutomationCapabilities.Define collecting: CollectingCapabilities.Define @@ -92,12 +74,6 @@ export namespace SocialNetworkUI { /** My profiles at current network */ readonly profiles: ValueRef } - export interface RuntimePermission { - /** This function should check if Mask has the permission to the site */ - has(): Promise - /** This function should request the related permission, e.g. `browser.permissions.request()` */ - request(): Promise - } export interface DeclarativePermission { origins: readonly string[] } @@ -123,8 +99,6 @@ export namespace SocialNetworkUI { userBadge?(signal: AbortSignal): void /** Inject UI to the search result */ searchResult?(signal: AbortSignal): void - /** Inject UI to the profile slider */ - profileSlider?(signal: AbortSignal): void /** Inject UI to the profile tab */ profileTab?(signal: AbortSignal): void /** Inject UI to the profile page */ @@ -147,13 +121,9 @@ export namespace SocialNetworkUI { /** @deprecated same reason as userAvatar */ profileTip?(signal: AbortSignal): void /** @deprecated same reason as userAvatar */ - postAvatar?(signal: AbortSignal, current: PostInfo): void - /** @deprecated same reason as userAvatar */ openNFTAvatar?(signal: AbortSignal): void /** @deprecated same reason as userAvatar */ postAndReplyNFTAvatar?(signal: AbortSignal): void - /** @deprecated same reason as userAvatar */ - collectionAvatar?(signal: AbortSignal): void /** @deprecated same reason as useAvatar */ avatarClipNFT?(signal: AbortSignal): void } @@ -222,7 +192,6 @@ export namespace SocialNetworkUI { /** Get searched keyword */ getSearchedKeyword?(): string } - export type ProfileUI = { bioContent: string } /** Resolve the information of who am I on the current network. */ export interface IdentityResolveProvider { @@ -304,29 +273,3 @@ export namespace SocialNetworkUI { } } } - -export namespace SocialNetworkWorker { - export interface WorkerBase { - /** - * Hint for partition when finding keys on Gun - * - * For Facebook.com, use "" - * For network with a large number of users, use something like "twitter-" - * For other networks, to keep the Anti-censor of the gun v2 design, - * use string like "anonymous-" - */ - gunNetworkHint: string - } - export interface DeferredDefinition extends SocialNetwork.Base, WorkerBase { - load(): Promise<{ default: Definition }> - /** - * On Hot Module Reload. When call the callback, it will unload the current instance and load the new one. - */ - hotModuleReload?(onHot: (hot: Definition) => void): void - } - - /** - * A SocialNetworkWorker is running in the background page - */ - export interface Definition extends SocialNetwork.Base, SocialNetwork.Shared, WorkerBase {} -} diff --git a/packages/mask/src/social-network/ui.ts b/packages/mask/src/social-network/ui.ts index 63cdcf357d48..cdb08a3142e9 100644 --- a/packages/mask/src/social-network/ui.ts +++ b/packages/mask/src/social-network/ui.ts @@ -28,10 +28,6 @@ export let activatedSocialNetworkUI: SocialNetworkUI.Definition = { collecting: {}, customization: {}, configuration: {}, - permission: { - has: async () => false, - request: async () => false, - }, init: () => { throw new Error() }, diff --git a/packages/mask/src/social-network/utils/text-payload-ui.ts b/packages/mask/src/social-network/utils/text-payload-ui.ts deleted file mode 100644 index 744ab5bf30d7..000000000000 --- a/packages/mask/src/social-network/utils/text-payload-ui.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { activatedSocialNetworkUI } from '../ui' -export function decodeTextPayloadUI(x: string): string[] { - const f = activatedSocialNetworkUI.utils.textPayloadPostProcessor?.decoder - if (f) return f(x).concat(x) - return [x] -} diff --git a/packages/mask/src/social-network/worker.ts b/packages/mask/src/social-network/worker.ts deleted file mode 100644 index 37327e56384e..000000000000 --- a/packages/mask/src/social-network/worker.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { isEnvironment, Environment } from '@dimensiondev/holoflows-kit' -import { definedSocialNetworkWorkers } from './define' -import type { SocialNetworkWorker } from './types' -import type { ProfileIdentifier } from '@masknet/shared-base' - -export const definedSocialNetworkWorkersResolved = new Set() - -async function activateNetworkWorker(id: string): Promise { - if (!isEnvironment(Environment.ManifestBackground)) { - throw new TypeError() - } - for (const each of definedSocialNetworkWorkersResolved) { - if (each.networkIdentifier === id) return each - } - for (const each of definedSocialNetworkWorkers) { - if (each.networkIdentifier === id) { - const worker = (await each.load()).default - definedSocialNetworkWorkersResolved.add(worker) - return worker - } - } - throw new Error('Worker not found') -} -export async function getNetworkWorker(network: string | ProfileIdentifier): Promise { - if (typeof network === 'string') return activateNetworkWorker(network) - return getNetworkWorker(network.network) -} diff --git a/packages/plugin-infra/src/types.ts b/packages/plugin-infra/src/types.ts index 15aa383c7e6b..7022f50697aa 100644 --- a/packages/plugin-infra/src/types.ts +++ b/packages/plugin-infra/src/types.ts @@ -240,8 +240,6 @@ export namespace Plugin.SNSAdaptor { CompositionDialogMetadataBadgeRender?: CompositionMetadataBadgeRender /** This UI will be rendered as an entry in the wallet status dialog */ ApplicationEntries?: ApplicationEntry[] - /** This UI will be rendered as sliders on the profile page */ - ProfileSliders?: ProfileSlider[] /** This UI will be rendered as tabs on the profile page */ ProfileTabs?: ProfileTab[] /** This UI will be rendered as plugin wrapper page */ @@ -374,23 +372,6 @@ export namespace Plugin.SNSAdaptor { resolvedAddress: string } - export interface ProfileSlider { - ID: string - - /** - * The name of the slider card - */ - label: I18NStringField | string - /** - * Used to order the sliders - */ - priority: number - /** - * The injected UI - */ - children: InjectUI<{}> - } - export interface ProfileTab { ID: string