diff --git a/package.json b/package.json index ec01aa2c29..0004e2aa28 100644 --- a/package.json +++ b/package.json @@ -16,8 +16,6 @@ "build:chrome:core": "cross-env CORE_BUILD=true run-s build:chrome", "build:firefox": "cross-env TARGET_BROWSER=firefox run-s build", "build:firefox:core": "cross-env CORE_BUILD=true run-s build:firefox", - "build:safari": "cross-env TARGET_BROWSER=safari run-s build", - "build:safari:core": "cross-env CORE_BUILD=true run-s build:safari", "build:opera": "cross-env TARGET_BROWSER=opera run-s build", "build:opera:core": "cross-env CORE_BUILD=true run-s build:opera", "test": "jest", diff --git a/src/app/ConfirmPage.tsx b/src/app/ConfirmPage.tsx index 34959ae857..637a1debf1 100644 --- a/src/app/ConfirmPage.tsx +++ b/src/app/ConfirmPage.tsx @@ -4,6 +4,7 @@ import clsx from 'clsx'; import { AccountTypeBadge, Alert, FormSubmitButton, FormSecondaryButton } from 'app/atoms'; import ConfirmLedgerOverlay from 'app/atoms/ConfirmLedgerOverlay'; +import DAppLogo from 'app/atoms/DAppLogo'; import HashShortView from 'app/atoms/HashShortView'; import Money from 'app/atoms/Money'; import Name from 'app/atoms/Name'; @@ -16,7 +17,6 @@ import AccountBanner from 'app/templates/AccountBanner'; import { TezosBalance } from 'app/templates/Balance'; import ConnectBanner from 'app/templates/ConnectBanner'; import CustomSelect, { OptionRenderProps } from 'app/templates/CustomSelect'; -import DAppLogo from 'app/templates/DAppLogo'; import { ModifyFeeAndLimit } from 'app/templates/ExpensesView/ExpensesView'; import NetworkBanner from 'app/templates/NetworkBanner'; import OperationView from 'app/templates/OperationView'; @@ -278,7 +278,7 @@ const ConfirmDAppForm = memo(() => { want: (
- + {payload.appMeta.name} @@ -305,7 +305,7 @@ const ConfirmDAppForm = memo(() => { want: (
- + {payload.appMeta.name} diff --git a/src/app/PageRouter.tsx b/src/app/PageRouter.tsx index b1809b6bce..6aacd1cb91 100644 --- a/src/app/PageRouter.tsx +++ b/src/app/PageRouter.tsx @@ -7,7 +7,6 @@ import Exolix from 'app/pages/Buy/Crypto/Exolix/Exolix'; import { BuyWithCreditCard } from 'app/pages/BuyWithCreditCard/BuyWithCreditCard'; import CollectiblePage from 'app/pages/Collectibles/CollectiblePage'; import ConnectLedger from 'app/pages/ConnectLedger/ConnectLedger'; -import DApps from 'app/pages/DApps'; import Delegate from 'app/pages/Delegate'; import Home from 'app/pages/Home/Home'; import AttentionPage from 'app/pages/Onboarding/pages/AttentionPage'; @@ -85,7 +84,6 @@ const ROUTE_MAP = Woozie.createMap([ ['/swap', onlyReady(() => )], ['/delegate/:tezosChainId', onlyReady(({ tezosChainId }) => )], ['/staking/:tezosChainId', onlyReady(({ tezosChainId }) => )], - ['/dapps', onlyReady(() => )], [ '/collectible/:chainKind?/:chainId?/:assetSlug?', onlyReady(({ chainKind, chainId, assetSlug }) => ( diff --git a/src/app/atoms/DAppLogo/index.tsx b/src/app/atoms/DAppLogo/index.tsx new file mode 100644 index 0000000000..fa8c17a019 --- /dev/null +++ b/src/app/atoms/DAppLogo/index.tsx @@ -0,0 +1,42 @@ +import React, { CSSProperties, memo, useMemo } from 'react'; + +import clsx from 'clsx'; + +import { ImageStacked } from 'lib/ui/ImageStacked'; + +import { IconBase } from '../IconBase'; + +import { ReactComponent as PlugSvg } from './plug.svg'; + +interface DAppLogoProps { + origin: string; + size: number; + className?: string; + icon?: string; + style?: CSSProperties; +} + +const DAppLogo = memo(({ origin, size, icon, className, style }) => { + const faviconSrc = useMemo(() => [icon ? icon : `${origin}/favicon.ico`], [origin, icon]); + + const styleMemo = useMemo(() => ({ width: size, height: size, ...style }), [style, size]); + + const placeholder = ( +
+ +
+ ); + + return ( + + ); +}); + +export default DAppLogo; diff --git a/src/app/atoms/DAppLogo/plug.svg b/src/app/atoms/DAppLogo/plug.svg new file mode 100644 index 0000000000..bfedc9554e --- /dev/null +++ b/src/app/atoms/DAppLogo/plug.svg @@ -0,0 +1,6 @@ + + + diff --git a/src/app/atoms/EmptyState.tsx b/src/app/atoms/EmptyState.tsx index 29b88abd0d..1c93a6e9f0 100644 --- a/src/app/atoms/EmptyState.tsx +++ b/src/app/atoms/EmptyState.tsx @@ -4,18 +4,25 @@ import clsx from 'clsx'; import { ReactComponent as SadSearchIcon } from 'app/icons/monochrome/sad-search.svg'; import { ReactComponent as SadUniversalIcon } from 'app/icons/monochrome/sad-universal.svg'; -import { T } from 'lib/i18n'; +import { T, TID } from 'lib/i18n'; interface EmptyStateProps { - className?: string; - variant: 'tokenSearch' | 'universal' | 'searchUniversal'; + forSearch?: boolean; + textI18n?: TID; + text?: string; + stretch?: boolean; } -export const EmptyState = memo(({ className, variant }) => ( -
- {variant === 'universal' ? : } - - - -
-)); +export const EmptyState = memo(({ forSearch = true, textI18n, text, stretch }) => { + const Icon = forSearch ? SadSearchIcon : SadUniversalIcon; + + return ( +
+ + + + {textI18n ? : text || } + +
+ ); +}); diff --git a/src/app/atoms/loader/index.tsx b/src/app/atoms/Loader/index.tsx similarity index 100% rename from src/app/atoms/loader/index.tsx rename to src/app/atoms/Loader/index.tsx diff --git a/src/app/atoms/loader/loader.module.css b/src/app/atoms/Loader/loader.module.css similarity index 100% rename from src/app/atoms/loader/loader.module.css rename to src/app/atoms/Loader/loader.module.css diff --git a/src/app/atoms/PageModal/actions-buttons-box.tsx b/src/app/atoms/PageModal/actions-buttons-box.tsx index 3bffb75ac1..71d1aa3083 100644 --- a/src/app/atoms/PageModal/actions-buttons-box.tsx +++ b/src/app/atoms/PageModal/actions-buttons-box.tsx @@ -8,12 +8,12 @@ import { setToastsContainerBottomShiftAction } from 'app/store/settings/actions' interface ActionsButtonsBoxProps extends HTMLAttributes { shouldCastShadow?: boolean; - flexDirection?: 'row' | 'col'; + bgSet?: false; shouldChangeBottomShift?: boolean; } export const ActionsButtonsBox = memo( - ({ className, shouldCastShadow, flexDirection = 'col', shouldChangeBottomShift = true, ...restProps }) => { + ({ className, shouldCastShadow, bgSet = true, shouldChangeBottomShift = true, ...restProps }) => { const dispatch = useDispatch(); useEffect(() => { @@ -23,7 +23,7 @@ export const ActionsButtonsBox = memo( const handleResize = useMemo( () => throttle(entries => { - const borderBoxSize = entries.map(entry => entry.borderBoxSize?.[0]).filter(Boolean)[0]; + const borderBoxSize = entries.map(entry => entry.borderBoxSize[0]).filter(Boolean)[0]; if (borderBoxSize && shouldChangeBottomShift) { dispatch(setToastsContainerBottomShiftAction(borderBoxSize.blockSize - 24)); @@ -48,8 +48,8 @@ export const ActionsButtonsBox = memo( return (
= ({ className, children }) => { + const [contentHiding, setContentHiding] = useSafeState(false); + + const ref = useRef(); + + const setContentHidingThrottled = useMemo(() => throttle((value: boolean) => setContentHiding(value), 300), []); + + const onScroll = useCallback>(event => { + const node = event.currentTarget; + + setContentHidingThrottled(isContentHidingBelow(node)); + }, []); + + const resizeObserver = useMemo( + () => + new ResizeObserver(() => { + const node = ref.current; + + if (node) setContentHidingThrottled(isContentHidingBelow(node)); + }), + [] + ); + + useWillUnmount(() => void resizeObserver.disconnect()); + + const refFn = useCallback((node: HTMLDivElement | null) => { + ref.current = node; + if (!node) return void setContentHiding(false); + + resizeObserver.observe(node); + + setContentHiding(isContentHidingBelow(node)); + }, []); + + return ( +
+ {children} +
+ ); +}; + +function isContentHidingBelow(node: HTMLDivElement) { + const scrollBottom = node.scrollHeight - node.clientHeight - node.scrollTop; + + return node.scrollHeight > node.clientHeight && scrollBottom > 0; +} diff --git a/src/app/atoms/index.ts b/src/app/atoms/index.ts index ea7231d992..31b210f61f 100644 --- a/src/app/atoms/index.ts +++ b/src/app/atoms/index.ts @@ -24,6 +24,8 @@ export { HashChip } from './HashChip'; export { Lines } from './Lines'; +export { Loader } from './Loader'; + export { ExternalLinkChip } from './ExternalLinkChip'; export { default as SubTitle } from './SubTitle'; diff --git a/src/app/icons/base/unlink.svg b/src/app/icons/base/unlink.svg new file mode 100644 index 0000000000..5f0af3a231 --- /dev/null +++ b/src/app/icons/base/unlink.svg @@ -0,0 +1,19 @@ + + + + + + + + + diff --git a/src/app/icons/monochrome/apps-alt.svg b/src/app/icons/monochrome/apps-alt.svg deleted file mode 100644 index 4c2e3e3d99..0000000000 --- a/src/app/icons/monochrome/apps-alt.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - diff --git a/src/app/icons/monochrome/sad-search.svg b/src/app/icons/monochrome/sad-search.svg index da3ab1bb7c..b1f9265b86 100644 --- a/src/app/icons/monochrome/sad-search.svg +++ b/src/app/icons/monochrome/sad-search.svg @@ -1,11 +1,13 @@ - - - - + + + + + + diff --git a/src/app/icons/monochrome/sad-universal.svg b/src/app/icons/monochrome/sad-universal.svg index d26b64334d..22b1e802cb 100644 --- a/src/app/icons/monochrome/sad-universal.svg +++ b/src/app/icons/monochrome/sad-universal.svg @@ -1,4 +1,10 @@ - - - + + + + + diff --git a/src/app/icons/tag.svg b/src/app/icons/tag.svg deleted file mode 100644 index b7c1899483..0000000000 --- a/src/app/icons/tag.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/app/layouts/PageLayout/index.tsx b/src/app/layouts/PageLayout/index.tsx index dadc15ccad..31ead375a7 100644 --- a/src/app/layouts/PageLayout/index.tsx +++ b/src/app/layouts/PageLayout/index.tsx @@ -41,16 +41,18 @@ interface ScrollEdgesVisibilityProps { export interface PageLayoutProps extends DefaultHeaderProps, ScrollEdgesVisibilityProps { /** With this given, header props are ignored */ Header?: ComponentType; + noScroll?: boolean; contentPadding?: boolean; - paperClassName?: string; + dimBg?: boolean; headerChildren?: ReactNode; } const PageLayout: FC> = ({ Header, children, + noScroll = false, contentPadding = true, - paperClassName, + dimBg = true, headerChildren, onBottomEdgeVisibilityChange, bottomEdgeThreshold, @@ -74,7 +76,6 @@ const PageLayout: FC> = ({
> = ({ > {Header ?
: {headerChildren}} -
+
{children}
diff --git a/src/app/pages/AccountSettings/index.tsx b/src/app/pages/AccountSettings/index.tsx index 18178bf23d..f54d3df410 100644 --- a/src/app/pages/AccountSettings/index.tsx +++ b/src/app/pages/AccountSettings/index.tsx @@ -94,6 +94,7 @@ export const AccountSettings = memo(({ id }) => { setCurrentModal(null); setPrivateKeysPayload([]); }, []); + const modal = useMemo(() => { switch (currentModal) { case AccountSettingsModal.EditName: @@ -134,7 +135,7 @@ export const AccountSettings = memo(({ id }) => { @@ -200,6 +201,7 @@ export const AccountSettings = memo(({ id }) => {

+ {derivationPaths.map(({ chainName, path }) => ( (({ id }) => {
)}
+ (({ id }) => { + {modal} ); diff --git a/src/app/pages/DApps.tsx b/src/app/pages/DApps.tsx deleted file mode 100644 index 3e5d07d07f..0000000000 --- a/src/app/pages/DApps.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import React, { FC } from 'react'; - -import { ReactComponent as DAppsIcon } from 'app/icons/monochrome/apps-alt.svg'; -import PageLayout from 'app/layouts/PageLayout'; -import DAppsList from 'app/templates/DAppsList'; -import { t } from 'lib/i18n'; - -const DApps: FC = () => ( - - {t('dApps')} - - } - > - - -); - -export default DApps; diff --git a/src/app/pages/Home/Home.tsx b/src/app/pages/Home/Home.tsx index ff0c0f687e..66cbb9313d 100644 --- a/src/app/pages/Home/Home.tsx +++ b/src/app/pages/Home/Home.tsx @@ -90,7 +90,7 @@ const Home = memo(props => { {showScamTokenAlert && } -
+
{chainKind && chainId && assetSlug ? ( ) : ( diff --git a/src/app/pages/Home/OtherComponents/Tokens/components/AddTokenModal/SelectNetworkPage.tsx b/src/app/pages/Home/OtherComponents/Tokens/components/AddTokenModal/SelectNetworkPage.tsx index de661c9ed6..e167822b1d 100644 --- a/src/app/pages/Home/OtherComponents/Tokens/components/AddTokenModal/SelectNetworkPage.tsx +++ b/src/app/pages/Home/OtherComponents/Tokens/components/AddTokenModal/SelectNetworkPage.tsx @@ -65,7 +65,7 @@ export const SelectNetworkPage: FC = ({ selectedNetwork,
- {filteredNetworks.length === 0 && } + {filteredNetworks.length === 0 && } {filteredNetworks.map(network => ( (({ forCollectibles, network }) => { return ( <>
- + +
+)); + +const Section: FC> = ({ title, children }) => ( +
+ {title} + + {children} +
+); diff --git a/src/app/pages/Settings/Settings.tsx b/src/app/pages/Settings/Settings.tsx index 530fd94972..9ca94dd233 100644 --- a/src/app/pages/Settings/Settings.tsx +++ b/src/app/pages/Settings/Settings.tsx @@ -20,7 +20,6 @@ import About from 'app/templates/About/About'; import { AccountsManagement } from 'app/templates/AccountsManagement'; import AddressBook from 'app/templates/AddressBook/AddressBook'; import { AdvancedFeatures } from 'app/templates/AdvancedFeatures'; -import DAppSettings from 'app/templates/DAppSettings/DAppSettings'; import { NetworksSettings } from 'app/templates/NetworksSettings'; import { SecuritySettings } from 'app/templates/SecuritySettings'; import GeneralSettings from 'app/templates/SettingsGeneral'; @@ -31,6 +30,7 @@ import { SettingsTabProps } from 'lib/ui/settings-tab-props'; import { Link } from 'lib/woozie'; import { useAccount } from 'temple/front'; +import { DAppsSettings } from './DApps'; import { ResetExtensionModal } from './reset-extension-modal'; import { SettingsSelectors } from './Settings.selectors'; @@ -42,6 +42,8 @@ interface Tab { slug: string; titleI18nKey: TID; Icon: FC; + noScroll?: true; + noPadding?: true; Component: FC; testID?: SettingsSelectors; } @@ -59,6 +61,7 @@ const TABS_GROUPS: Tab[][] = [ return ; }), + noPadding: true, Component: AccountsManagement, testID: SettingsSelectors.accountsManagementButton } @@ -98,7 +101,9 @@ const TABS_GROUPS: Tab[][] = [ slug: 'dapps', titleI18nKey: 'connectedDApps', Icon: DefaultSettingsIconHOC(LinkIcon), - Component: DAppSettings, + Component: DAppsSettings, + noScroll: true, + noPadding: true, testID: SettingsSelectors.dAppsButton }, { @@ -126,6 +131,7 @@ const TABS_GROUPS: Tab[][] = [ } ] ]; + const TABS = TABS_GROUPS.flat(); const Settings = memo(({ tabSlug }) => { @@ -136,14 +142,17 @@ const Settings = memo(({ tabSlug }) => { return ( } - paperClassName="!bg-background" + dimBg headerChildren={headerChildren} + noScroll={activeTab?.noScroll} + contentPadding={!activeTab?.noPadding} > {extensionModalOpened && } + {activeTab ? ( ) : ( -
+
{TABS_GROUPS.map((tabs, i) => ( {tabs.map(({ slug, titleI18nKey, Icon, testID }, j) => ( @@ -166,11 +175,12 @@ const Settings = memo(({ tabSlug }) => { +
diff --git a/src/app/pages/Welcome/Welcome.tsx b/src/app/pages/Welcome/Welcome.tsx index 49097253d7..f297d4579f 100644 --- a/src/app/pages/Welcome/Welcome.tsx +++ b/src/app/pages/Welcome/Welcome.tsx @@ -57,7 +57,7 @@ const Welcome = memo(() => { ); return ( - + ; + +export const getStoredTezosDappsSessions = () => fetchFromStorage(storageKey); + +export const putStoredTezosDappsSessions = (value: TezosDAppsSessionsRecord) => + putToStorage(storageKey, value); diff --git a/src/app/storage/dapps/use-value.hook.ts b/src/app/storage/dapps/use-value.hook.ts new file mode 100644 index 0000000000..4e16c02864 --- /dev/null +++ b/src/app/storage/dapps/use-value.hook.ts @@ -0,0 +1,5 @@ +import { useStorage } from 'lib/temple/front'; + +import { TezosDAppsSessionsRecord, storageKey } from './index'; + +export const useStoredTezosDappsSessions = () => useStorage(storageKey); diff --git a/src/app/templates/AccountsManagement/group-view.tsx b/src/app/templates/AccountsManagement/group-view.tsx index 80f3e3f53a..d2d596b7ce 100644 --- a/src/app/templates/AccountsManagement/group-view.tsx +++ b/src/app/templates/AccountsManagement/group-view.tsx @@ -16,14 +16,14 @@ interface GroupViewProps extends GroupActionsPopperProps { } export const GroupView = memo(({ group, searchValue, ...restProps }) => ( -
-
-
+
+
+
{group.name}
-
+
{t(getPluralKey('accounts', group.accounts.length), String(group.accounts.length))} @@ -34,7 +34,7 @@ export const GroupView = memo(({ group, searchValue, ...restProp {group.accounts.map(acc => ( diff --git a/src/app/templates/AccountsManagement/index.tsx b/src/app/templates/AccountsManagement/index.tsx index a751aa0b96..89454d7a77 100644 --- a/src/app/templates/AccountsManagement/index.tsx +++ b/src/app/templates/AccountsManagement/index.tsx @@ -216,11 +216,11 @@ export const AccountsManagement = memo(({ setHeaderChildren }) return ( <> {filteredGroups.length === 0 ? ( -
- +
+
) : ( -
+
{filteredGroups.map(group => ( void; -}; +} const AddressBook: React.FC = () => { const { removeContact } = useContactsActions(); @@ -87,10 +87,10 @@ const AddressBook: React.FC = () => { export default AddressBook; -type ContactFormData = { +interface ContactFormData { address: string; name: string; -}; +} const SUBMIT_ERROR_TYPE = 'submit-error'; @@ -216,11 +216,11 @@ const AddNewContactForm: React.FC<{ className?: string }> = ({ className }) => { ); }; -const ContactIcon: React.FC> = ({ item }) => ( +const ContactIcon: React.FC> = ({ item }) => ( ); -const ContactContent: React.FC> = ({ item, actions }) => ( +const ContactContent: React.FC> = ({ item, actions }) => (
(({ opened, onRequestClose }) => { {filteredGroups.length === 0 ? (
- +
) : ( filteredGroups.map(group => ( diff --git a/src/app/templates/AppHeader/MenuDropdown/index.tsx b/src/app/templates/AppHeader/MenuDropdown/index.tsx index 303ff6bcb0..ff82fcfaf5 100644 --- a/src/app/templates/AppHeader/MenuDropdown/index.tsx +++ b/src/app/templates/AppHeader/MenuDropdown/index.tsx @@ -8,7 +8,6 @@ import { useShortcutAccountSelectModalIsOpened } from 'app/hooks/use-account-sel import { ReactComponent as FullViewIcon } from 'app/icons/base/fullview.svg'; import { ReactComponent as LockIcon } from 'app/icons/base/lock.svg'; import { ReactComponent as SettingsIcon } from 'app/icons/base/settings.svg'; -import { ReactComponent as DAppsIcon } from 'app/icons/monochrome/apps-alt.svg'; import { T } from 'lib/i18n'; import { NotificationsBell } from 'lib/notifications/components/bell'; import { useTempleClient } from 'lib/temple/front'; @@ -39,14 +38,6 @@ const MenuDropdown = memo(({ opened, setOpened }) => { const actions = useMemo( (): TDropdownAction[] => [ - { - key: 'dapps', - Icon: DAppsIcon, - children: , - linkTo: '/dApps', - testID: MenuDropdownSelectors.dAppsButton, - onClick: closeDropdown - }, { key: 'settings', Icon: SettingsIcon, diff --git a/src/app/templates/ConnectBanner.tsx b/src/app/templates/ConnectBanner.tsx index cc5784ee82..75ca4f74d8 100644 --- a/src/app/templates/ConnectBanner.tsx +++ b/src/app/templates/ConnectBanner.tsx @@ -2,11 +2,11 @@ import React, { FC } from 'react'; import classNames from 'clsx'; +import DAppLogo from 'app/atoms/DAppLogo'; import { Logo } from 'app/atoms/Logo'; import Name from 'app/atoms/Name'; import { ReactComponent as LayersIcon } from 'app/icons/layers.svg'; import { ReactComponent as OkIcon } from 'app/icons/ok.svg'; -import DAppLogo from 'app/templates/DAppLogo'; import { DappMetadata } from 'lib/temple/types'; interface ConnectBannerProps { @@ -22,7 +22,7 @@ const ConnectBanner: FC = ({ type, origin, appMeta, classNam return (
- + {appMeta.name} diff --git a/src/app/templates/CustomSelect.tsx b/src/app/templates/CustomSelect.tsx index 19a7940e50..667216ca83 100644 --- a/src/app/templates/CustomSelect.tsx +++ b/src/app/templates/CustomSelect.tsx @@ -4,15 +4,13 @@ import classNames from 'clsx'; import { ReactComponent as OkIcon } from 'app/icons/ok.svg'; -type Actions = { [key: string]: (id: K) => void }; - -export type OptionRenderProps = {}> = { +export interface OptionRenderProps { actions?: A; item: T; index: number; -}; +} -type CustomSelectProps = {}> = { +interface CustomSelectProps { activeItemId?: K; actions?: A; className?: string; @@ -25,11 +23,11 @@ type CustomSelectProps void; - OptionIcon?: ComponentType>; - OptionContent: ComponentType>; -}; + OptionIcon?: ComponentType>; + OptionContent: ComponentType>; +} -const CustomSelect = = {}>( +const CustomSelect = ( props: CustomSelectProps ) => { const { @@ -90,7 +88,7 @@ const CustomSelect = > = Pick< +type CustomSelectItemProps = Pick< CustomSelectProps, 'onSelect' | 'OptionIcon' | 'OptionContent' | 'padding' | 'autoFocus' | 'light' | 'hoverable' | 'actions' > & { @@ -101,9 +99,7 @@ type CustomSelectItemProps> = item: T; }; -const CustomSelectItem = >( - props: CustomSelectItemProps -) => { +const CustomSelectItem = (props: CustomSelectItemProps) => { const { active, actions, diff --git a/src/app/templates/DAppConnection/index.tsx b/src/app/templates/DAppConnection/index.tsx new file mode 100644 index 0000000000..7478903b18 --- /dev/null +++ b/src/app/templates/DAppConnection/index.tsx @@ -0,0 +1,70 @@ +import React, { memo } from 'react'; + +import { IconBase } from 'app/atoms'; +import DAppLogo from 'app/atoms/DAppLogo'; +import { TezosNetworkLogo } from 'app/atoms/NetworkLogo'; +import { StyledButton } from 'app/atoms/StyledButton'; +import { ReactComponent as ChevronRightSvg } from 'app/icons/base/chevron_right.svg'; +import { t } from 'lib/i18n'; +import { useTypedSWR } from 'lib/swr'; +import { TempleTezosChainId } from 'lib/temple/types'; +import { Link } from 'lib/woozie'; +import { useAllTezosChains } from 'temple/front'; +import { loadTezosChainId } from 'temple/tezos'; + +import { useDAppsConnections } from './use-connections'; + +export const DAppConnection = memo(() => { + const { activeDApp, disconnectOne } = useDAppsConnections(); + + const tezosChains = useAllTezosChains(); + + const { data: chainId } = useTypedSWR(['dapp-connection', 'tezos-chain-id'], () => { + if (dapp.network === 'mainnet') return TempleTezosChainId.Mainnet; + if (dapp.network === 'ghostnet') return TempleTezosChainId.Ghostnet; + + if (dapp.network === 'sandbox') return loadTezosChainId('http://localhost:8732'); + + if (typeof dapp.network === 'string') return null; + + return loadTezosChainId(dapp.network.rpc); + }); + + if (!activeDApp) return null; + + const [origin, dapp] = activeDApp; + + const network = chainId ? tezosChains[chainId] : null; + + return ( +
+
+ + + {network && ( +
+ +
+ )} +
+ +
+ {dapp.appMeta.name} + + + Manage connections + + + +
+ + disconnectOne(origin)}> + Disconnect + +
+ ); +}); diff --git a/src/app/templates/DAppConnection/use-active-tab.ts b/src/app/templates/DAppConnection/use-active-tab.ts new file mode 100644 index 0000000000..09a2b29a58 --- /dev/null +++ b/src/app/templates/DAppConnection/use-active-tab.ts @@ -0,0 +1,56 @@ +import { useEffect, useMemo } from 'react'; + +import type { Tabs } from 'webextension-polyfill'; + +import { browser } from 'lib/browser'; +import { useTypedSWR } from 'lib/swr'; +import { useUpdatableRef } from 'lib/ui/hooks'; + +function useActiveTab() { + const { data: activeTab, mutate } = useTypedSWR( + ['browser', 'active-tab'], + () => + browser.tabs + .query({ + active: true, + lastFocusedWindow: true + }) + .then(tabs => tabs.at(0)), + { + suspense: true + } + ); + + const activeTabRef = useUpdatableRef(activeTab); + + useEffect(() => { + const onUpdated = (tabId: number, _info: Tabs.OnUpdatedChangeInfoType) => { + if (tabId === activeTabRef.current?.id) mutate(); + }; + + const onActivated = (_info: Tabs.OnActivatedActiveInfoType) => { + mutate(); + }; + + browser.tabs.onUpdated.addListener(onUpdated); + + browser.tabs.onActivated.addListener(onActivated); + + return () => { + browser.tabs.onUpdated.removeListener(onUpdated); + browser.tabs.onActivated.removeListener(onActivated); + }; + }, [mutate, activeTabRef]); + + return activeTab; +} + +export function useActiveTabUrlOrigin() { + const tab = useActiveTab(); + + return useMemo(() => { + const url = tab?.url ? new URL(tab.url) : null; + + return url?.origin; + }, [tab]); +} diff --git a/src/app/templates/DAppConnection/use-connections.ts b/src/app/templates/DAppConnection/use-connections.ts new file mode 100644 index 0000000000..4685b3b60c --- /dev/null +++ b/src/app/templates/DAppConnection/use-connections.ts @@ -0,0 +1,39 @@ +import { useCallback, useMemo } from 'react'; + +import { useStoredTezosDappsSessions } from 'app/storage/dapps/use-value.hook'; +import { useTempleClient } from 'lib/temple/front'; +import { throttleAsyncCalls } from 'lib/utils/functions'; +import { useAccountAddressForTezos } from 'temple/front'; + +import { useActiveTabUrlOrigin } from './use-active-tab'; + +export function useDAppsConnections() { + const { removeDAppSession } = useTempleClient(); + + const tezAddress = useAccountAddressForTezos(); + const [dappsSessions] = useStoredTezosDappsSessions(); + + const dapps = useMemo(() => { + if (!dappsSessions) return []; + + const entries = Object.entries(dappsSessions); + + return tezAddress ? entries.filter(([, ds]) => ds.pkh === tezAddress) : entries; + }, [dappsSessions, tezAddress]); + + const activeTabOrigin = useActiveTabUrlOrigin(); + + const activeDApp = useMemo( + () => (activeTabOrigin ? dapps.find(([origin]) => origin === activeTabOrigin) : null), + [dapps, activeTabOrigin] + ); + + const disconnectDApps = useMemo( + () => throttleAsyncCalls((origins: string[]) => removeDAppSession(origins)), + [removeDAppSession] + ); + + const disconnectOne = useCallback((origin: string) => disconnectDApps([origin]), [disconnectDApps]); + + return { dapps, activeDApp, disconnectDApps, disconnectOne }; +} diff --git a/src/app/templates/DAppLogo.tsx b/src/app/templates/DAppLogo.tsx deleted file mode 100644 index 2d263055f4..0000000000 --- a/src/app/templates/DAppLogo.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import React, { CSSProperties, memo, useCallback, useMemo, useState } from 'react'; - -import classNames from 'clsx'; - -import { Identicon } from 'app/atoms'; - -type DAppLogoProps = { - origin: string; - size: number; - className?: string; - icon?: string; - style?: CSSProperties; -}; - -const DAppLogo = memo(({ origin, size, icon, className, style }) => { - const faviconSrc = useMemo(() => (icon ? icon : `${origin}/favicon.ico`), [origin, icon]); - const [faviconShowed, setFaviconShowed] = useState(true); - const handleFaviconError = useCallback(() => { - setFaviconShowed(false); - }, [setFaviconShowed]); - - return faviconShowed ? ( -
- {origin} -
- ) : ( - - ); -}); - -export default DAppLogo; diff --git a/src/app/templates/DAppSettings/DAppSettings.selectors.ts b/src/app/templates/DAppSettings/DAppSettings.selectors.ts deleted file mode 100644 index 2a44a43198..0000000000 --- a/src/app/templates/DAppSettings/DAppSettings.selectors.ts +++ /dev/null @@ -1,3 +0,0 @@ -export enum DAppSettingsSelectors { - DAppInteractionCheckBox = 'DApp Settings/ DApp Interaction Check Box' -} diff --git a/src/app/templates/DAppSettings/DAppSettings.tsx b/src/app/templates/DAppSettings/DAppSettings.tsx deleted file mode 100644 index c76ce8c335..0000000000 --- a/src/app/templates/DAppSettings/DAppSettings.tsx +++ /dev/null @@ -1,216 +0,0 @@ -import React, { ComponentProps, FC, useCallback, useMemo, useRef, useState } from 'react'; - -import classNames from 'clsx'; - -import { Name, FormCheckbox, HashChip } from 'app/atoms'; -import { ReactComponent as CloseIcon } from 'app/icons/close.svg'; -import CustomSelect, { OptionRenderProps } from 'app/templates/CustomSelect'; -import DAppLogo from 'app/templates/DAppLogo'; -import { TID, T, t } from 'lib/i18n'; -import { useRetryableSWR } from 'lib/swr'; -import { useTempleClient, useStorage } from 'lib/temple/front'; -import { TempleSharedStorageKey, TempleDAppSession, TempleDAppSessions } from 'lib/temple/types'; -import { useConfirm } from 'lib/ui/dialog'; - -import { DAppSettingsSelectors } from './DAppSettings.selectors'; - -type DAppEntry = [string, TempleDAppSession]; -type DAppActions = { - remove: (origin: string) => void; -}; - -const getDAppKey = (entry: DAppEntry) => entry[0]; - -const DAppSettings: FC = () => { - const { getAllDAppSessions, removeDAppSession } = useTempleClient(); - const confirm = useConfirm(); - - const { data, mutate } = useRetryableSWR(['getAllDAppSessions'], getAllDAppSessions, { - suspense: true, - shouldRetryOnError: false, - revalidateOnFocus: false, - revalidateOnReconnect: false - }); - const dAppSessions = data!; - - const [dAppEnabled, setDAppEnabled] = useStorage(TempleSharedStorageKey.DAppEnabled, true); - - const changingRef = useRef(false); - const [error, setError] = useState(null); - - const handleChange = useCallback( - async (checked: boolean) => { - if (changingRef.current) return; - changingRef.current = true; - setError(null); - - setDAppEnabled(checked).catch((err: any) => setError(err)); - - changingRef.current = false; - }, - [setError, setDAppEnabled] - ); - - const handleRemoveClick = useCallback( - async (origin: string) => { - if ( - await confirm({ - title: t('actionConfirmation'), - children: t('resetPermissionsConfirmation', origin) - }) - ) { - await removeDAppSession(origin); - mutate(); - } - }, - [removeDAppSession, mutate, confirm] - ); - - const dAppEntries = useMemo(() => Object.entries(dAppSessions), [dAppSessions]); - - return ( -
-

- - - -

- - - - {dAppEntries.length > 0 && ( - <> -

- - - -

- -
- - - -
- - - - )} -
- ); -}; - -export default DAppSettings; - -const DAppIcon: FC> = props => ( - -); - -const DAppDescription: FC> = props => { - const { - actions, - item: [origin, { appMeta, network, pkh }] - } = props; - const { remove: onRemove } = actions!; - - const handleRemoveClick = useCallback( - (e: React.MouseEvent) => { - e.stopPropagation(); - onRemove(origin); - }, - [onRemove, origin] - ); - - interface TDAppAttribute { - key: TID; - value: React.ReactNode; - valueClassName?: string; - Component: React.FC | keyof JSX.IntrinsicElements; - } - - const dAppAttributes = useMemo( - (): TDAppAttribute[] => [ - { - key: 'originLabel', - value: origin, - Component: ({ className, ...rest }: ComponentProps) => ( - - - - ) - }, - { - key: 'networkLabel', - value: typeof network === 'string' ? network : network.name || network.rpc, - valueClassName: (typeof network === 'string' || network.name) && 'capitalize', - Component: Name - }, - { - key: 'pkhLabel', - value: , - Component: 'span' - } - ], - [origin, network, pkh] - ); - - return ( -
-
- - {appMeta.name} - - - {dAppAttributes.map(({ key, value, valueClassName, Component }) => ( -
- - {value} - - ]} - /> -
- ))} -
- - -
- ); -}; diff --git a/src/app/templates/DAppsList.selectors.ts b/src/app/templates/DAppsList.selectors.ts deleted file mode 100644 index a40818f108..0000000000 --- a/src/app/templates/DAppsList.selectors.ts +++ /dev/null @@ -1,3 +0,0 @@ -export enum DAppStoreSelectors { - DAppOpened = 'DApp (Some DApp)/DApp Opened' -} diff --git a/src/app/templates/DAppsList.tsx b/src/app/templates/DAppsList.tsx deleted file mode 100644 index de2d439d39..0000000000 --- a/src/app/templates/DAppsList.tsx +++ /dev/null @@ -1,162 +0,0 @@ -import React, { FC, useCallback, useMemo, useState } from 'react'; - -import clsx from 'clsx'; - -import { Anchor } from 'app/atoms/Anchor'; -import { openInFullPage, useAppEnv } from 'app/env'; -import { DAppIcon } from 'app/templates/DAppsList/DAppIcon'; -import DAppItem from 'app/templates/DAppsList/DAppItem'; -import SearchField from 'app/templates/SearchField'; -import { DappEnum, getDApps } from 'lib/apis/temple'; -import { TID, t } from 'lib/i18n'; -import { useRetryableSWR } from 'lib/swr'; - -import { DAppStoreSelectors } from './DAppsList.selectors'; - -const USED_TAGS = Object.values(DappEnum).filter(x => typeof x !== 'number') as DappEnum[]; -const TOP_DAPPS_SLUGS = ['quipuswap', 'objkt.com', 'youves']; - -const DAppsList = () => { - const { popup } = useAppEnv(); - const { data } = useRetryableSWR('dapps-list', getDApps, { suspense: true }); - - const dApps = useMemo(() => { - return data!.dApps.map(({ categories: rawCategories, ...restProps }) => { - const categories = rawCategories.filter(name => name !== DappEnum.Other); - if (categories.length !== rawCategories.length) { - categories.push(DappEnum.Other); - } - return { - categories, - ...restProps - }; - }); - }, [data]); - - const [searchString, setSearchString] = useState(''); - const [selectedTags, setSelectedTags] = useState([]); - - const handleTagClick = useCallback((name: DappEnum) => { - setSelectedTags(prevSelectedTags => { - const tagIndex = prevSelectedTags.indexOf(name); - const newSelectedTags = [...prevSelectedTags]; - if (tagIndex === -1) { - newSelectedTags.push(name); - } else { - newSelectedTags.splice(tagIndex, 1); - } - return newSelectedTags; - }); - }, []); - - const featuredDApps = useMemo(() => { - const topDApps = dApps.filter(({ slug }) => TOP_DAPPS_SLUGS.some(topDAppSlug => topDAppSlug === slug)); - const otherDApps = dApps.filter(({ slug }) => !TOP_DAPPS_SLUGS.some(topDAppSlug => topDAppSlug === slug)); - return [...topDApps, ...otherDApps.slice(0, 3 - topDApps.length)]; - }, [dApps]); - - const matchingDApps = useMemo(() => { - return dApps.filter( - ({ name, categories }) => - name.toLowerCase().includes(searchString.toLowerCase()) && - selectedTags.every(selectedTag => categories.includes(selectedTag)) - ); - }, [dApps, searchString, selectedTags]); - - return ( -
3 && 'pb-12')}> - {t('promoted')} - -
- {featuredDApps.slice(0, 3).map(({ slug, name, logo, dappUrl }) => ( - - - - {name} - - - ))} -
- - - -
-
- {USED_TAGS.map(tag => ( - - ))} -
-
- - {matchingDApps.slice(0, popup ? 3 : matchingDApps.length).map(dAppProps => ( - - ))} - -
- -
-
- ); -}; - -export default DAppsList; - -type TagProps = { - name: DappEnum; - onClick: (name: DappEnum) => void; - selected: boolean; -}; - -const Tag: FC = ({ name, onClick, selected }) => { - const handleClick = useCallback(() => onClick(name), [onClick, name]); - - return ( - - ); -}; diff --git a/src/app/templates/DAppsList/DAppIcon.tsx b/src/app/templates/DAppsList/DAppIcon.tsx deleted file mode 100644 index 2b73520d04..0000000000 --- a/src/app/templates/DAppsList/DAppIcon.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import React, { useMemo } from 'react'; - -import classNames from 'clsx'; - -import { useAppEnv } from 'app/env'; -import { ImageStacked } from 'lib/ui/ImageStacked'; - -type DAppIconProps = { - name: string; - logo: string; - className?: string; -}; - -export const DAppIcon: React.FC = ({ name, logo, className }) => { - const { popup } = useAppEnv(); - - const sources = useMemo(() => (logo ? [logo] : []), []); - - const fallbackElement = useMemo(() => {name}, [name]); - - return ( -
- -
- ); -}; diff --git a/src/app/templates/DAppsList/DAppItem.tsx b/src/app/templates/DAppsList/DAppItem.tsx deleted file mode 100644 index 8ebe20d8b3..0000000000 --- a/src/app/templates/DAppsList/DAppItem.tsx +++ /dev/null @@ -1,49 +0,0 @@ -import React, { FC, SVGProps } from 'react'; - -import { Anchor } from 'app/atoms'; -import { ReactComponent as TagIcon } from 'app/icons/tag.svg'; -import { DAppIcon } from 'app/templates/DAppsList/DAppIcon'; -import { CustomDAppInfo } from 'lib/apis/temple'; - -import { DAppStoreSelectors } from '../DAppsList.selectors'; - -type DAppItemProps = CustomDAppInfo; - -const DAppItem: FC = ({ dappUrl, name, logo, categories }) => ( -
- - - - -
-
-

- {name} -

- - {categories.map(category => `#${category}`).join(', ')} -
-
-
-); - -export default DAppItem; - -type DAppCharacteristicProps = { - Icon?: React.FC>; - children: React.ReactChild | React.ReactChild[]; -}; - -const DAppCharacteristic: FC = ({ Icon, children }) => ( -
- {Icon && } - {children} -
-); diff --git a/src/app/templates/NetworkSelectModal.tsx b/src/app/templates/NetworkSelectModal.tsx index 34f1cb65d0..5b35e4dcf4 100644 --- a/src/app/templates/NetworkSelectModal.tsx +++ b/src/app/templates/NetworkSelectModal.tsx @@ -84,7 +84,7 @@ export const NetworkSelectModal = memo(({ opened, selectedNetwork, onRequ
- {filteredNetworks.length === 0 && } + {filteredNetworks.length === 0 && } {filteredNetworks.map(network => ( (({ setHeaderChildren }) = <> {chainsGroups.length === 0 ? (
- +
) : (
diff --git a/src/app/templates/SecuritySettings/index.tsx b/src/app/templates/SecuritySettings/index.tsx index c6d0dd4ab3..ad45d71e6f 100644 --- a/src/app/templates/SecuritySettings/index.tsx +++ b/src/app/templates/SecuritySettings/index.tsx @@ -4,7 +4,7 @@ import { AutoLockSelect } from './auto-lock-select'; import { UsageAnalyticsSettings } from './usage-analytics-settings'; export const SecuritySettings = memo(() => ( -
+
diff --git a/src/app/templates/select-with-modal/select-modal.tsx b/src/app/templates/select-with-modal/select-modal.tsx index 7a9059c38e..00d1f3d157 100644 --- a/src/app/templates/select-with-modal/select-modal.tsx +++ b/src/app/templates/select-with-modal/select-modal.tsx @@ -64,7 +64,7 @@ export const SelectModal = >({ onTopEdgeVisibilityChange={setTopEdgeIsVisible} topEdgeThreshold={4} > - {filteredOptions.length === 0 && } + {filteredOptions.length === 0 && } {filteredOptions.map((option, index) => ( diff --git a/src/background.ts b/src/background.ts index 088e85b755..5977244565 100644 --- a/src/background.ts +++ b/src/background.ts @@ -73,12 +73,6 @@ browser.runtime.onUpdateAvailable.addListener(newManifest => { start(); -if (process.env.TARGET_BROWSER === 'safari') { - browser.browserAction.onClicked.addListener(() => { - openFullPage(); - }); -} - function openFullPage() { browser.tabs.create({ url: browser.runtime.getURL('fullpage.html') diff --git a/src/content-scripts/utils.ts b/src/content-scripts/utils.ts index 244e107a0b..5937c4e503 100644 --- a/src/content-scripts/utils.ts +++ b/src/content-scripts/utils.ts @@ -19,21 +19,3 @@ export async function checkIfShouldReplaceReferrals() { return value ?? IS_MISES_BROWSER; } - -export function throttleAsyncCalls any>( - func: F -): (...args: Parameters) => Promise { - let settling = false; - - return async function (...args: Parameters) { - if (settling) return; - settling = true; - - try { - await func(...args); - return; - } finally { - settling = false; - } - }; -} diff --git a/src/lib/apis/temple/dapps/index.ts b/src/lib/apis/temple/dapps/index.ts deleted file mode 100644 index 5d3828072e..0000000000 --- a/src/lib/apis/temple/dapps/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export type { CustomDAppInfo } from './types'; -export { DappEnum } from './types'; -export { getDApps } from './operations'; diff --git a/src/lib/apis/temple/dapps/operations.ts b/src/lib/apis/temple/dapps/operations.ts deleted file mode 100644 index 17d0c76712..0000000000 --- a/src/lib/apis/temple/dapps/operations.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { templeWalletApi } from '../endpoints/templewallet.api'; - -import type { CustomDAppsInfo } from './types'; - -export const getDApps = () => templeWalletApi.get('/dapps').then(res => res.data); diff --git a/src/lib/apis/temple/dapps/types.ts b/src/lib/apis/temple/dapps/types.ts deleted file mode 100644 index 3968301ffa..0000000000 --- a/src/lib/apis/temple/dapps/types.ts +++ /dev/null @@ -1,21 +0,0 @@ -export enum DappEnum { - Exchanges = 'Exchanges', - Marketplaces = 'Marketplaces', - Games = 'Games', - DeFi = 'DeFi', - Collectibles = 'Collectibles', - Other = 'Other' -} - -export interface CustomDAppInfo { - name: string; - dappUrl: string; - type: DappEnum; - logo: string; - slug: string; - categories: DappEnum[]; -} - -export interface CustomDAppsInfo { - dApps: CustomDAppInfo[]; -} diff --git a/src/lib/apis/temple/index.ts b/src/lib/apis/temple/index.ts index dfa3e2d479..487512d403 100644 --- a/src/lib/apis/temple/index.ts +++ b/src/lib/apis/temple/index.ts @@ -5,6 +5,5 @@ export * from './endpoints/get-advertising-info'; export * from './endpoints/get-exchange-rates'; export * from './endpoints/get-moonpay-sign'; export * from './whitelist-tokens'; -export * from './dapps'; export { templeWalletApi } from './endpoints/templewallet.api'; diff --git a/src/lib/temple/back/actions.ts b/src/lib/temple/back/actions.ts index c66e044e00..e545f27f1f 100644 --- a/src/lib/temple/back/actions.ts +++ b/src/lib/temple/back/actions.ts @@ -14,14 +14,7 @@ import { BACKGROUND_IS_WORKER } from 'lib/env'; import { putToStorage } from 'lib/storage'; import { addLocalOperation } from 'lib/temple/activity'; import * as Beacon from 'lib/temple/beacon'; -import { - TempleState, - TempleMessageType, - TempleRequest, - TempleSettings, - TempleSharedStorageKey, - TempleAccountType -} from 'lib/temple/types'; +import { TempleState, TempleMessageType, TempleRequest, TempleSettings, TempleAccountType } from 'lib/temple/types'; import { createQueue, delay } from 'lib/utils'; import { loadTezosChainId } from 'temple/tezos'; import { TempleChainKind } from 'temple/types'; @@ -32,8 +25,7 @@ import { requestOperation, requestSign, requestBroadcast, - getAllDApps, - removeDApp + removeDApps } from './dapp'; import { intercom } from './defaults'; import type { DryRunResult } from './dryrun'; @@ -81,17 +73,8 @@ export async function getFrontState(): Promise { } } -export async function isDAppEnabled() { - const bools = await Promise.all([ - Vault.isExist(), - (async () => { - const key = TempleSharedStorageKey.DAppEnabled; - const items = await browser.storage.local.get([key]); - return key in items ? items[key] : true; - })() - ]); - - return bools.every(Boolean); +export function canInteractWithDApps() { + return Vault.isExist(); } export function registerNewWallet(password: string, mnemonic?: string) { @@ -256,12 +239,8 @@ export function createOrImportWallet(mnemonic?: string) { }); } -export function getAllDAppSessions() { - return getAllDApps(); -} - -export function removeDAppSession(origin: string) { - return removeDApp(origin); +export function removeDAppSession(origins: string[]) { + return removeDApps(origins); } export function sendOperations( @@ -516,7 +495,7 @@ export async function processBeacon( // Process Disconnect if (req.type === Beacon.MessageType.Disconnect) { - await removeDApp(origin); + await removeDApps([origin]); return; } diff --git a/src/lib/temple/back/dapp.ts b/src/lib/temple/back/dapp.ts index 751edc4f9e..f7cc3dff3c 100644 --- a/src/lib/temple/back/dapp.ts +++ b/src/lib/temple/back/dapp.ts @@ -15,12 +15,17 @@ import { TempleDAppSignRequest, TempleDAppSignResponse, TempleDAppBroadcastRequest, - TempleDAppBroadcastResponse, - TempleDAppNetwork + TempleDAppBroadcastResponse } from '@temple-wallet/dapp/dist/types'; import { nanoid } from 'nanoid'; import browser, { Runtime } from 'webextension-polyfill'; +import { + TezosDAppNetwork, + TezosDAppSession, + getStoredTezosDappsSessions, + putStoredTezosDappsSessions +} from 'app/storage/dapps'; import { CUSTOM_TEZOS_NETWORKS_STORAGE_KEY, TEZOS_CHAINS_SPECS_STORAGE_KEY } from 'lib/constants'; import { fetchFromStorage } from 'lib/storage'; import { addLocalOperation } from 'lib/temple/activity'; @@ -29,10 +34,9 @@ import { TempleMessageType, TempleRequest, TempleDAppPayload, - TempleDAppSession, - TempleDAppSessions, TempleNotification, - TEZOS_MAINNET_CHAIN_ID + TEZOS_MAINNET_CHAIN_ID, + TempleTezosChainId } from 'lib/temple/types'; import { isValidTezosAddress } from 'lib/tezos'; import { TezosChainSpecs } from 'temple/front/chains-specs'; @@ -46,7 +50,6 @@ import { withUnlocked } from './store'; const CONFIRM_WINDOW_WIDTH = 380; const CONFIRM_WINDOW_HEIGHT = 632; const AUTODECLINE_AFTER = 120_000; -const STORAGE_KEY = 'dapp_sessions'; const HEX_PATTERN = /^[0-9a-fA-F]+$/; const TEZ_MSG_SIGN_PATTERN = /^0501[a-f0-9]{8}54657a6f73205369676e6564204d6573736167653a20[a-f0-9]*$/; @@ -54,7 +57,7 @@ export async function getCurrentPermission(origin: string): Promise { - if (![isAllowedNetwork(req?.network), typeof req?.appMeta?.name === 'string'].every(Boolean)) { - throw new Error(TempleDAppErrorType.InvalidParams); - } + if (typeof req?.appMeta?.name !== 'string') throw new Error(TempleDAppErrorType.InvalidParams); + + const networkRpc = await getNetworkRPC(req.network).then(rpcUrl => { + if (!rpcUrl) throw new Error(TempleDAppErrorType.InvalidParams); + + return rpcUrl; + }); - const networkRpc = await getNetworkRPC(req.network); const dApp = await getDApp(origin); if (!req.force && dApp && isNetworkEquals(req.network, dApp.network) && req.appMeta.name === dApp.appMeta.name) { @@ -160,7 +166,7 @@ export async function requestOperation( return new Promise(async (resolve, reject) => { const id = nanoid(); - const networkRpc = await getNetworkRPC(dApp.network); + const networkRpc = await getAssertNetworkRPC(dApp.network); await requestConfirm({ id, @@ -186,7 +192,7 @@ const handleIntercomRequest = async ( confirmReq: TempleRequest, decline: () => void, id: string, - dApp: TempleDAppSession, + dApp: TezosDAppSession, networkRpc: string, req: TempleDAppOperationRequest, resolve: any, @@ -257,14 +263,9 @@ export async function requestSign(origin: string, req: TempleDAppSignRequest): P return new Promise((resolve, reject) => generatePromisifySign(resolve, reject, dApp, req)); } -const generatePromisifySign = async ( - resolve: any, - reject: any, - dApp: TempleDAppSession, - req: TempleDAppSignRequest -) => { +const generatePromisifySign = async (resolve: any, reject: any, dApp: TezosDAppSession, req: TempleDAppSignRequest) => { const id = nanoid(); - const networkRpc = await getNetworkRPC(dApp.network); + const networkRpc = await getAssertNetworkRPC(dApp.network); let preview: any; try { @@ -340,7 +341,7 @@ export async function requestBroadcast( } try { - const rpc = new RpcClient(await getNetworkRPC(dApp.network)); + const rpc = new RpcClient(await getAssertNetworkRPC(dApp.network)); const opHash = await rpc.injectOperation(req.signedOpBytes); return { type: TempleDAppMessageType.BroadcastResponse, @@ -356,31 +357,28 @@ export async function requestBroadcast( } } -export async function getAllDApps() { - const dAppsSessions: TempleDAppSessions = (await browser.storage.local.get([STORAGE_KEY]))[STORAGE_KEY] || {}; - return dAppsSessions; +async function getAllDApps() { + return (await getStoredTezosDappsSessions()) || {}; } -async function getDApp(origin: string): Promise { +async function getDApp(origin: string): Promise { return (await getAllDApps())[origin]; } -async function setDApp(origin: string, permissions: TempleDAppSession) { +async function setDApp(origin: string, permissions: TezosDAppSession) { const current = await getAllDApps(); const newDApps = { ...current, [origin]: permissions }; - await setDApps(newDApps); + await putStoredTezosDappsSessions(newDApps); return newDApps; } -export async function removeDApp(origin: string) { - const { [origin]: permissionsToRemove, ...restDApps } = await getAllDApps(); - await setDApps(restDApps); - await Beacon.removeDAppPublicKey(origin); - return restDApps; -} +export async function removeDApps(origins: string[]) { + const dappsRecord = await getAllDApps(); + for (const origin of origins) delete dappsRecord[origin]; + await putStoredTezosDappsSessions(dappsRecord); + await Beacon.removeDAppPublicKey(origins); -function setDApps(newDApps: TempleDAppSessions) { - return browser.storage.local.set({ [STORAGE_KEY]: newDApps }); + return dappsRecord; } type RequestConfirmParams = { @@ -470,22 +468,28 @@ async function requestConfirm({ id, payload, onDecline, handleIntercomRequest }: const stopTimeout = () => clearTimeout(t); } -async function getNetworkRPC(net: TempleDAppNetwork) { +async function getNetworkRPC(net: TezosDAppNetwork) { if (net === 'sandbox') { return 'http://localhost:8732'; } - if (net === 'mainnet') { - const rpcUrl = await getActiveTempleRpcUrlByChainId(TEZOS_MAINNET_CHAIN_ID); + if (net === 'mainnet') return await getActiveTempleRpcUrlByChainId(TEZOS_MAINNET_CHAIN_ID); - return rpcUrl!; - } + if (net === 'ghostnet') return await getActiveTempleRpcUrlByChainId(TempleTezosChainId.Ghostnet); - if (typeof net === 'string') throw new Error('Unsupported network'); + if (typeof net === 'string') return null; return removeLastSlash(net.rpc); } +async function getAssertNetworkRPC(net: TezosDAppNetwork) { + const rpcUrl = await getNetworkRPC(net); + + if (!rpcUrl) throw new Error('Unsupported network'); + + return rpcUrl; +} + async function getActiveTempleRpcUrlByChainId(chainId: string): Promise { const customTezosNetworks = await fetchFromStorage(CUSTOM_TEZOS_NETWORKS_STORAGE_KEY); const chainNetworks = ( @@ -500,11 +504,7 @@ async function getActiveTempleRpcUrlByChainId(chainId: string): Promise n.id === net) : Boolean(net?.rpc); -} - -function isNetworkEquals(fNet: TempleDAppNetwork, sNet: TempleDAppNetwork) { +function isNetworkEquals(fNet: TezosDAppNetwork, sNet: TezosDAppNetwork) { return typeof fNet !== 'string' && typeof sNet !== 'string' ? removeLastSlash(fNet.rpc) === removeLastSlash(sNet.rpc) : fNet === sNet; diff --git a/src/lib/temple/back/main.ts b/src/lib/temple/back/main.ts index e0e379baa1..a8c0767fdc 100644 --- a/src/lib/temple/back/main.ts +++ b/src/lib/temple/back/main.ts @@ -192,15 +192,8 @@ const processRequest = async (req: TempleRequest, port: Runtime.Port): Promise { describe('removeDAppPublicKey', () => { it('called with correct data', async () => { await removeDAppPublicKey(MOCK_ORIGINAL_KEY); - expect(mockBrowserStorageLocal.remove).toBeCalledWith([MOCK_MODIFIED_KEY]); + expect(mockBrowserStorageLocal.remove).toBeCalledWith(MOCK_MODIFIED_KEY); }); }); describe('getDAppPublicKey', () => { diff --git a/src/lib/temple/beacon.ts b/src/lib/temple/beacon.ts index 90b554c48e..ec9a4ed655 100644 --- a/src/lib/temple/beacon.ts +++ b/src/lib/temple/beacon.ts @@ -22,6 +22,7 @@ import memoizee from 'memoizee'; import browser from 'webextension-polyfill'; import { APP_TITLE } from 'lib/constants'; +import { fetchFromStorage, putToStorage, removeFromStorage } from 'lib/storage'; interface AppMetadata { senderId: string; @@ -324,38 +325,32 @@ export async function createCryptoBox( export const getOrCreateKeyPair = memoizee( async () => { - const items = await browser.storage.local.get([KEYPAIR_SEED_STORAGE_KEY]); - const exist = KEYPAIR_SEED_STORAGE_KEY in items; + let seed = await fetchFromStorage(KEYPAIR_SEED_STORAGE_KEY); - let seed: string; - if (exist) { - seed = items[KEYPAIR_SEED_STORAGE_KEY]; - } else { + if (seed === null) { const newSeed = generateNewSeed(); - await browser.storage.local.set({ [KEYPAIR_SEED_STORAGE_KEY]: newSeed }); + await putToStorage(KEYPAIR_SEED_STORAGE_KEY, newSeed); seed = newSeed; } await ready; + return crypto_sign_seed_keypair(crypto_generichash(32, from_string(seed))); }, { maxAge: 60_000, promise: true } ); export async function getDAppPublicKey(origin: string) { - const key = toPubKeyStorageKey(origin); - const items = await browser.storage.local.get([key]); - return key in items ? (items[key] as string) : null; + return await fetchFromStorage(toPubKeyStorageKey(origin)); } export async function saveDAppPublicKey(origin: string, publicKey: string) { - await browser.storage.local.set({ - [toPubKeyStorageKey(origin)]: publicKey - }); + await putToStorage(toPubKeyStorageKey(origin), publicKey); } -export async function removeDAppPublicKey(origin: string) { - await browser.storage.local.remove([toPubKeyStorageKey(origin)]); +export async function removeDAppPublicKey(origin: string | string[]) { + const keys = Array.isArray(origin) ? origin.map(o => toPubKeyStorageKey(o)) : toPubKeyStorageKey(origin); + await removeFromStorage(keys); } export function generateNewSeed() { diff --git a/src/lib/temple/front/client.ts b/src/lib/temple/front/client.ts index 312d721bb9..819a541dfc 100644 --- a/src/lib/temple/front/client.ts +++ b/src/lib/temple/front/client.ts @@ -364,18 +364,10 @@ export const [TempleClientProvider, useTempleClient] = constate(() => { assertResponse(res.type === TempleMessageType.DAppSignConfirmationResponse); }, []); - const getAllDAppSessions = useCallback(async () => { - const res = await request({ - type: TempleMessageType.DAppGetAllSessionsRequest - }); - assertResponse(res.type === TempleMessageType.DAppGetAllSessionsResponse); - return res.sessions; - }, []); - - const removeDAppSession = useCallback(async (origin: string) => { + const removeDAppSession = useCallback(async (origins: string[]) => { const res = await request({ type: TempleMessageType.DAppRemoveSessionRequest, - origin + origins }); assertResponse(res.type === TempleMessageType.DAppRemoveSessionResponse); return res.sessions; @@ -436,7 +428,6 @@ export const [TempleClientProvider, useTempleClient] = constate(() => { confirmDAppPermission, confirmDAppOperation, confirmDAppSign, - getAllDAppSessions, removeDAppSession, resetExtension }; diff --git a/src/lib/temple/types.ts b/src/lib/temple/types.ts index 6e59b88978..3f233ea8d3 100644 --- a/src/lib/temple/types.ts +++ b/src/lib/temple/types.ts @@ -1,7 +1,8 @@ import type { DerivationType } from '@taquito/ledger-signer'; import type { Estimate } from '@taquito/taquito'; -import type { TempleDAppMetadata, TempleDAppNetwork } from '@temple-wallet/dapp/dist/types'; +import type { TempleDAppMetadata } from '@temple-wallet/dapp/dist/types'; +import { TezosDAppsSessionsRecord } from 'app/storage/dapps'; import type { StoredEvmNetwork, StoredTezosNetwork } from 'temple/networks'; import type { TempleChainKind } from 'temple/types'; @@ -14,13 +15,6 @@ import type { export { DerivationType }; -export interface TempleDAppSession { - network: TempleDAppNetwork; - appMeta: TempleDAppMetadata; - pkh: string; - publicKey: string; -} - export interface WalletSpecs { name: string; createdAt: number; @@ -125,15 +119,14 @@ export interface TempleSettings { } export enum TempleSharedStorageKey { - DAppEnabled = 'dappenabled', + /** @deprecated */ + DAppEnabled = 'dappenabled', // rm /** @deprecated */ LockUpEnabled = 'lock_up', PasswordAttempts = 'passwordAttempts', TimeLock = 'timelock' } -export type TempleDAppSessions = Record; - export interface TempleContact { address: string; name: string; @@ -276,8 +269,6 @@ export enum TempleMessageType { DAppOpsConfirmationResponse = 'TEMPLE_DAPP_OPS_CONFIRMATION_RESPONSE', DAppSignConfirmationRequest = 'TEMPLE_DAPP_SIGN_CONFIRMATION_REQUEST', DAppSignConfirmationResponse = 'TEMPLE_DAPP_SIGN_CONFIRMATION_RESPONSE', - DAppGetAllSessionsRequest = 'TEMPLE_DAPP_GET_ALL_SESSIONS_REQUEST', - DAppGetAllSessionsResponse = 'TEMPLE_DAPP_GET_ALL_SESSIONS_RESPONSE', DAppRemoveSessionRequest = 'TEMPLE_DAPP_REMOVE_SESSION_REQUEST', DAppRemoveSessionResponse = 'TEMPLE_DAPP_REMOVE_SESSION_RESPONSE', SendTrackEventRequest = 'SEND_TRACK_EVENT_REQUEST', @@ -325,7 +316,6 @@ export type TempleRequest = | TempleDAppOpsConfirmationRequest | TempleDAppSignConfirmationRequest | TempleUpdateSettingsRequest - | TempleGetAllDAppSessionsRequest | TempleRemoveDAppSessionRequest | TempleSendTrackEventRequest | TempleSendPageEventRequest @@ -362,7 +352,6 @@ export type TempleResponse = | TempleDAppOpsConfirmationResponse | TempleDAppSignConfirmationResponse | TempleUpdateSettingsResponse - | TempleGetAllDAppSessionsResponse | TempleRemoveDAppSessionResponse | TempleSendTrackEventResponse | TempleSendPageEventResponse @@ -717,23 +706,14 @@ interface TempleDAppSignConfirmationResponse extends TempleMessageBase { type: TempleMessageType.DAppSignConfirmationResponse; } -interface TempleGetAllDAppSessionsRequest extends TempleMessageBase { - type: TempleMessageType.DAppGetAllSessionsRequest; -} - -interface TempleGetAllDAppSessionsResponse extends TempleMessageBase { - type: TempleMessageType.DAppGetAllSessionsResponse; - sessions: TempleDAppSessions; -} - interface TempleRemoveDAppSessionRequest extends TempleMessageBase { type: TempleMessageType.DAppRemoveSessionRequest; - origin: string; + origins: string[]; } interface TempleRemoveDAppSessionResponse extends TempleMessageBase { type: TempleMessageType.DAppRemoveSessionResponse; - sessions: TempleDAppSessions; + sessions: TezosDAppsSessionsRecord; } interface TempleResetExtensionRequest extends TempleMessageBase { diff --git a/src/lib/ui/use-styled-button-or-link-props.tsx b/src/lib/ui/use-styled-button-or-link-props.tsx index d1bc1100e0..31eaacf3da 100644 --- a/src/lib/ui/use-styled-button-or-link-props.tsx +++ b/src/lib/ui/use-styled-button-or-link-props.tsx @@ -2,8 +2,8 @@ import React, { useMemo } from 'react'; import clsx from 'clsx'; +import { Loader } from 'app/atoms'; import { ButtonProps } from 'app/atoms/Button'; -import { Loader } from 'app/atoms/loader'; import { LinkProps } from 'lib/woozie/Link'; type Size = 'L' | 'M' | 'S'; diff --git a/src/lib/utils/functions.ts b/src/lib/utils/functions.ts new file mode 100644 index 0000000000..3f52fa893c --- /dev/null +++ b/src/lib/utils/functions.ts @@ -0,0 +1,17 @@ +export function throttleAsyncCalls any>( + func: F +): (...args: Parameters) => Promise { + let settling = false; + + return async function (...args: Parameters) { + if (settling) return; + settling = true; + + try { + await func(...args); + return; + } finally { + settling = false; + } + }; +} diff --git a/src/replaceAds.ts b/src/replaceAds.ts index 15aa5543b9..824750dcfd 100644 --- a/src/replaceAds.ts +++ b/src/replaceAds.ts @@ -1,10 +1,11 @@ import browser from 'webextension-polyfill'; -import { checkIfShouldReplaceAds, throttleAsyncCalls } from 'content-scripts/utils'; +import { checkIfShouldReplaceAds } from 'content-scripts/utils'; import { configureAds } from 'lib/ads/configure-ads'; import { importExtensionAdsModule } from 'lib/ads/import-extension-ads-module'; import { ContentScriptType, ADS_RULES_UPDATE_INTERVAL } from 'lib/constants'; import { IS_MISES_BROWSER } from 'lib/env'; +import { throttleAsyncCalls } from 'lib/utils/functions'; import { getRulesFromContentScript, clearRulesCache } from './content-scripts/replace-ads'; diff --git a/src/replaceReferrals.ts b/src/replaceReferrals.ts index 88b8a4b604..216afe2cb8 100644 --- a/src/replaceReferrals.ts +++ b/src/replaceReferrals.ts @@ -1,7 +1,8 @@ -import { checkIfShouldReplaceReferrals, throttleAsyncCalls } from 'content-scripts/utils'; +import { checkIfShouldReplaceReferrals } from 'content-scripts/utils'; import { importExtensionAdsReferralsModule } from 'lib/ads/import-extension-ads-module'; import { browser } from 'lib/browser'; import { ContentScriptType } from 'lib/constants'; +import { throttleAsyncCalls } from 'lib/utils/functions'; let interval: NodeJS.Timer; diff --git a/webpack/env.ts b/webpack/env.ts index b647065faf..78d53a0529 100644 --- a/webpack/env.ts +++ b/webpack/env.ts @@ -31,16 +31,15 @@ export const RELOADER_PORTS = { PAGES: 9092 }; -export const ALL_VENDORS = ['chrome', 'brave', 'firefox', 'opera', 'safari'] as const; +export const ALL_VENDORS = ['chrome', 'brave', 'firefox', 'opera'] as const; -export type Vendor = typeof ALL_VENDORS[number]; +export type Vendor = (typeof ALL_VENDORS)[number]; const MANIFEST_VERSION_BY_VENDORS: Record = { chrome: 3, brave: 3, firefox: 2, - opera: 3, - safari: 2 + opera: 3 }; export const getManifestVersion = (vendor: string) => MANIFEST_VERSION_BY_VENDORS[vendor as Vendor] || 2; diff --git a/xcode/Temple Extension/Info.plist b/xcode/Temple Extension/Info.plist deleted file mode 100644 index 1c4134ee14..0000000000 --- a/xcode/Temple Extension/Info.plist +++ /dev/null @@ -1,33 +0,0 @@ - - - - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleDisplayName - Temple Extension - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - $(PRODUCT_BUNDLE_PACKAGE_TYPE) - CFBundleShortVersionString - $(MARKETING_VERSION) - CFBundleVersion - $(CURRENT_PROJECT_VERSION) - LSMinimumSystemVersion - $(MACOSX_DEPLOYMENT_TARGET) - NSExtension - - NSExtensionPointIdentifier - com.apple.Safari.web-extension - NSExtensionPrincipalClass - $(PRODUCT_MODULE_NAME).SafariWebExtensionHandler - - - diff --git a/xcode/Temple Extension/SafariWebExtensionHandler.swift b/xcode/Temple Extension/SafariWebExtensionHandler.swift deleted file mode 100644 index 6a1b4c5f53..0000000000 --- a/xcode/Temple Extension/SafariWebExtensionHandler.swift +++ /dev/null @@ -1,25 +0,0 @@ -// -// SafariWebExtensionHandler.swift -// Temple Extension -// -// Created by Andrii Ivaniv on 29.03.2021. -// - -import SafariServices -import os.log - -let SFExtensionMessageKey = "message" - -class SafariWebExtensionHandler: NSObject, NSExtensionRequestHandling { - - func beginRequest(with context: NSExtensionContext) { - let item = context.inputItems[0] as! NSExtensionItem - let message = item.userInfo?[SFExtensionMessageKey] - - let response = NSExtensionItem() - response.userInfo = [ SFExtensionMessageKey: [ "Response to": message ] ] - - context.completeRequest(returningItems: [response], completionHandler: nil) - } - -} diff --git a/xcode/Temple Extension/Temple_Extension.entitlements b/xcode/Temple Extension/Temple_Extension.entitlements deleted file mode 100644 index f2ef3ae026..0000000000 --- a/xcode/Temple Extension/Temple_Extension.entitlements +++ /dev/null @@ -1,10 +0,0 @@ - - - - - com.apple.security.app-sandbox - - com.apple.security.files.user-selected.read-only - - - diff --git a/xcode/Temple.xcodeproj/project.pbxproj b/xcode/Temple.xcodeproj/project.pbxproj deleted file mode 100644 index 7621ffda05..0000000000 --- a/xcode/Temple.xcodeproj/project.pbxproj +++ /dev/null @@ -1,552 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 50; - objects = { - -/* Begin PBXBuildFile section */ - 142578322612114300061546 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 142578312612114300061546 /* AppDelegate.swift */; }; - 142578352612114300061546 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 142578332612114300061546 /* Main.storyboard */; }; - 142578372612114300061546 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 142578362612114300061546 /* ViewController.swift */; }; - 142578392612114400061546 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 142578382612114400061546 /* Assets.xcassets */; }; - 142578402612114400061546 /* Temple Extension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 1425783F2612114400061546 /* Temple Extension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; - 142578452612114400061546 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 142578442612114400061546 /* Cocoa.framework */; }; - 142578482612114400061546 /* SafariWebExtensionHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 142578472612114400061546 /* SafariWebExtensionHandler.swift */; }; - 1425785F2612114500061546 /* misc in Resources */ = {isa = PBXBuildFile; fileRef = 142578552612114500061546 /* misc */; }; - 142578602612114500061546 /* confirm.html in Resources */ = {isa = PBXBuildFile; fileRef = 142578562612114500061546 /* confirm.html */; }; - 142578612612114500061546 /* popup.html in Resources */ = {isa = PBXBuildFile; fileRef = 142578572612114500061546 /* popup.html */; }; - 142578622612114500061546 /* styles in Resources */ = {isa = PBXBuildFile; fileRef = 142578582612114500061546 /* styles */; }; - 142578632612114500061546 /* scripts in Resources */ = {isa = PBXBuildFile; fileRef = 142578592612114500061546 /* scripts */; }; - 142578642612114500061546 /* manifest.json in Resources */ = {isa = PBXBuildFile; fileRef = 1425785A2612114500061546 /* manifest.json */; }; - 142578652612114500061546 /* fullpage.html in Resources */ = {isa = PBXBuildFile; fileRef = 1425785B2612114500061546 /* fullpage.html */; }; - 142578662612114500061546 /* options.html in Resources */ = {isa = PBXBuildFile; fileRef = 1425785C2612114500061546 /* options.html */; }; - 142578672612114500061546 /* _locales in Resources */ = {isa = PBXBuildFile; fileRef = 1425785D2612114500061546 /* _locales */; }; - 142578682612114500061546 /* media in Resources */ = {isa = PBXBuildFile; fileRef = 1425785E2612114500061546 /* media */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - 142578412612114400061546 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 142578252612114300061546 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 1425783E2612114400061546; - remoteInfo = "Temple Extension"; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 142578502612114400061546 /* Embed App Extensions */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 13; - files = ( - 142578402612114400061546 /* Temple Extension.appex in Embed App Extensions */, - ); - name = "Embed App Extensions"; - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 1425782D2612114300061546 /* Temple.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Temple.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 142578302612114300061546 /* Temple.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Temple.entitlements; sourceTree = ""; }; - 142578312612114300061546 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - 142578342612114300061546 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 142578362612114300061546 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; - 142578382612114400061546 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 1425783A2612114400061546 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 1425783F2612114400061546 /* Temple Extension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "Temple Extension.appex"; sourceTree = BUILT_PRODUCTS_DIR; }; - 142578442612114400061546 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; - 142578472612114400061546 /* SafariWebExtensionHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SafariWebExtensionHandler.swift; sourceTree = ""; }; - 142578492612114400061546 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 1425784A2612114400061546 /* Temple_Extension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Temple_Extension.entitlements; sourceTree = ""; }; - 142578552612114500061546 /* misc */ = {isa = PBXFileReference; lastKnownFileType = folder; name = misc; path = ../../dist/safari_unpacked/misc; sourceTree = ""; }; - 142578562612114500061546 /* confirm.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; name = confirm.html; path = ../../dist/safari_unpacked/confirm.html; sourceTree = ""; }; - 142578572612114500061546 /* popup.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; name = popup.html; path = ../../dist/safari_unpacked/popup.html; sourceTree = ""; }; - 142578582612114500061546 /* styles */ = {isa = PBXFileReference; lastKnownFileType = folder; name = styles; path = ../../dist/safari_unpacked/styles; sourceTree = ""; }; - 142578592612114500061546 /* scripts */ = {isa = PBXFileReference; lastKnownFileType = folder; name = scripts; path = ../../dist/safari_unpacked/scripts; sourceTree = ""; }; - 1425785A2612114500061546 /* manifest.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; name = manifest.json; path = ../../dist/safari_unpacked/manifest.json; sourceTree = ""; }; - 1425785B2612114500061546 /* fullpage.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; name = fullpage.html; path = ../../dist/safari_unpacked/fullpage.html; sourceTree = ""; }; - 1425785C2612114500061546 /* options.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; name = options.html; path = ../../dist/safari_unpacked/options.html; sourceTree = ""; }; - 1425785D2612114500061546 /* _locales */ = {isa = PBXFileReference; lastKnownFileType = folder; name = _locales; path = ../../dist/safari_unpacked/_locales; sourceTree = ""; }; - 1425785E2612114500061546 /* media */ = {isa = PBXFileReference; lastKnownFileType = folder; name = media; path = ../../dist/safari_unpacked/media; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 1425782A2612114300061546 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 1425783C2612114400061546 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 142578452612114400061546 /* Cocoa.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 142578242612114300061546 = { - isa = PBXGroup; - children = ( - 1425782F2612114300061546 /* Temple */, - 142578462612114400061546 /* Temple Extension */, - 142578432612114400061546 /* Frameworks */, - 1425782E2612114300061546 /* Products */, - ); - sourceTree = ""; - }; - 1425782E2612114300061546 /* Products */ = { - isa = PBXGroup; - children = ( - 1425782D2612114300061546 /* Temple.app */, - 1425783F2612114400061546 /* Temple Extension.appex */, - ); - name = Products; - sourceTree = ""; - }; - 1425782F2612114300061546 /* Temple */ = { - isa = PBXGroup; - children = ( - 142578302612114300061546 /* Temple.entitlements */, - 142578312612114300061546 /* AppDelegate.swift */, - 142578332612114300061546 /* Main.storyboard */, - 142578362612114300061546 /* ViewController.swift */, - 142578382612114400061546 /* Assets.xcassets */, - 1425783A2612114400061546 /* Info.plist */, - ); - path = Temple; - sourceTree = ""; - }; - 142578432612114400061546 /* Frameworks */ = { - isa = PBXGroup; - children = ( - 142578442612114400061546 /* Cocoa.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; - 142578462612114400061546 /* Temple Extension */ = { - isa = PBXGroup; - children = ( - 142578542612114500061546 /* Resources */, - 142578472612114400061546 /* SafariWebExtensionHandler.swift */, - 142578492612114400061546 /* Info.plist */, - 1425784A2612114400061546 /* Temple_Extension.entitlements */, - ); - path = "Temple Extension"; - sourceTree = ""; - }; - 142578542612114500061546 /* Resources */ = { - isa = PBXGroup; - children = ( - 142578552612114500061546 /* misc */, - 142578562612114500061546 /* confirm.html */, - 142578572612114500061546 /* popup.html */, - 142578582612114500061546 /* styles */, - 142578592612114500061546 /* scripts */, - 1425785A2612114500061546 /* manifest.json */, - 1425785B2612114500061546 /* fullpage.html */, - 1425785C2612114500061546 /* options.html */, - 1425785D2612114500061546 /* _locales */, - 1425785E2612114500061546 /* media */, - ); - name = Resources; - path = "Temple Extension"; - sourceTree = SOURCE_ROOT; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 1425782C2612114300061546 /* Temple */ = { - isa = PBXNativeTarget; - buildConfigurationList = 142578512612114400061546 /* Build configuration list for PBXNativeTarget "Temple" */; - buildPhases = ( - 142578292612114300061546 /* Sources */, - 1425782A2612114300061546 /* Frameworks */, - 1425782B2612114300061546 /* Resources */, - 142578502612114400061546 /* Embed App Extensions */, - ); - buildRules = ( - ); - dependencies = ( - 142578422612114400061546 /* PBXTargetDependency */, - ); - name = Temple; - productName = Temple; - productReference = 1425782D2612114300061546 /* Temple.app */; - productType = "com.apple.product-type.application"; - }; - 1425783E2612114400061546 /* Temple Extension */ = { - isa = PBXNativeTarget; - buildConfigurationList = 1425784D2612114400061546 /* Build configuration list for PBXNativeTarget "Temple Extension" */; - buildPhases = ( - 1425783B2612114400061546 /* Sources */, - 1425783C2612114400061546 /* Frameworks */, - 1425783D2612114400061546 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = "Temple Extension"; - productName = "Temple Extension"; - productReference = 1425783F2612114400061546 /* Temple Extension.appex */; - productType = "com.apple.product-type.app-extension"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 142578252612114300061546 /* Project object */ = { - isa = PBXProject; - attributes = { - LastSwiftUpdateCheck = 1240; - LastUpgradeCheck = 1240; - TargetAttributes = { - 1425782C2612114300061546 = { - CreatedOnToolsVersion = 12.4; - }; - 1425783E2612114400061546 = { - CreatedOnToolsVersion = 12.4; - }; - }; - }; - buildConfigurationList = 142578282612114300061546 /* Build configuration list for PBXProject "Temple" */; - compatibilityVersion = "Xcode 9.3"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 142578242612114300061546; - productRefGroup = 1425782E2612114300061546 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 1425782C2612114300061546 /* Temple */, - 1425783E2612114400061546 /* Temple Extension */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 1425782B2612114300061546 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 142578392612114400061546 /* Assets.xcassets in Resources */, - 142578352612114300061546 /* Main.storyboard in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 1425783D2612114400061546 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 142578672612114500061546 /* _locales in Resources */, - 142578652612114500061546 /* fullpage.html in Resources */, - 1425785F2612114500061546 /* misc in Resources */, - 142578612612114500061546 /* popup.html in Resources */, - 142578662612114500061546 /* options.html in Resources */, - 142578622612114500061546 /* styles in Resources */, - 142578632612114500061546 /* scripts in Resources */, - 142578682612114500061546 /* media in Resources */, - 142578642612114500061546 /* manifest.json in Resources */, - 142578602612114500061546 /* confirm.html in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 142578292612114300061546 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 142578372612114300061546 /* ViewController.swift in Sources */, - 142578322612114300061546 /* AppDelegate.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 1425783B2612114400061546 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 142578482612114400061546 /* SafariWebExtensionHandler.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - 142578422612114400061546 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 1425783E2612114400061546 /* Temple Extension */; - targetProxy = 142578412612114400061546 /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin PBXVariantGroup section */ - 142578332612114300061546 /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 142578342612114300061546 /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 1425784B2612114400061546 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - APP_BUILD = 3; - APP_VERSION = 1.6.1; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 11.1; - MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; - MTL_FAST_MATH = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = macosx; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - }; - name = Debug; - }; - 1425784C2612114400061546 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - APP_BUILD = 3; - APP_VERSION = 1.6.1; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 11.1; - MTL_ENABLE_DEBUG_INFO = NO; - MTL_FAST_MATH = YES; - SDKROOT = macosx; - SWIFT_COMPILATION_MODE = wholemodule; - SWIFT_OPTIMIZATION_LEVEL = "-O"; - }; - name = Release; - }; - 1425784E2612114400061546 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CODE_SIGN_ENTITLEMENTS = "Temple Extension/Temple_Extension.entitlements"; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = "$(APP_BUILD)"; - INFOPLIST_FILE = "Temple Extension/Info.plist"; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/../Frameworks", - "@executable_path/../../../../Frameworks", - ); - MACOSX_DEPLOYMENT_TARGET = 10.14; - MARKETING_VERSION = "$(APP_VERSION)"; - PRODUCT_BUNDLE_IDENTIFIER = "com.madfish-solutions.Temple.Extension"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = YES; - SWIFT_VERSION = 5.0; - }; - name = Debug; - }; - 1425784F2612114400061546 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CODE_SIGN_ENTITLEMENTS = "Temple Extension/Temple_Extension.entitlements"; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = "$(APP_BUILD)"; - INFOPLIST_FILE = "Temple Extension/Info.plist"; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/../Frameworks", - "@executable_path/../../../../Frameworks", - ); - MACOSX_DEPLOYMENT_TARGET = 10.14; - MARKETING_VERSION = "$(APP_VERSION)"; - PRODUCT_BUNDLE_IDENTIFIER = "com.madfish-solutions.Temple.Extension"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = YES; - SWIFT_VERSION = 5.0; - }; - name = Release; - }; - 142578522612114400061546 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; - CODE_SIGN_ENTITLEMENTS = Temple/Temple.entitlements; - CODE_SIGN_STYLE = Automatic; - COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = "$(APP_BUILD)"; - DEVELOPMENT_TEAM = ""; - INFOPLIST_FILE = Temple/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/../Frameworks", - ); - MACOSX_DEPLOYMENT_TARGET = 10.14; - MARKETING_VERSION = "$(APP_VERSION)"; - PRODUCT_BUNDLE_IDENTIFIER = "com.madfish-solutions.Temple"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 5.0; - }; - name = Debug; - }; - 142578532612114400061546 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; - CODE_SIGN_ENTITLEMENTS = Temple/Temple.entitlements; - CODE_SIGN_STYLE = Automatic; - COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = "$(APP_BUILD)"; - DEVELOPMENT_TEAM = ""; - INFOPLIST_FILE = Temple/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/../Frameworks", - ); - MACOSX_DEPLOYMENT_TARGET = 10.14; - MARKETING_VERSION = "$(APP_VERSION)"; - PRODUCT_BUNDLE_IDENTIFIER = "com.madfish-solutions.Temple"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 5.0; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 142578282612114300061546 /* Build configuration list for PBXProject "Temple" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 1425784B2612114400061546 /* Debug */, - 1425784C2612114400061546 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 1425784D2612114400061546 /* Build configuration list for PBXNativeTarget "Temple Extension" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 1425784E2612114400061546 /* Debug */, - 1425784F2612114400061546 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 142578512612114400061546 /* Build configuration list for PBXNativeTarget "Temple" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 142578522612114400061546 /* Debug */, - 142578532612114400061546 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 142578252612114300061546 /* Project object */; -} diff --git a/xcode/Temple.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/xcode/Temple.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 919434a625..0000000000 --- a/xcode/Temple.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/xcode/Temple.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/xcode/Temple.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d981003d..0000000000 --- a/xcode/Temple.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/xcode/Temple/AppDelegate.swift b/xcode/Temple/AppDelegate.swift deleted file mode 100644 index d0ff0d29e4..0000000000 --- a/xcode/Temple/AppDelegate.swift +++ /dev/null @@ -1,25 +0,0 @@ -// -// AppDelegate.swift -// Temple -// -// Created by Andrii Ivaniv on 29.03.2021. -// - -import Cocoa - -@main -class AppDelegate: NSObject, NSApplicationDelegate { - - func applicationDidFinishLaunching(_ notification: Notification) { - // Insert code here to initialize your application - } - - func applicationWillTerminate(_ notification: Notification) { - // Insert code here to tear down your application - } - - func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { - return true - } - -} diff --git a/xcode/Temple/Assets.xcassets/AccentColor.colorset/Contents.json b/xcode/Temple/Assets.xcassets/AccentColor.colorset/Contents.json deleted file mode 100644 index eb87897008..0000000000 --- a/xcode/Temple/Assets.xcassets/AccentColor.colorset/Contents.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "colors" : [ - { - "idiom" : "universal" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/xcode/Temple/Assets.xcassets/AppIcon.appiconset/Contents.json b/xcode/Temple/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index b91a05065e..0000000000 --- a/xcode/Temple/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "images" : [ - { - "size" : "16x16", - "idiom" : "mac", - "filename" : "mac-16x16.png", - "scale" : "1x" - }, - { - "size" : "16x16", - "idiom" : "mac", - "filename" : "mac-16x16@2x.png", - "scale" : "2x" - }, - { - "size" : "32x32", - "idiom" : "mac", - "filename" : "mac-32x32.png", - "scale" : "1x" - }, - { - "size" : "32x32", - "idiom" : "mac", - "filename" : "mac-32x32@2x.png", - "scale" : "2x" - }, - { - "size" : "128x128", - "idiom" : "mac", - "filename" : "mac-128x128.png", - "scale" : "1x" - }, - { - "size" : "128x128", - "idiom" : "mac", - "filename" : "mac-128x128@2x.png", - "scale" : "2x" - }, - { - "size" : "256x256", - "idiom" : "mac", - "filename" : "mac-256x256.png", - "scale" : "1x" - }, - { - "size" : "256x256", - "idiom" : "mac", - "filename" : "mac-256x256@2x.png", - "scale" : "2x" - }, - { - "size" : "512x512", - "idiom" : "mac", - "filename" : "mac-512x512.png", - "scale" : "1x" - }, - { - "size" : "512x512", - "idiom" : "mac", - "filename" : "mac-512x512@2x.png", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/xcode/Temple/Assets.xcassets/AppIcon.appiconset/mac-128x128.png b/xcode/Temple/Assets.xcassets/AppIcon.appiconset/mac-128x128.png deleted file mode 100644 index 84b6dcd423..0000000000 Binary files a/xcode/Temple/Assets.xcassets/AppIcon.appiconset/mac-128x128.png and /dev/null differ diff --git a/xcode/Temple/Assets.xcassets/AppIcon.appiconset/mac-128x128@2x.png b/xcode/Temple/Assets.xcassets/AppIcon.appiconset/mac-128x128@2x.png deleted file mode 100644 index a9ad6b002d..0000000000 Binary files a/xcode/Temple/Assets.xcassets/AppIcon.appiconset/mac-128x128@2x.png and /dev/null differ diff --git a/xcode/Temple/Assets.xcassets/AppIcon.appiconset/mac-16x16.png b/xcode/Temple/Assets.xcassets/AppIcon.appiconset/mac-16x16.png deleted file mode 100644 index 6dbd38119f..0000000000 Binary files a/xcode/Temple/Assets.xcassets/AppIcon.appiconset/mac-16x16.png and /dev/null differ diff --git a/xcode/Temple/Assets.xcassets/AppIcon.appiconset/mac-16x16@2x.png b/xcode/Temple/Assets.xcassets/AppIcon.appiconset/mac-16x16@2x.png deleted file mode 100644 index cad0e9b7b7..0000000000 Binary files a/xcode/Temple/Assets.xcassets/AppIcon.appiconset/mac-16x16@2x.png and /dev/null differ diff --git a/xcode/Temple/Assets.xcassets/AppIcon.appiconset/mac-256x256.png b/xcode/Temple/Assets.xcassets/AppIcon.appiconset/mac-256x256.png deleted file mode 100644 index a9ad6b002d..0000000000 Binary files a/xcode/Temple/Assets.xcassets/AppIcon.appiconset/mac-256x256.png and /dev/null differ diff --git a/xcode/Temple/Assets.xcassets/AppIcon.appiconset/mac-256x256@2x.png b/xcode/Temple/Assets.xcassets/AppIcon.appiconset/mac-256x256@2x.png deleted file mode 100644 index 0ec610be49..0000000000 Binary files a/xcode/Temple/Assets.xcassets/AppIcon.appiconset/mac-256x256@2x.png and /dev/null differ diff --git a/xcode/Temple/Assets.xcassets/AppIcon.appiconset/mac-32x32.png b/xcode/Temple/Assets.xcassets/AppIcon.appiconset/mac-32x32.png deleted file mode 100644 index cad0e9b7b7..0000000000 Binary files a/xcode/Temple/Assets.xcassets/AppIcon.appiconset/mac-32x32.png and /dev/null differ diff --git a/xcode/Temple/Assets.xcassets/AppIcon.appiconset/mac-32x32@2x.png b/xcode/Temple/Assets.xcassets/AppIcon.appiconset/mac-32x32@2x.png deleted file mode 100644 index 799015e485..0000000000 Binary files a/xcode/Temple/Assets.xcassets/AppIcon.appiconset/mac-32x32@2x.png and /dev/null differ diff --git a/xcode/Temple/Assets.xcassets/AppIcon.appiconset/mac-512x512.png b/xcode/Temple/Assets.xcassets/AppIcon.appiconset/mac-512x512.png deleted file mode 100644 index 0ec610be49..0000000000 Binary files a/xcode/Temple/Assets.xcassets/AppIcon.appiconset/mac-512x512.png and /dev/null differ diff --git a/xcode/Temple/Assets.xcassets/AppIcon.appiconset/mac-512x512@2x.png b/xcode/Temple/Assets.xcassets/AppIcon.appiconset/mac-512x512@2x.png deleted file mode 100644 index c923ed98f2..0000000000 Binary files a/xcode/Temple/Assets.xcassets/AppIcon.appiconset/mac-512x512@2x.png and /dev/null differ diff --git a/xcode/Temple/Assets.xcassets/Contents.json b/xcode/Temple/Assets.xcassets/Contents.json deleted file mode 100644 index 73c00596a7..0000000000 --- a/xcode/Temple/Assets.xcassets/Contents.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/xcode/Temple/Base.lproj/Main.storyboard b/xcode/Temple/Base.lproj/Main.storyboard deleted file mode 100644 index f97402a791..0000000000 --- a/xcode/Temple/Base.lproj/Main.storyboard +++ /dev/null @@ -1,167 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/xcode/Temple/Info.plist b/xcode/Temple/Info.plist deleted file mode 100644 index 0d2a45b2bd..0000000000 --- a/xcode/Temple/Info.plist +++ /dev/null @@ -1,32 +0,0 @@ - - - - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIconFile - - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - $(PRODUCT_BUNDLE_PACKAGE_TYPE) - CFBundleShortVersionString - $(MARKETING_VERSION) - CFBundleVersion - $(CURRENT_PROJECT_VERSION) - LSApplicationCategoryType - public.app-category.productivity - LSMinimumSystemVersion - $(MACOSX_DEPLOYMENT_TARGET) - NSMainStoryboardFile - Main - NSPrincipalClass - NSApplication - - diff --git a/xcode/Temple/Temple.entitlements b/xcode/Temple/Temple.entitlements deleted file mode 100644 index f2ef3ae026..0000000000 --- a/xcode/Temple/Temple.entitlements +++ /dev/null @@ -1,10 +0,0 @@ - - - - - com.apple.security.app-sandbox - - com.apple.security.files.user-selected.read-only - - - diff --git a/xcode/Temple/ViewController.swift b/xcode/Temple/ViewController.swift deleted file mode 100644 index 8bdb5c4f58..0000000000 --- a/xcode/Temple/ViewController.swift +++ /dev/null @@ -1,51 +0,0 @@ -// -// ViewController.swift -// Temple -// -// Created by Andrii Ivaniv on 29.03.2021. -// - -import Cocoa -import SafariServices.SFSafariApplication -import SafariServices.SFSafariExtensionManager - -let appName = "Temple" -let extensionBundleIdentifier = "com.madfish-solutions.Temple.Extension" - -class ViewController: NSViewController { - - @IBOutlet var appNameLabel: NSTextField! - - override func viewDidLoad() { - super.viewDidLoad() - self.appNameLabel.stringValue = appName - SFSafariExtensionManager.getStateOfSafariExtension(withIdentifier: extensionBundleIdentifier) { (state, error) in - guard let state = state, error == nil else { - // Insert code to inform the user that something went wrong. - return - } - - DispatchQueue.main.async { - if (state.isEnabled) { - self.appNameLabel.stringValue = "\(appName)'s extension is currently on." - } else { - self.appNameLabel.stringValue = "\(appName)'s extension is currently off. You can turn it on in Safari Extensions preferences." - } - } - } - } - - @IBAction func openSafariExtensionPreferences(_ sender: AnyObject?) { - SFSafariApplication.showPreferencesForExtension(withIdentifier: extensionBundleIdentifier) { error in - guard error == nil else { - // Insert code to inform the user that something went wrong. - return - } - - DispatchQueue.main.async { - NSApplication.shared.terminate(nil) - } - } - } - -}