From 5b68433497272c23bf7d06a992c3209f3c97a2b5 Mon Sep 17 00:00:00 2001 From: Evgeny Kuzyakov Date: Thu, 16 Feb 2023 09:59:08 -0800 Subject: [PATCH] Move VM to root --- .babelrc | 2 +- .gitignore | 1 + README.md | 84 --- config/webpack.production.js | 17 +- package.json | 120 +-- public/.nojekyll | 0 public/CNAME | 1 - public/_redirects | 1 - public/favicon.png | Bin 24347 -> 0 bytes public/index.html | 33 - public/logo.png | Bin 46005 -> 0 bytes public/manifest.json | 15 - public/robots.txt | 3 - src/App.js | 143 ---- src/App.scss | 45 -- src/components/Editor/OpenModal.js | 62 -- src/components/Editor/RenameModal.js | 49 -- src/components/common/buttons/BlueButton.js | 13 - src/components/common/buttons/Button.js | 26 - .../common/buttons/GrayBorderButton.js | 13 - src/components/icons/ArrowUpRight.js | 29 - src/components/icons/Book.js | 28 - src/components/icons/Close.js | 28 - src/components/icons/Code.js | 28 - src/components/icons/Fork.js | 42 -- src/components/icons/Home.js | 28 - src/components/icons/LogOut.js | 35 - src/components/icons/NearSocialLogo.js | 28 - src/components/icons/Pretend.js | 24 - src/components/icons/StopPretending.js | 19 - src/components/icons/User.js | 28 - src/components/icons/UserCircle.js | 35 - src/components/icons/Withdraw.js | 19 - src/components/navigation/Logotype.js | 33 - src/components/navigation/NavigationButton.js | 51 -- .../navigation/NavigationWrapper.js | 21 - .../navigation/NotificationWidget.js | 43 -- src/components/navigation/PretendModal.js | 60 -- src/components/navigation/SignInButton.js | 10 - .../navigation/desktop/DesktopNavigation.js | 91 --- .../navigation/desktop/DevActionsDropdown.js | 133 ---- .../navigation/desktop/UserDropdown.js | 200 ----- src/components/navigation/mobile/Menu.js | 256 ------- .../navigation/mobile/MobileMenuButton.js | 41 -- .../navigation/mobile/MobileNavigation.js | 52 -- .../navigation/mobile/Navigation.js | 63 -- src/data/widgets.js | 35 - src/hooks/useQuery.js | 8 - src/hooks/useScrollBlock.js | 51 -- src/images/near_social_combo.svg | 5 - src/images/near_social_icon.svg | 4 - src/index.css | 13 - src/index.js | 22 +- .../src => }/lib/components/Commit.js | 0 .../lib/components/ConfirmTransactions.js | 0 .../src => }/lib/components/Markdown.js | 0 .../src => }/lib/components/SecureIframe.js | 0 .../src => }/lib/components/Widget.js | 0 .../lib/components/remark/mentions.js | 0 .../src => }/lib/data/account.js | 0 .../src => }/lib/data/cache.js | 0 .../src => }/lib/data/commitData.js | 0 src/{near-social-vm/src => }/lib/data/near.js | 0 .../src => }/lib/data/utils.js | 0 src/{near-social-vm/src => }/lib/vm/vm.js | 0 src/near-social-vm/.babelrc | 3 - src/near-social-vm/.gitignore | 33 - src/near-social-vm/config/paths.js | 13 - .../config/presets/loadPreset.js | 13 - .../config/presets/webpack.analyze.js | 6 - .../config/webpack.development.js | 48 -- .../config/webpack.production.js | 75 -- src/near-social-vm/package.json | 103 --- src/near-social-vm/src/index.js | 18 - src/near-social-vm/webpack.config.js | 83 --- src/pages/EditorPage.js | 693 ------------------ src/pages/EmbedPage.js | 35 - src/pages/ViewPage.js | 55 -- webpack.config.js | 70 +- 79 files changed, 120 insertions(+), 3319 deletions(-) delete mode 100644 README.md delete mode 100644 public/.nojekyll delete mode 100644 public/CNAME delete mode 100644 public/_redirects delete mode 100644 public/favicon.png delete mode 100644 public/index.html delete mode 100644 public/logo.png delete mode 100644 public/manifest.json delete mode 100644 public/robots.txt delete mode 100644 src/App.js delete mode 100644 src/App.scss delete mode 100644 src/components/Editor/OpenModal.js delete mode 100644 src/components/Editor/RenameModal.js delete mode 100644 src/components/common/buttons/BlueButton.js delete mode 100644 src/components/common/buttons/Button.js delete mode 100644 src/components/common/buttons/GrayBorderButton.js delete mode 100644 src/components/icons/ArrowUpRight.js delete mode 100644 src/components/icons/Book.js delete mode 100644 src/components/icons/Close.js delete mode 100644 src/components/icons/Code.js delete mode 100644 src/components/icons/Fork.js delete mode 100644 src/components/icons/Home.js delete mode 100644 src/components/icons/LogOut.js delete mode 100644 src/components/icons/NearSocialLogo.js delete mode 100644 src/components/icons/Pretend.js delete mode 100644 src/components/icons/StopPretending.js delete mode 100644 src/components/icons/User.js delete mode 100644 src/components/icons/UserCircle.js delete mode 100644 src/components/icons/Withdraw.js delete mode 100644 src/components/navigation/Logotype.js delete mode 100644 src/components/navigation/NavigationButton.js delete mode 100644 src/components/navigation/NavigationWrapper.js delete mode 100644 src/components/navigation/NotificationWidget.js delete mode 100644 src/components/navigation/PretendModal.js delete mode 100644 src/components/navigation/SignInButton.js delete mode 100644 src/components/navigation/desktop/DesktopNavigation.js delete mode 100644 src/components/navigation/desktop/DevActionsDropdown.js delete mode 100644 src/components/navigation/desktop/UserDropdown.js delete mode 100644 src/components/navigation/mobile/Menu.js delete mode 100644 src/components/navigation/mobile/MobileMenuButton.js delete mode 100644 src/components/navigation/mobile/MobileNavigation.js delete mode 100644 src/components/navigation/mobile/Navigation.js delete mode 100644 src/data/widgets.js delete mode 100644 src/hooks/useQuery.js delete mode 100644 src/hooks/useScrollBlock.js delete mode 100644 src/images/near_social_combo.svg delete mode 100644 src/images/near_social_icon.svg delete mode 100644 src/index.css rename src/{near-social-vm/src => }/lib/components/Commit.js (100%) rename src/{near-social-vm/src => }/lib/components/ConfirmTransactions.js (100%) rename src/{near-social-vm/src => }/lib/components/Markdown.js (100%) rename src/{near-social-vm/src => }/lib/components/SecureIframe.js (100%) rename src/{near-social-vm/src => }/lib/components/Widget.js (100%) rename src/{near-social-vm/src => }/lib/components/remark/mentions.js (100%) rename src/{near-social-vm/src => }/lib/data/account.js (100%) rename src/{near-social-vm/src => }/lib/data/cache.js (100%) rename src/{near-social-vm/src => }/lib/data/commitData.js (100%) rename src/{near-social-vm/src => }/lib/data/near.js (100%) rename src/{near-social-vm/src => }/lib/data/utils.js (100%) rename src/{near-social-vm/src => }/lib/vm/vm.js (100%) delete mode 100644 src/near-social-vm/.babelrc delete mode 100644 src/near-social-vm/.gitignore delete mode 100644 src/near-social-vm/config/paths.js delete mode 100644 src/near-social-vm/config/presets/loadPreset.js delete mode 100644 src/near-social-vm/config/presets/webpack.analyze.js delete mode 100644 src/near-social-vm/config/webpack.development.js delete mode 100644 src/near-social-vm/config/webpack.production.js delete mode 100644 src/near-social-vm/package.json delete mode 100644 src/near-social-vm/src/index.js delete mode 100644 src/near-social-vm/webpack.config.js delete mode 100644 src/pages/EditorPage.js delete mode 100644 src/pages/EmbedPage.js delete mode 100644 src/pages/ViewPage.js diff --git a/.babelrc b/.babelrc index 0dce8c0..2b7bafa 100644 --- a/.babelrc +++ b/.babelrc @@ -1,3 +1,3 @@ { - "presets": ["@babel/env", "@babel/preset-react"] + "presets": ["@babel/preset-env", "@babel/preset-react"] } diff --git a/.gitignore b/.gitignore index f7d618c..2d85219 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ # production /build +/dist # misc .DS_Store diff --git a/README.md b/README.md deleted file mode 100644 index 9582cc5..0000000 --- a/README.md +++ /dev/null @@ -1,84 +0,0 @@ -# Browser - -A framework for reusable components to render and modify SocialDB by Near Social. - -## Setup & Development - -Initialize repo: -``` -yarn -``` - -Start development version: -``` -yarn start -``` - -## Widget example - -Profile view - -```jsx -let accountId = props.accountId || "eugenethedream"; -let profile = socialGetr(`${accountId}/profile`); - -( -
- - {profile.name} (@{accountId}) -
-); -``` - - -Profile editor - -```jsx -let accountId = context.accountId; - -if (!accountId) { - return "Please sign in with NEAR wallet"; -} - -const profile = socialGetr(`${accountId}/profile`); - -if (profile === null) { - return "Loading"; -} - -initState({ - name: profile.name, - url: profile.image.url, -}); - -const data = { - profile: { - name: state.name, - image: { - url: state.url, - }, - }, -}; - -return ( -
-
account = {accountId}
-
- Name: - -
-
- Image URL: - -
-
Preview
-
- profile image {state.name} -
-
- Save profile -
-
-); - -``` diff --git a/config/webpack.production.js b/config/webpack.production.js index e8eb89a..8fe9edb 100644 --- a/config/webpack.production.js +++ b/config/webpack.production.js @@ -4,11 +4,12 @@ const path = require("path"); module.exports = () => { return { - output: { - path: path.resolve(__dirname, "../dist"), - publicPath: "./", - filename: "[name].[contenthash].bundle.js", - }, + // output: { + // path: path.resolve(__dirname, "../dist"), + // publicPath: "./", + // // filename: "[name].[contenthash].bundle.js", + // filename: "index.js", + // }, devtool: false, module: { rules: [ @@ -61,9 +62,9 @@ module.exports = () => { optimization: { minimize: true, minimizer: [new CssMinimizerPlugin(), "..."], - runtimeChunk: { - name: "runtime", - }, + // runtimeChunk: { + // name: "runtime", + // }, }, performance: { hints: false, diff --git a/package.json b/package.json index 01a173c..9c46f59 100644 --- a/package.json +++ b/package.json @@ -1,35 +1,86 @@ { - "name": "frontend", - "version": "0.5.0", - "homepage": "/", - "private": true, + "name": "near-social-vm", + "version": "0.1.0", + "description": "Near Social VM", + "main": "dist/index.js", + "files": [ + "dist" + ], "dependencies": { - "@monaco-editor/react": "^4.4.6", - "@near-wallet-selector/modal-ui": "^7.4.0", + "@braintree/sanitize-url": "6.0.0", + "@near-wallet-selector/core": "^7.4.0", + "@near-wallet-selector/here-wallet": "^7.4.0", + "@near-wallet-selector/meteor-wallet": "^7.4.0", + "@near-wallet-selector/my-near-wallet": "^7.4.0", + "@near-wallet-selector/near-wallet": "^7.4.0", + "@near-wallet-selector/neth": "^7.4.0", + "@near-wallet-selector/sender": "^7.4.0", + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", "big.js": "^6.1.1", "bn.js": "^5.1.1", "bootstrap": "^5.2.1", "bootstrap-icons": "^1.9.0", "collections": "^5.1.12", - "error-polyfill": "^0.1.2", + "deep-equal": "^2.2.0", + "elliptic": "^6.5.4", + "idb": "^7.1.1", "local-storage": "^2.0.0", + "mdast-util-find-and-replace": "^2.0.0", "near-api-js": "^0.45.1", - "near-social-vm": "file:src/near-social-vm", "prettier": "^2.7.1", - "react": "^18.2.0", "react-bootstrap": "^2.5.0", - "react-dom": "^18.2.0", - "react-router-dom": "^5.2.0", - "styled-components": "^5.3.6" + "react-bootstrap-typeahead": "^6.0.0", + "react-error-boundary": "^3.1.4", + "react-files": "^3.0.0-alpha.3", + "react-infinite-scroller": "^1.2.6", + "react-markdown": "^7.1.0", + "react-singleton-hook": "^3.1.1", + "react-syntax-highlighter": "^15.5.0", + "react-uuid": "^1.0.2", + "remark-gfm": "^3.0.1", + "styled-components": "^5.3.6", + "tweetnacl": "^1.0.3" + }, + "devDependencies": { + "@babel/core": "^7.20.12", + "@babel/preset-env": "^7.20.2", + "@babel/preset-react": "^7.18.6", + "buffer": "^6.0.3", + "clean-webpack-plugin": "^4.0.0", + "copy-webpack-plugin": "^9.0.1", + "cross-env": "^7.0.3", + "crypto-browserify": "^3.12.0", + "css-loader": "^6.2.0", + "css-minimizer-webpack-plugin": "^3.0.2", + "html-webpack-plugin": "^5.3.2", + "https-browserify": "^1.0.0", + "mini-css-extract-plugin": "^2.2.2", + "node-sass": "^7.0.3", + "os-browserify": "^0.3.0", + "postcss-loader": "^7.0.1", + "process": "^0.11.10", + "sass-loader": "^13.1.0", + "stream-browserify": "^3.0.0", + "stream-http": "^3.2.0", + "style-loader": "^3.2.1", + "url": "^0.11.0", + "webpack": "^5.52.0", + "webpack-bundle-analyzer": "^4.4.2", + "webpack-cli": "^4.8.0", + "webpack-dev-server": "^4.1.0", + "webpack-manifest-plugin": "^5.0.0", + "webpack-merge": "^5.8.0", + "webpack-node-externals": "^3.0.0" + }, + "peerDependencies": { + "react": "^18.2.0", + "react-dom": "^18.2.0" }, "scripts": { - "serve": "webpack serve", "webpack": "webpack", - "dev": "npm run serve -- --env mode=development", "prod": "npm run webpack -- --env mode=production", - "prod:analyze": "npm run prod -- --env presets=analyze", - "build": "npm run prod", - "start": "npm run dev" + "build": "npm run prod" }, "eslintConfig": { "extends": [ @@ -48,40 +99,5 @@ "last 1 firefox version", "last 1 safari version" ] - }, - "devDependencies": { - "@babel/cli": "^7.15.4", - "@babel/core": "^7.15.5", - "@babel/preset-env": "^7.15.4", - "@babel/preset-react": "^7.14.5", - "assert": "^2.0.0", - "babel-loader": "^8.2.2", - "browserify-zlib": "^0.2.0", - "buffer": "^6.0.3", - "clean-webpack-plugin": "^4.0.0", - "copy-webpack-plugin": "^9.0.1", - "cross-env": "^7.0.3", - "crypto-browserify": "^3.12.0", - "css-loader": "^6.2.0", - "css-minimizer-webpack-plugin": "^3.0.2", - "html-webpack-plugin": "^5.3.2", - "https-browserify": "^1.0.0", - "mini-css-extract-plugin": "^2.2.2", - "node-sass": "^7.0.3", - "os-browserify": "^0.3.0", - "path-browserify": "^1.0.1", - "postcss-loader": "^7.0.1", - "process": "^0.11.10", - "sass-loader": "^13.1.0", - "stream-browserify": "^3.0.0", - "stream-http": "^3.2.0", - "style-loader": "^3.2.1", - "url": "^0.11.0", - "webpack": "^5.52.0", - "webpack-bundle-analyzer": "^4.4.2", - "webpack-cli": "^4.8.0", - "webpack-dev-server": "^4.1.0", - "webpack-manifest-plugin": "^5.0.0", - "webpack-merge": "^5.8.0" } } diff --git a/public/.nojekyll b/public/.nojekyll deleted file mode 100644 index e69de29..0000000 diff --git a/public/CNAME b/public/CNAME deleted file mode 100644 index 5411039..0000000 --- a/public/CNAME +++ /dev/null @@ -1 +0,0 @@ -near.social diff --git a/public/_redirects b/public/_redirects deleted file mode 100644 index ad37e2c..0000000 --- a/public/_redirects +++ /dev/null @@ -1 +0,0 @@ -/* /index.html 200 diff --git a/public/favicon.png b/public/favicon.png deleted file mode 100644 index 00b44cd2315c4307ea586a3315730aa26d10b222..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24347 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 - - - - - - - - - - - - - - - - - - Near Social - - - - - -
- - diff --git a/public/logo.png b/public/logo.png deleted file mode 100644 index 48ec1211c2741783726108b740c742f6e124b272..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 46005 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 diff --git a/public/manifest.json b/public/manifest.json deleted file mode 100644 index 642b9a5..0000000 --- a/public/manifest.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "short_name": "Near Social", - "name": "Near Social", - "icons": [ - { - "src": "favicon.png", - "sizes": "1024x1024", - "type": "image/png" - } - ], - "start_url": ".", - "display": "standalone", - "theme_color": "#333333", - "background_color": "#ffffff" -} diff --git a/public/robots.txt b/public/robots.txt deleted file mode 100644 index e9e57dc..0000000 --- a/public/robots.txt +++ /dev/null @@ -1,3 +0,0 @@ -# https://www.robotstxt.org/robotstxt.html -User-agent: * -Disallow: diff --git a/src/App.js b/src/App.js deleted file mode 100644 index 63da767..0000000 --- a/src/App.js +++ /dev/null @@ -1,143 +0,0 @@ -import React, { useCallback, useEffect, useState } from "react"; -import "error-polyfill"; -import "bootstrap-icons/font/bootstrap-icons.css"; -import "@near-wallet-selector/modal-ui/styles.css"; -import "bootstrap/dist/js/bootstrap.bundle"; -import "App.scss"; -import { HashRouter as Router, Link, Route, Switch } from "react-router-dom"; -import EditorPage from "./pages/EditorPage"; -import ViewPage from "./pages/ViewPage"; -import { setupModal } from "@near-wallet-selector/modal-ui"; -import EmbedPage from "./pages/EmbedPage"; -import { useAccount, useInitNear, useNear, utils } from "near-social-vm"; -import Big from "big.js"; -import { NavigationWrapper } from "./components/navigation/NavigationWrapper"; -import { NetworkId, Widgets } from "./data/widgets"; - -export const refreshAllowanceObj = {}; - -function App(props) { - console.log(useState); - const [connected, setConnected] = useState(false); - const [signedIn, setSignedIn] = useState(false); - const [signedAccountId, setSignedAccountId] = useState(null); - const [availableStorage, setAvailableStorage] = useState(null); - const [walletModal, setWalletModal] = useState(null); - const [widgetSrc, setWidgetSrc] = useState(null); - - const { initNear } = useInitNear(); - const near = useNear(); - const account = useAccount(); - const accountId = account.accountId; - - const location = window.location; - - useEffect(() => { - initNear && - initNear({ - networkId: NetworkId, - }); - }, [initNear]); - - useEffect(() => { - if ( - !location.search.includes("?account_id") && - !location.search.includes("&account_id") && - (location.search || location.href.includes("/?#")) - ) { - window.history.replaceState({}, "/", "/" + location.hash); - } - }, [location]); - - useEffect(() => { - if (!near) { - return; - } - near.selector.then((selector) => { - setWalletModal( - setupModal(selector, { contractId: near.config.contractName }) - ); - }); - }, [near]); - - const requestSignIn = useCallback( - (e) => { - e && e.preventDefault(); - walletModal.show(); - return false; - }, - [walletModal] - ); - - const logOut = useCallback(async () => { - if (!near) { - return; - } - const wallet = await (await near.selector).wallet(); - wallet.signOut(); - near.accountId = null; - setSignedIn(false); - setSignedAccountId(null); - }, [near]); - - const refreshAllowance = useCallback(async () => { - alert( - "You're out of access key allowance. Need sign in again to refresh it" - ); - await logOut(); - requestSignIn(); - }, [logOut, requestSignIn]); - refreshAllowanceObj.refreshAllowance = refreshAllowance; - - useEffect(() => { - if (!near) { - return; - } - setSignedIn(!!accountId); - setSignedAccountId(accountId); - setConnected(true); - }, [near, accountId]); - - useEffect(() => { - setAvailableStorage( - account.storageBalance - ? Big(account.storageBalance.available).div(utils.StorageCostPerByte) - : Big(0) - ); - }, [account]); - - const passProps = { - refreshAllowance: () => refreshAllowance(), - setWidgetSrc, - signedAccountId, - signedIn, - connected, - availableStorage, - widgetSrc, - logOut, - requestSignIn, - widgets: Widgets, - }; - - return ( -
- - - - - - - - - - - - - - - -
- ); -} - -export default App; diff --git a/src/App.scss b/src/App.scss deleted file mode 100644 index da794f2..0000000 --- a/src/App.scss +++ /dev/null @@ -1,45 +0,0 @@ -@import "bootstrap"; - -body, html { - -webkit-font-smoothing: antialiased; -} - -.pointer { - cursor: pointer; -} - -.btn-success, .btn-primary { - .text-muted { - color: #fff !important; - }; -} - -.outline-none { - outline: 0 !important; -} - -a { - text-decoration: none; - &:hover { - text-decoration: underline; - } - &.btn { - text-decoration: none; - } -} - -.sidebar-items { - &> div { - border-right: 1px solid #e5e5e5; - text-align: center; - min-height: 4rem; - max-height: 4rem; - display: flex; - } - - &> div:not(.apps) { - min-width: 4rem; - align-items: center !important; - justify-content: center !important; - } -} diff --git a/src/components/Editor/OpenModal.js b/src/components/Editor/OpenModal.js deleted file mode 100644 index 0d66aab..0000000 --- a/src/components/Editor/OpenModal.js +++ /dev/null @@ -1,62 +0,0 @@ -import React, { useState } from "react"; -import Modal from "react-bootstrap/Modal"; - -export default function OpenModal(props) { - const onHide = props.onHide; - const onOpen = props.onOpen; - const onNew = props.onNew; - const show = props.show; - - const [widgetSrc, setWidgetSrc] = useState(""); - - return ( - - - Open widget - - - - - setWidgetSrc(e.target.value.replaceAll(/[^a-zA-Z0-9_.\-\/]/g, "")) - } - /> - - - - - - - - ); -} diff --git a/src/components/Editor/RenameModal.js b/src/components/Editor/RenameModal.js deleted file mode 100644 index 026ff11..0000000 --- a/src/components/Editor/RenameModal.js +++ /dev/null @@ -1,49 +0,0 @@ -import React, { useState } from "react"; -import Modal from "react-bootstrap/Modal"; - -export default function RenameModal(props) { - const onHide = props.onHide; - const name = props.name; - const onRename = props.onRename; - const show = props.show; - - const [newName, setNewName] = useState(name); - - return ( - - - Rename - - - - - setNewName(e.target.value.replaceAll(/[^a-zA-Z0-9_.\-]/g, "")) - } - /> - - - - - - - ); -} diff --git a/src/components/common/buttons/BlueButton.js b/src/components/common/buttons/BlueButton.js deleted file mode 100644 index 26a1312..0000000 --- a/src/components/common/buttons/BlueButton.js +++ /dev/null @@ -1,13 +0,0 @@ -import React from "react"; -import { Button } from "./Button"; -import styled from "styled-components"; - -const StyledButton = styled(Button)` - background-color: var(--blue-light-9); - border-color: var(--blue-light-9); - color: white; -`; - -export function BlueButton(props) { - return {props.children}; -} diff --git a/src/components/common/buttons/Button.js b/src/components/common/buttons/Button.js deleted file mode 100644 index 45ab1c8..0000000 --- a/src/components/common/buttons/Button.js +++ /dev/null @@ -1,26 +0,0 @@ -import React from "react"; -import styled from "styled-components"; - -const StyledButton = styled.button` - border-radius: 8px; - border-style: solid; - border-width: 1px; - border-color: transparent; - padding: 8px 16px; - font-weight: var(--font-weight-bold); - display: inline-block; - height: 40px; -`; - -export function Button(props) { - return ( - - {props.children} - - ); -} diff --git a/src/components/common/buttons/GrayBorderButton.js b/src/components/common/buttons/GrayBorderButton.js deleted file mode 100644 index 564a9f3..0000000 --- a/src/components/common/buttons/GrayBorderButton.js +++ /dev/null @@ -1,13 +0,0 @@ -import React from "react"; -import { Button } from "./Button"; -import styled from "styled-components"; - -const StyledButton = styled(Button)` - background-color: var(--slate-dark-6); - border-color: var(--slate-dark-8); - color: white; -`; - -export function GrayBorderButton(props) { - return {props.children}; -} diff --git a/src/components/icons/ArrowUpRight.js b/src/components/icons/ArrowUpRight.js deleted file mode 100644 index 601fac3..0000000 --- a/src/components/icons/ArrowUpRight.js +++ /dev/null @@ -1,29 +0,0 @@ -import React from "react"; - -export function ArrowUpRight() { - return ( - - - - - ); -} diff --git a/src/components/icons/Book.js b/src/components/icons/Book.js deleted file mode 100644 index f6f5f6d..0000000 --- a/src/components/icons/Book.js +++ /dev/null @@ -1,28 +0,0 @@ -import React from "react"; - -export function Book() { - return ( - - - - - ); -} diff --git a/src/components/icons/Close.js b/src/components/icons/Close.js deleted file mode 100644 index da7e9d1..0000000 --- a/src/components/icons/Close.js +++ /dev/null @@ -1,28 +0,0 @@ -import React from "react"; - -export function Close() { - return ( - - - - - ); -} diff --git a/src/components/icons/Code.js b/src/components/icons/Code.js deleted file mode 100644 index 6f4a808..0000000 --- a/src/components/icons/Code.js +++ /dev/null @@ -1,28 +0,0 @@ -import React from "react"; - -export function Code() { - return ( - - - - - ); -} diff --git a/src/components/icons/Fork.js b/src/components/icons/Fork.js deleted file mode 100644 index e66527e..0000000 --- a/src/components/icons/Fork.js +++ /dev/null @@ -1,42 +0,0 @@ -import React from "react"; - -export function Fork() { - return ( - - - - - - - ); -} diff --git a/src/components/icons/Home.js b/src/components/icons/Home.js deleted file mode 100644 index a55b8c4..0000000 --- a/src/components/icons/Home.js +++ /dev/null @@ -1,28 +0,0 @@ -import React from "react"; - -export function Home() { - return ( - - - - - ); -} diff --git a/src/components/icons/LogOut.js b/src/components/icons/LogOut.js deleted file mode 100644 index a07dfc7..0000000 --- a/src/components/icons/LogOut.js +++ /dev/null @@ -1,35 +0,0 @@ -import React from "react"; - -export function LogOut() { - return ( - - - - - - ); -} diff --git a/src/components/icons/NearSocialLogo.js b/src/components/icons/NearSocialLogo.js deleted file mode 100644 index 5e02b15..0000000 --- a/src/components/icons/NearSocialLogo.js +++ /dev/null @@ -1,28 +0,0 @@ -import React from "react"; - -export function NearSocialLogo() { - return ( - - - - - ); -} diff --git a/src/components/icons/Pretend.js b/src/components/icons/Pretend.js deleted file mode 100644 index 1a96c08..0000000 --- a/src/components/icons/Pretend.js +++ /dev/null @@ -1,24 +0,0 @@ -import React from "react"; - -export function Pretend() { - return ( - - - - - ); -} diff --git a/src/components/icons/StopPretending.js b/src/components/icons/StopPretending.js deleted file mode 100644 index 585b580..0000000 --- a/src/components/icons/StopPretending.js +++ /dev/null @@ -1,19 +0,0 @@ -import React from "react"; - -export function StopPretending() { - return ( - - - - ); -} diff --git a/src/components/icons/User.js b/src/components/icons/User.js deleted file mode 100644 index c79903f..0000000 --- a/src/components/icons/User.js +++ /dev/null @@ -1,28 +0,0 @@ -import React from "react"; - -export function User() { - return ( - - - - - ); -} diff --git a/src/components/icons/UserCircle.js b/src/components/icons/UserCircle.js deleted file mode 100644 index 8e69a37..0000000 --- a/src/components/icons/UserCircle.js +++ /dev/null @@ -1,35 +0,0 @@ -import React from "react"; - -export function UserCircle() { - return ( - - - - - - ); -} diff --git a/src/components/icons/Withdraw.js b/src/components/icons/Withdraw.js deleted file mode 100644 index 3a54d68..0000000 --- a/src/components/icons/Withdraw.js +++ /dev/null @@ -1,19 +0,0 @@ -import React from "react"; - -export function Withdraw() { - return ( - - - - ); -} diff --git a/src/components/navigation/Logotype.js b/src/components/navigation/Logotype.js deleted file mode 100644 index 8e76da6..0000000 --- a/src/components/navigation/Logotype.js +++ /dev/null @@ -1,33 +0,0 @@ -import React from "react"; - -export function Logotype({ color = "white" }) { - return ( - - - - - - ); -} diff --git a/src/components/navigation/NavigationButton.js b/src/components/navigation/NavigationButton.js deleted file mode 100644 index cec0cdc..0000000 --- a/src/components/navigation/NavigationButton.js +++ /dev/null @@ -1,51 +0,0 @@ -import React from "react"; -import styled from "styled-components"; -import { NavLink } from "react-router-dom"; - -const StyledNavigationButton = styled.div` - a { - color: var(--slate-dark-11); - font-size: 16px; - padding: 10px; - border-radius: 8px; - font-weight: var(--font-weight-bold); - height: 40px; - display: flex; - align-items: center; - justify-content: center; - - &:hover, - &.active { - color: white; - text-decoration: none; - background-color: var(--slate-dark-6); - } - } - &.disabled { - opacity: 0.5; - } -`; - -export function NavigationButton(props) { - return ( - - {props.route ? ( - { - if (props.disabled) { - e.preventDefault(); - } - }} - to={props.route} - exact={true} - > - {props.children} - - ) : ( -
- {props.children} - - )} - - ); -} diff --git a/src/components/navigation/NavigationWrapper.js b/src/components/navigation/NavigationWrapper.js deleted file mode 100644 index e32aa9b..0000000 --- a/src/components/navigation/NavigationWrapper.js +++ /dev/null @@ -1,21 +0,0 @@ -import React, { useState, useEffect } from "react"; -import { DesktopNavigation } from "./desktop/DesktopNavigation"; -import { MobileNavigation } from "./mobile/MobileNavigation"; - -export function NavigationWrapper(props) { - const [matches, setMatches] = useState( - window.matchMedia("(min-width: 992px)").matches - ); - - useEffect(() => { - window - .matchMedia("(min-width: 992px)") - .addEventListener("change", (e) => setMatches(e.matches)); - }, []); - return ( - <> - {matches && } - {!matches && } - - ); -} diff --git a/src/components/navigation/NotificationWidget.js b/src/components/navigation/NotificationWidget.js deleted file mode 100644 index 6fee5ae..0000000 --- a/src/components/navigation/NotificationWidget.js +++ /dev/null @@ -1,43 +0,0 @@ -import React from "react"; -import styled from "styled-components"; -import { Widget } from "near-social-vm"; - -const StyledNotificationWidget = styled.div` - margin: 0 15px; - background-color: var(--slate-dark-5); - height: 40px; - width: 40px; - border-radius: 50%; - - > div, - a { - width: 100%; - height: 100%; - } - - a { - color: var(--slate-dark-11) !important; - display: flex; - align-items: center; - justify-content: center; - - i { - font-size: 18px !important; - } - } - - :hover { - a, - i { - color: white; - } - } -`; - -export function NotificationWidget({ notificationButtonSrc }) { - return ( - - - - ); -} diff --git a/src/components/navigation/PretendModal.js b/src/components/navigation/PretendModal.js deleted file mode 100644 index 1046853..0000000 --- a/src/components/navigation/PretendModal.js +++ /dev/null @@ -1,60 +0,0 @@ -import React, { useState } from "react"; -import Modal from "react-bootstrap/Modal"; -import { Widget, useAccount } from "near-social-vm"; - -export default function PretendModal(props) { - const account = useAccount(); - const onHide = props.onHide; - const show = props.show; - - const [accountId, setAccountId] = useState(""); - - return ( - - - Pretend to be another account - - -
- - - setAccountId( - e.target.value.toLowerCase().replaceAll(/[^a-z0-9_.\-]/g, "") - ) - } - /> -
-
- -
-
- - - - -
- ); -} diff --git a/src/components/navigation/SignInButton.js b/src/components/navigation/SignInButton.js deleted file mode 100644 index d955125..0000000 --- a/src/components/navigation/SignInButton.js +++ /dev/null @@ -1,10 +0,0 @@ -import React from "react"; -import { GrayBorderButton } from "../common/buttons/GrayBorderButton"; - -export function SignInButton(props) { - return ( - - Sign In - - ); -} diff --git a/src/components/navigation/desktop/DesktopNavigation.js b/src/components/navigation/desktop/DesktopNavigation.js deleted file mode 100644 index 003ef68..0000000 --- a/src/components/navigation/desktop/DesktopNavigation.js +++ /dev/null @@ -1,91 +0,0 @@ -import React from "react"; -import styled from "styled-components"; -import { Link } from "react-router-dom"; -import { Logotype } from "../Logotype"; -import { NavigationButton } from "../NavigationButton"; -import { ArrowUpRight } from "../../icons/ArrowUpRight"; -import { SignInButton } from "../SignInButton"; -import { UserDropdown } from "./UserDropdown"; -import { DevActionsDropdown } from "./DevActionsDropdown"; -import { NotificationWidget } from "../NotificationWidget"; - -const StyledNavigation = styled.div` - position: sticky; - top: 0; - left: 0; - right: 0; - width: 100%; - background-color: var(--slate-dark-1); - z-index: 1000; - padding: 12px 0; - - .user-section { - margin-left: auto; - > button { - font-size: 14px; - } - } - - .container { - display: flex; - align-items: center; - - .navigation-section { - margin-left: 50px; - display: flex; - - > div { - > a { - margin-right: 20px; - } - } - } - - .user-section { - display: flex; - align-items: center; - - .nav-create-btn { - margin-left: 10px; - } - } - - .arrow-up-right { - margin-left: 4px; - } - } -`; - -export function DesktopNavigation(props) { - return ( - -
- - - -
- Home - Create - - Documentation - - -
-
- {!props.signedIn && ( - props.requestSignIn()} /> - )} - {props.signedIn && ( - <> - - - - - )} -
-
-
- ); -} diff --git a/src/components/navigation/desktop/DevActionsDropdown.js b/src/components/navigation/desktop/DevActionsDropdown.js deleted file mode 100644 index c531369..0000000 --- a/src/components/navigation/desktop/DevActionsDropdown.js +++ /dev/null @@ -1,133 +0,0 @@ -import React from "react"; -import styled from "styled-components"; -import { Link } from "react-router-dom"; -import { Fork } from "../../icons/Fork"; -import { Code } from "../../icons/Code"; -import { useAccount } from "near-social-vm"; - -const StyledDropdown = styled.div` - .dropdown-toggle { - display: flex; - align-items: center; - justify-content: center; - background-color: var(--slate-dark-5); - border-radius: 50px; - outline: none; - border: 0; - width: 40px; - height: 40px; - - &:after { - display none; - } - - .menu { - width: 18px; - height: 24px; - display: flex; - flex-direction: column; - justify-content: space-evenly; - - div { - background-color: var(--slate-dark-11);; - height: 2px; - width: 100%; - border-radius: 30px; - } - } - - :hover { - .menu { - div { - background-color: white; - } - } - } - } - - ul { - background-color: var(--slate-dark-5); - width: 100%; - - li { - padding: 0 6px; - } - - button, - a { - color: var(--slate-dark-11); - display: flex; - align-items: center; - border-radius: 8px; - padding: 12px; - - :hover, - :focus { - text-decoration: none; - background-color: var(--slate-dark-1); - color: white; - - svg { - path { - stroke: white; - } - } - } - - svg { - margin-right: 7px; - path { - stroke: var(--slate-dark-9); - } - } - } - } -`; - -export function DevActionsDropdown(props) { - const account = useAccount(); - - if (props.widgetSrc?.edit || props.widgetSrc?.view) { - return ( - - -
    - {props.widgetSrc?.edit && ( -
  • - - - {props.widgetSrc.edit.startsWith(`${account.accountId}/widget/`) - ? "Edit widget" - : "Fork widget"} - -
  • - )} - {props.widgetSrc?.view && ( -
  • - - - View source - -
  • - )} -
-
- ); - } else { - return null; - } -} diff --git a/src/components/navigation/desktop/UserDropdown.js b/src/components/navigation/desktop/UserDropdown.js deleted file mode 100644 index 4154320..0000000 --- a/src/components/navigation/desktop/UserDropdown.js +++ /dev/null @@ -1,200 +0,0 @@ -import React, { useCallback } from "react"; -import { Widget, useNear, useAccount } from "near-social-vm"; -import styled from "styled-components"; -import { User } from "../../icons/User"; -import { LogOut } from "../../icons/LogOut"; -import { Withdraw } from "../../icons/Withdraw"; -import { NavLink } from "react-router-dom"; -import PretendModal from "../PretendModal"; -import { Pretend } from "../../icons/Pretend"; -import { StopPretending } from "../../icons/StopPretending"; - -const StyledDropdown = styled.div` - button, - a { - font-weight: var(--font-weight-medium); - } - .dropdown-toggle { - display: flex; - align-items: center; - text-align: left; - background-color: var(--slate-dark-5); - border-radius: 50px; - outline: none; - border: 0; - - &:after { - margin: 0 15px; - border-top-color: var(--slate-dark-11); - } - - img { - border-radius: 50% !important; - } - - .profile-info { - margin: 5px 10px; - line-height: normal; - max-width: 140px; - - .profile-name, - .profile-username { - text-overflow: ellipsis; - overflow: hidden; - } - - .profile-name { - color: var(--slate-dark-12); - } - .profile-username { - color: var(--slate-dark-11); - } - } - } - - ul { - background-color: var(--slate-dark-5); - width: 100%; - - li { - padding: 0 6px; - } - - button, - a { - color: var(--slate-dark-11); - display: flex; - align-items: center; - border-radius: 8px; - padding: 12px; - - :hover, - :focus { - text-decoration: none; - background-color: var(--slate-dark-1); - color: white; - - svg { - path { - stroke: white; - } - } - } - - svg { - margin-right: 7px; - min-width: 24px; - path { - stroke: var(--slate-dark-9); - } - } - } - } -`; - -export function UserDropdown(props) { - const near = useNear(); - const account = useAccount(); - - const withdrawStorage = useCallback(async () => { - await near.contract.storage_withdraw({}, undefined, "1"); - }, [near]); - - const [showPretendModal, setShowPretendModal] = React.useState(false); - - return ( - <> - - -
    -
  • - - - My Profile - -
  • -
  • - -
  • - {account.pretendAccountId ? ( -
  • - -
  • - ) : ( -
  • - -
  • - )} -
  • - -
  • -
-
- setShowPretendModal(false)} - widgets={props.widgets} - /> - - ); -} diff --git a/src/components/navigation/mobile/Menu.js b/src/components/navigation/mobile/Menu.js deleted file mode 100644 index 88d8007..0000000 --- a/src/components/navigation/mobile/Menu.js +++ /dev/null @@ -1,256 +0,0 @@ -import React from "react"; -import styled from "styled-components"; -import { Close } from "../../icons/Close"; -import { Home } from "../../icons/Home"; -import { Book } from "../../icons/Book"; -import { Code } from "../../icons/Code"; -import { LogOut } from "../../icons/LogOut"; -import { Fork } from "../../icons/Fork"; -import { UserCircle } from "../../icons/UserCircle"; -import { Widget } from "near-social-vm"; -import { NavigationButton } from "../NavigationButton"; -import { SignInButton } from "../SignInButton"; -import { Link } from "react-router-dom"; - -const StyledMenu = styled.div` - position: fixed; - top: 0; - bottom: 0; - left: 0; - right: 0; - z-index: 1000; - display: flex; - transition: 350ms; - transform: translateX(-100%); - - &.show { - transform: translateX(0); - } - - ul { - list-style-type: none; - margin: 0; - padding: 0; - } - - .left-side { - flex: 80; - background-color: var(--slate-dark-1); - position: relative; - display: flex; - flex-direction: column; - padding: 25px; - overflow-x: auto; - - .nav-sign-in-btn { - width: fit-content; - } - - .profile-link { - max-width: 100%; - white-space: nowrap; - - :hover { - text-decoration: none; - } - } - - img { - border-radius: 50% !important; - } - - .profile-name { - color: var(--slate-dark-12); - font-weight: var(--font-weight-bold); - margin-top: 10px; - } - - .profile-username { - color: var(--slate-dark-11); - } - - .profile-name, - .profile-username { - text-overflow: ellipsis; - overflow: hidden; - } - } - - .top-links, - .bottom-links { - a, - button { - justify-content: flex-start; - padding: 28px 0; - display: flex; - align-items: center; - color: var(--slate-dark-11); - font-weight: var(--font-weight-bold); - - svg { - margin-right: 12px; - } - - &.active, - &:hover, - &:focus { - background-color: transparent; - color: white; - text-decoration: none; - svg { - path { - stroke: white; - } - } - } - } - } - - .top-links { - margin-top: 40px; - } - - .bottom-links { - margin-top: auto; - - a, - button { - padding: 14px 0; - } - } - - .log-out-button { - background: none; - border: none; - color: var(--slate-dark-11); - font-weight: var(--font-weight-bold); - padding: 28px 0; - - svg { - path { - stroke: #9ba1a6; - } - } - } - - .close-button { - background: none; - border: none; - position: absolute; - right: 16px; - top: 16px; - padding: 10px; - - svg { - margin: 0; - } - } - - .right-side { - flex: 20; - opacity: 0.8; - background-color: var(--slate-dark-1); - } -`; - -export function Menu(props) { - return ( - -
- {props.signedIn ? ( - - - {props.widgets.profileName && ( -
- -
- )} -
{props.signedAccountId}
- - ) : ( - { - props.onCloseMenu(); - props.requestSignIn(); - }} - /> - )} -
    -
  • - - - Home - -
  • -
  • - - - Profile - -
  • -
  • - - - Create - -
  • -
  • - - - Documentation - -
  • -
-
    - {props.widgetSrc?.edit && ( -
  • - - - {props.widgetSrc.edit.startsWith( - `${props.signedAccountId}/widget/` - ) - ? "Edit widget" - : "Fork widget"} - -
  • - )} - {props.widgetSrc?.view && ( -
  • - - - View source - -
  • - )} - {props.signedIn && ( -
  • - -
  • - )} -
- -
-
- - ); -} diff --git a/src/components/navigation/mobile/MobileMenuButton.js b/src/components/navigation/mobile/MobileMenuButton.js deleted file mode 100644 index 2664d08..0000000 --- a/src/components/navigation/mobile/MobileMenuButton.js +++ /dev/null @@ -1,41 +0,0 @@ -import React from "react"; -import styled from "styled-components"; - -const StyledMobileMenuButton = styled.button` - background-color: transparent; - border: none; - display: flex; - align-items: center; - color: white; - font-weight: var(--font-weight-bold); - padding: 0; - - .menu { - width: 18px; - height: 24px; - display: flex; - flex-direction: column; - justify-content: space-evenly; - margin-right: 10px; - - div { - background-color: white; - height: 2px; - width: 100%; - border-radius: 30px; - } - } -`; - -export function MobileMenuButton(props) { - return ( - -
-
-
-
-
- {props.currentPage} - - ); -} diff --git a/src/components/navigation/mobile/MobileNavigation.js b/src/components/navigation/mobile/MobileNavigation.js deleted file mode 100644 index 6ebf4e9..0000000 --- a/src/components/navigation/mobile/MobileNavigation.js +++ /dev/null @@ -1,52 +0,0 @@ -import React, { useState, useEffect } from "react"; -import { Navigation } from "./Navigation"; -import { Menu } from "./Menu"; -import { useLocation } from "react-router-dom"; -import useScrollBlock from ".././../../hooks/useScrollBlock"; - -export function MobileNavigation(props) { - const [showMenu, setShowMenu] = useState(false); - const [currentPage, setCurrentPage] = useState(""); - const location = useLocation(); - const [blockScroll, allowScroll] = useScrollBlock(); - - useEffect(() => { - setShowMenu(false); - getCurrentPage(); - allowScroll(); - }, [location.pathname]); - - const getCurrentPage = () => { - switch (location.pathname) { - case "/": - return setCurrentPage("Home"); - case `/${props.widgets.profilePage}`: - return setCurrentPage("Profile"); - case "/edit": - return setCurrentPage("Create"); - default: - return setCurrentPage(""); - } - }; - - return ( - <> - { - setShowMenu(true); - blockScroll(); - }} - /> - { - setShowMenu(false); - allowScroll(); - }} - /> - - ); -} diff --git a/src/components/navigation/mobile/Navigation.js b/src/components/navigation/mobile/Navigation.js deleted file mode 100644 index dc6de45..0000000 --- a/src/components/navigation/mobile/Navigation.js +++ /dev/null @@ -1,63 +0,0 @@ -import React from "react"; -import styled from "styled-components"; -import { Link } from "react-router-dom"; -import { MobileMenuButton } from "./MobileMenuButton"; -import { NearSocialLogo } from "../../icons/NearSocialLogo"; -import { NotificationWidget } from "../NotificationWidget"; -import { SignInButton } from "../SignInButton"; - -const StyledNavigation = styled.div` - position: sticky; - top: 0; - left: 0; - right: 0; - width: 100%; - background-color: var(--slate-dark-1); - z-index: 1000; - padding: 16px 24px; - display: flex; - align-items: center; - justify-content: space-between; - - .logo-link { - position: absolute; - left: 0; - right: 0; - margin: auto; - display: flex; - align-items: center; - justify-content: center; - width: fit-content; - } - - .nav-notification-widget { - margin: 0; - } - - .nav-sign-in-btn { - background: none; - border: none; - padding-right: 0; - } -`; - -export function Navigation(props) { - return ( - - - - - - {props.signedIn ? ( - - ) : ( - props.requestSignIn()} /> - )} - - ); -} diff --git a/src/data/widgets.js b/src/data/widgets.js deleted file mode 100644 index b28c394..0000000 --- a/src/data/widgets.js +++ /dev/null @@ -1,35 +0,0 @@ -const TestnetDomains = { - "test.near.social": true, - "127.0.0.1": true, -}; - -export const NetworkId = - window.location.hostname in TestnetDomains ? "testnet" : "mainnet"; -const TestnetWidgets = { - image: "eugenethedream/widget/Image", - default: "eugenethedream/widget/Welcome", - viewSource: "eugenethedream/widget/WidgetSource", - widgetMetadataEditor: "eugenethedream/widget/WidgetMetadataEditor", - widgetMetadata: "eugenethedream/widget/WidgetMetadata", - profileImage: "eugenethedream/widget/ProfileImage", - profilePage: "eugenethedream/widget/Profile", - profileName: "eugenethedream/widget/ProfileName", - notificationButton: "eugenethedream/widget/NotificationButton", -}; - -const MainnetWidgets = { - image: "mob.near/widget/Image", - default: "mob.near/widget/Homepage", - viewSource: "mob.near/widget/WidgetSource", - widgetMetadataEditor: "mob.near/widget/WidgetMetadataEditor", - widgetMetadata: "mob.near/widget/WidgetMetadata", - profileImage: "mob.near/widget/ProfileImage", - notificationButton: "mob.near/widget/NotificationButton", - profilePage: "mob.near/widget/ProfilePage", - profileName: "patrick.near/widget/ProfileName", - editorComponentSearch: "mob.near/widget/Editor.ComponentSearch", - profileInlineBlock: "mob.near/widget/Profile.InlineBlock", -}; - -export const Widgets = - NetworkId === "testnet" ? TestnetWidgets : MainnetWidgets; diff --git a/src/hooks/useQuery.js b/src/hooks/useQuery.js deleted file mode 100644 index 3aefe87..0000000 --- a/src/hooks/useQuery.js +++ /dev/null @@ -1,8 +0,0 @@ -import { useLocation } from "react-router-dom"; -import React from "react"; - -export function useQuery() { - const { search } = useLocation(); - - return React.useMemo(() => new URLSearchParams(search), [search]); -} diff --git a/src/hooks/useScrollBlock.js b/src/hooks/useScrollBlock.js deleted file mode 100644 index 99e923a..0000000 --- a/src/hooks/useScrollBlock.js +++ /dev/null @@ -1,51 +0,0 @@ -import { useRef } from "react"; - -const safeDocument = typeof document !== "undefined" ? document : {}; - -/** - * Usage: - * const [blockScroll, allowScroll] = useScrollBlock(); - */ -export default () => { - const scrollBlocked = useRef(); - const html = safeDocument.documentElement; - const { body } = safeDocument; - - const blockScroll = () => { - if (!body || !body.style || scrollBlocked.current) return; - - const scrollBarWidth = window.innerWidth - html.clientWidth; - const bodyPaddingRight = - parseInt( - window.getComputedStyle(body).getPropertyValue("padding-right") - ) || 0; - - /** - * 1. Fixes a bug in iOS and desktop Safari whereby setting - * `overflow: hidden` on the html/body does not prevent scrolling. - * 2. Fixes a bug in desktop Safari where `overflowY` does not prevent - * scroll if an `overflow-x` style is also applied to the body. - */ - html.style.position = "relative"; /* [1] */ - html.style.overflow = "hidden"; /* [2] */ - body.style.position = "relative"; /* [1] */ - body.style.overflow = "hidden"; /* [2] */ - body.style.paddingRight = `${bodyPaddingRight + scrollBarWidth}px`; - - scrollBlocked.current = true; - }; - - const allowScroll = () => { - if (!body || !body.style || !scrollBlocked.current) return; - - html.style.position = ""; - html.style.overflow = ""; - body.style.position = ""; - body.style.overflow = ""; - body.style.paddingRight = ""; - - scrollBlocked.current = false; - }; - - return [blockScroll, allowScroll]; -}; diff --git a/src/images/near_social_combo.svg b/src/images/near_social_combo.svg deleted file mode 100644 index f538456..0000000 --- a/src/images/near_social_combo.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/src/images/near_social_icon.svg b/src/images/near_social_icon.svg deleted file mode 100644 index 63da35c..0000000 --- a/src/images/near_social_icon.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/index.css b/src/index.css deleted file mode 100644 index bd57d42..0000000 --- a/src/index.css +++ /dev/null @@ -1,13 +0,0 @@ -:root { - --slate-dark-1: #151718; - --slate-dark-5: #2B2F31; - --slate-dark-6: #313538; - --slate-dark-8: #4C5155; - --slate-dark-9: #697177; - --slate-dark-11: #9BA1A6; - --slate-dark-12: #ECEDEE; - --blue-light-9: #0091FF; - - --font-weight-medium: 500; - --font-weight-bold: 600; -} \ No newline at end of file diff --git a/src/index.js b/src/index.js index da5610d..8dfad77 100644 --- a/src/index.js +++ b/src/index.js @@ -1,8 +1,18 @@ import React from "react"; -import { createRoot } from "react-dom/client"; -import "./index.css"; -import App from "./App"; +import { useAccount, useAccountId } from "./lib/data/account"; +import { useInitNear, useNear } from "./lib/data/near"; +import { Widget } from "./lib/components/Widget"; +import { useCache } from "./lib/data/cache"; +import * as utils from "./lib/data/utils"; +import { CommitButton } from "./lib/components/Commit"; -const container = document.getElementById("root"); -const root = createRoot(container); -root.render(); +export { + Widget, + CommitButton, + useInitNear, + useNear, + useCache, + useAccount, + useAccountId, + utils, +}; diff --git a/src/near-social-vm/src/lib/components/Commit.js b/src/lib/components/Commit.js similarity index 100% rename from src/near-social-vm/src/lib/components/Commit.js rename to src/lib/components/Commit.js diff --git a/src/near-social-vm/src/lib/components/ConfirmTransactions.js b/src/lib/components/ConfirmTransactions.js similarity index 100% rename from src/near-social-vm/src/lib/components/ConfirmTransactions.js rename to src/lib/components/ConfirmTransactions.js diff --git a/src/near-social-vm/src/lib/components/Markdown.js b/src/lib/components/Markdown.js similarity index 100% rename from src/near-social-vm/src/lib/components/Markdown.js rename to src/lib/components/Markdown.js diff --git a/src/near-social-vm/src/lib/components/SecureIframe.js b/src/lib/components/SecureIframe.js similarity index 100% rename from src/near-social-vm/src/lib/components/SecureIframe.js rename to src/lib/components/SecureIframe.js diff --git a/src/near-social-vm/src/lib/components/Widget.js b/src/lib/components/Widget.js similarity index 100% rename from src/near-social-vm/src/lib/components/Widget.js rename to src/lib/components/Widget.js diff --git a/src/near-social-vm/src/lib/components/remark/mentions.js b/src/lib/components/remark/mentions.js similarity index 100% rename from src/near-social-vm/src/lib/components/remark/mentions.js rename to src/lib/components/remark/mentions.js diff --git a/src/near-social-vm/src/lib/data/account.js b/src/lib/data/account.js similarity index 100% rename from src/near-social-vm/src/lib/data/account.js rename to src/lib/data/account.js diff --git a/src/near-social-vm/src/lib/data/cache.js b/src/lib/data/cache.js similarity index 100% rename from src/near-social-vm/src/lib/data/cache.js rename to src/lib/data/cache.js diff --git a/src/near-social-vm/src/lib/data/commitData.js b/src/lib/data/commitData.js similarity index 100% rename from src/near-social-vm/src/lib/data/commitData.js rename to src/lib/data/commitData.js diff --git a/src/near-social-vm/src/lib/data/near.js b/src/lib/data/near.js similarity index 100% rename from src/near-social-vm/src/lib/data/near.js rename to src/lib/data/near.js diff --git a/src/near-social-vm/src/lib/data/utils.js b/src/lib/data/utils.js similarity index 100% rename from src/near-social-vm/src/lib/data/utils.js rename to src/lib/data/utils.js diff --git a/src/near-social-vm/src/lib/vm/vm.js b/src/lib/vm/vm.js similarity index 100% rename from src/near-social-vm/src/lib/vm/vm.js rename to src/lib/vm/vm.js diff --git a/src/near-social-vm/.babelrc b/src/near-social-vm/.babelrc deleted file mode 100644 index 2b7bafa..0000000 --- a/src/near-social-vm/.babelrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "presets": ["@babel/preset-env", "@babel/preset-react"] -} diff --git a/src/near-social-vm/.gitignore b/src/near-social-vm/.gitignore deleted file mode 100644 index 2d85219..0000000 --- a/src/near-social-vm/.gitignore +++ /dev/null @@ -1,33 +0,0 @@ -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - -# dependencies -/node_modules -/.pnp -.pnp.js - -# testing -/coverage - -# production -/build -/dist - -# misc -.DS_Store -.env.local -.env.development.local -.env.test.local -.env.production.local - -npm-debug.log* -yarn-debug.log* -yarn-error.log* - -#IDE -.idea - -target -neardev - -# OS X -.DS_Store diff --git a/src/near-social-vm/config/paths.js b/src/near-social-vm/config/paths.js deleted file mode 100644 index e65567f..0000000 --- a/src/near-social-vm/config/paths.js +++ /dev/null @@ -1,13 +0,0 @@ -const path = require("path"); - -const srcPath = path.resolve(__dirname, "../src"); -const distPath = path.resolve(__dirname, "../dist"); -const publicPath = path.resolve(__dirname, "../public"); -const nodeModulesPath = path.resolve(__dirname, "../node_modules"); - -module.exports = { - srcPath, - distPath, - publicPath, - nodeModulesPath, -}; diff --git a/src/near-social-vm/config/presets/loadPreset.js b/src/near-social-vm/config/presets/loadPreset.js deleted file mode 100644 index 5cebf54..0000000 --- a/src/near-social-vm/config/presets/loadPreset.js +++ /dev/null @@ -1,13 +0,0 @@ -const { merge } = require("webpack-merge"); - -const loadPresets = (env = { presets: [] }) => { - const presets = env.presets || []; - /** @type {string[]} */ - const mergedPresets = [].concat(...[presets]); - const mergedConfigs = mergedPresets.map((presetName) => - require(`./webpack.${presetName}.js`)(env) - ); - - return merge({}, ...mergedConfigs); -}; -module.exports = loadPresets; diff --git a/src/near-social-vm/config/presets/webpack.analyze.js b/src/near-social-vm/config/presets/webpack.analyze.js deleted file mode 100644 index 5dba45f..0000000 --- a/src/near-social-vm/config/presets/webpack.analyze.js +++ /dev/null @@ -1,6 +0,0 @@ -const WebpackBundleAnalyzer = - require("webpack-bundle-analyzer").BundleAnalyzerPlugin; - -module.exports = () => ({ - plugins: [new WebpackBundleAnalyzer()], -}); diff --git a/src/near-social-vm/config/webpack.development.js b/src/near-social-vm/config/webpack.development.js deleted file mode 100644 index 57cfb81..0000000 --- a/src/near-social-vm/config/webpack.development.js +++ /dev/null @@ -1,48 +0,0 @@ -const path = require("path"); -const { HotModuleReplacementPlugin } = require("webpack"); - -module.exports = () => ({ - devtool: false, - module: { - rules: [ - { - test: /\.(scss|css)$/, - use: [ - { - // inject CSS to page - loader: "style-loader", - }, - { - // translates CSS into CommonJS modules - loader: "css-loader", - }, - { - // Run postcss actions - loader: "postcss-loader", - options: { - // `postcssOptions` is needed for postcss 8.x; - // if you use postcss 7.x skip the key - postcssOptions: { - // postcss plugins, can be exported to postcss.config.js - plugins: function () { - return [require("autoprefixer")]; - }, - }, - }, - }, - { - // compiles Sass to CSS - loader: "sass-loader", - }, - ], - }, - ], - }, - devServer: { - open: true, - static: path.resolve(__dirname, "../dist"), - port: 3000, - compress: true, - }, - plugins: [new HotModuleReplacementPlugin()], -}); diff --git a/src/near-social-vm/config/webpack.production.js b/src/near-social-vm/config/webpack.production.js deleted file mode 100644 index 8fe9edb..0000000 --- a/src/near-social-vm/config/webpack.production.js +++ /dev/null @@ -1,75 +0,0 @@ -const MiniCssExtractPlugin = require("mini-css-extract-plugin"); -const CssMinimizerPlugin = require("css-minimizer-webpack-plugin"); -const path = require("path"); - -module.exports = () => { - return { - // output: { - // path: path.resolve(__dirname, "../dist"), - // publicPath: "./", - // // filename: "[name].[contenthash].bundle.js", - // filename: "index.js", - // }, - devtool: false, - module: { - rules: [ - // { - // test: /\.(css)$/, - // use: [MiniCssExtractPlugin.loader, "css-loader"], - // // options: { - // // sourceMap: false, - // // }, - // }, - { - test: /\.(scss|css)$/, - use: [ - { - // inject CSS to page - loader: "style-loader", - }, - { - // translates CSS into CommonJS modules - loader: "css-loader", - }, - { - // Run postcss actions - loader: "postcss-loader", - options: { - // `postcssOptions` is needed for postcss 8.x; - // if you use postcss 7.x skip the key - postcssOptions: { - // postcss plugins, can be exported to postcss.config.js - plugins: function () { - return [require("autoprefixer")]; - }, - }, - }, - }, - { - // compiles Sass to CSS - loader: "sass-loader", - }, - ], - }, - ], - }, - plugins: [ - new MiniCssExtractPlugin({ - filename: "styles/[name].[contenthash].css", - chunkFilename: "[id].css", - }), - ], - optimization: { - minimize: true, - minimizer: [new CssMinimizerPlugin(), "..."], - // runtimeChunk: { - // name: "runtime", - // }, - }, - performance: { - hints: false, - maxEntrypointSize: 512000, - maxAssetSize: 512000, - }, - }; -}; diff --git a/src/near-social-vm/package.json b/src/near-social-vm/package.json deleted file mode 100644 index 9c46f59..0000000 --- a/src/near-social-vm/package.json +++ /dev/null @@ -1,103 +0,0 @@ -{ - "name": "near-social-vm", - "version": "0.1.0", - "description": "Near Social VM", - "main": "dist/index.js", - "files": [ - "dist" - ], - "dependencies": { - "@braintree/sanitize-url": "6.0.0", - "@near-wallet-selector/core": "^7.4.0", - "@near-wallet-selector/here-wallet": "^7.4.0", - "@near-wallet-selector/meteor-wallet": "^7.4.0", - "@near-wallet-selector/my-near-wallet": "^7.4.0", - "@near-wallet-selector/near-wallet": "^7.4.0", - "@near-wallet-selector/neth": "^7.4.0", - "@near-wallet-selector/sender": "^7.4.0", - "acorn": "^8.8.0", - "acorn-jsx": "^5.3.2", - "big.js": "^6.1.1", - "bn.js": "^5.1.1", - "bootstrap": "^5.2.1", - "bootstrap-icons": "^1.9.0", - "collections": "^5.1.12", - "deep-equal": "^2.2.0", - "elliptic": "^6.5.4", - "idb": "^7.1.1", - "local-storage": "^2.0.0", - "mdast-util-find-and-replace": "^2.0.0", - "near-api-js": "^0.45.1", - "prettier": "^2.7.1", - "react-bootstrap": "^2.5.0", - "react-bootstrap-typeahead": "^6.0.0", - "react-error-boundary": "^3.1.4", - "react-files": "^3.0.0-alpha.3", - "react-infinite-scroller": "^1.2.6", - "react-markdown": "^7.1.0", - "react-singleton-hook": "^3.1.1", - "react-syntax-highlighter": "^15.5.0", - "react-uuid": "^1.0.2", - "remark-gfm": "^3.0.1", - "styled-components": "^5.3.6", - "tweetnacl": "^1.0.3" - }, - "devDependencies": { - "@babel/core": "^7.20.12", - "@babel/preset-env": "^7.20.2", - "@babel/preset-react": "^7.18.6", - "buffer": "^6.0.3", - "clean-webpack-plugin": "^4.0.0", - "copy-webpack-plugin": "^9.0.1", - "cross-env": "^7.0.3", - "crypto-browserify": "^3.12.0", - "css-loader": "^6.2.0", - "css-minimizer-webpack-plugin": "^3.0.2", - "html-webpack-plugin": "^5.3.2", - "https-browserify": "^1.0.0", - "mini-css-extract-plugin": "^2.2.2", - "node-sass": "^7.0.3", - "os-browserify": "^0.3.0", - "postcss-loader": "^7.0.1", - "process": "^0.11.10", - "sass-loader": "^13.1.0", - "stream-browserify": "^3.0.0", - "stream-http": "^3.2.0", - "style-loader": "^3.2.1", - "url": "^0.11.0", - "webpack": "^5.52.0", - "webpack-bundle-analyzer": "^4.4.2", - "webpack-cli": "^4.8.0", - "webpack-dev-server": "^4.1.0", - "webpack-manifest-plugin": "^5.0.0", - "webpack-merge": "^5.8.0", - "webpack-node-externals": "^3.0.0" - }, - "peerDependencies": { - "react": "^18.2.0", - "react-dom": "^18.2.0" - }, - "scripts": { - "webpack": "webpack", - "prod": "npm run webpack -- --env mode=production", - "build": "npm run prod" - }, - "eslintConfig": { - "extends": [ - "react-app", - "react-app/jest" - ] - }, - "browserslist": { - "production": [ - ">0.2%", - "not dead", - "not op_mini all" - ], - "development": [ - "last 1 chrome version", - "last 1 firefox version", - "last 1 safari version" - ] - } -} diff --git a/src/near-social-vm/src/index.js b/src/near-social-vm/src/index.js deleted file mode 100644 index 8dfad77..0000000 --- a/src/near-social-vm/src/index.js +++ /dev/null @@ -1,18 +0,0 @@ -import React from "react"; -import { useAccount, useAccountId } from "./lib/data/account"; -import { useInitNear, useNear } from "./lib/data/near"; -import { Widget } from "./lib/components/Widget"; -import { useCache } from "./lib/data/cache"; -import * as utils from "./lib/data/utils"; -import { CommitButton } from "./lib/components/Commit"; - -export { - Widget, - CommitButton, - useInitNear, - useNear, - useCache, - useAccount, - useAccountId, - utils, -}; diff --git a/src/near-social-vm/webpack.config.js b/src/near-social-vm/webpack.config.js deleted file mode 100644 index d018c03..0000000 --- a/src/near-social-vm/webpack.config.js +++ /dev/null @@ -1,83 +0,0 @@ -const webpack = require("webpack"); -const paths = require("./config/paths"); -const path = require("path"); -const { CleanWebpackPlugin } = require("clean-webpack-plugin"); -const { merge } = require("webpack-merge"); -const loadPreset = require("./config/presets/loadPreset"); -const loadConfig = (mode) => require(`./config/webpack.${mode}.js`)(mode); -const nodeExternals = require("webpack-node-externals"); - -module.exports = function (env) { - const { mode = "production" } = env || {}; - return merge( - { - mode, - entry: `${paths.srcPath}/index.js`, - output: { - path: paths.distPath, - filename: "index.js", - libraryTarget: "umd", - }, - externals: [ - nodeExternals(), - { - react: { - commonjs: "react", - commonjs2: "react", - amd: "react", - root: "React", - }, - "react-dom": { - commonjs: "react-dom", - commonjs2: "react-dom", - amd: "react-dom", - root: "ReactDOM", - }, - }, - ], - module: { - rules: [ - { - test: /\.m?js/, - resolve: { - fullySpecified: false, - }, - }, - { - test: /\.js$/, - use: ["babel-loader"], - exclude: path.resolve(__dirname, "node_modules"), - }, - // Images: Copy image files to build folder - { test: /\.(?:ico|gif|png|jpg|jpeg)$/i, type: "asset/resource" }, - - // Fonts and SVGs: Inline files - { test: /\.(woff(2)?|eot|ttf|otf|svg|)$/, type: "asset/inline" }, - ], - }, - resolve: { - modules: [paths.srcPath, "node_modules"], - extensions: [".js", ".jsx", ".json"], - fallback: { - crypto: require.resolve("crypto-browserify"), - stream: require.resolve("stream-browserify"), - }, - }, - target: "node", - plugins: [ - // new webpack.EnvironmentPlugin({ - // // Configure environment variables here. - // ENVIRONMENT: "browser", - // }), - new CleanWebpackPlugin(), - new webpack.ProgressPlugin(), - new webpack.ProvidePlugin({ - process: "process/browser", - Buffer: [require.resolve("buffer/"), "Buffer"], - }), - ], - }, - loadConfig(mode), - loadPreset(env) - ); -}; diff --git a/src/pages/EditorPage.js b/src/pages/EditorPage.js deleted file mode 100644 index 77ab4c0..0000000 --- a/src/pages/EditorPage.js +++ /dev/null @@ -1,693 +0,0 @@ -import React, { useCallback, useEffect, useMemo, useState } from "react"; -import ls from "local-storage"; -import prettier from "prettier"; -import parserBabel from "prettier/parser-babel"; -import { useHistory, useParams } from "react-router-dom"; -import Editor from "@monaco-editor/react"; -import { - Widget, - useCache, - useNear, - CommitButton, - useAccountId, -} from "near-social-vm"; -import { Nav, OverlayTrigger, Tooltip } from "react-bootstrap"; -import RenameModal from "../components/Editor/RenameModal"; -import OpenModal from "../components/Editor/OpenModal"; - -const StorageDomain = { - page: "editor", -}; - -const StorageType = { - Code: "code", - Files: "files", -}; - -const Filetype = { - Widget: "widget", - Module: "module", -}; - -const LsKey = "social.near:v01:"; -const EditorLayoutKey = LsKey + "editorLayout:"; -const WidgetPropsKey = LsKey + "widgetProps:"; - -const DefaultEditorCode = "return
Hello World
;"; - -const Tab = { - Editor: "Editor", - Props: "Props", - Metadata: "Metadata", - Widget: "Widget", -}; - -const Layout = { - Tabs: "Tabs", - Split: "Split", -}; - -export default function EditorPage(props) { - const { widgetSrc } = useParams(); - const history = useHistory(); - const setWidgetSrc = props.setWidgetSrc; - - const [loading, setLoading] = useState(false); - const [code, setCode] = useState(undefined); - const [path, setPath] = useState(undefined); - const [files, setFiles] = useState(undefined); - const [lastPath, setLastPath] = useState(undefined); - const [showRenameModal, setShowRenameModal] = useState(false); - const [showOpenModal, setShowOpenModal] = useState(false); - - const [renderCode, setRenderCode] = useState(code); - const [widgetProps, setWidgetProps] = useState( - ls.get(WidgetPropsKey) || "{}" - ); - const [parsedWidgetProps, setParsedWidgetProps] = useState({}); - const [propsError, setPropsError] = useState(null); - const [metadata, setMetadata] = useState(undefined); - const near = useNear(); - const cache = useCache(); - const accountId = useAccountId(); - - const [tab, setTab] = useState(Tab.Editor); - const [layout, setLayoutState] = useState( - ls.get(EditorLayoutKey) || Layout.Tabs - ); - - const setLayout = useCallback( - (layout) => { - ls.set(EditorLayoutKey, layout); - setLayoutState(layout); - }, - [setLayoutState] - ); - - useEffect(() => { - setWidgetSrc({ - edit: null, - view: widgetSrc, - }); - }, [widgetSrc, setWidgetSrc]); - - const updateCode = useCallback( - (path, code) => { - cache.localStorageSet( - StorageDomain, - { - path, - type: StorageType.Code, - }, - { - code, - time: Date.now(), - } - ); - setCode(code); - }, - [cache, setCode] - ); - - useEffect(() => { - ls.set(WidgetPropsKey, widgetProps); - try { - const parsedWidgetProps = JSON.parse(widgetProps); - setParsedWidgetProps(parsedWidgetProps); - setPropsError(null); - } catch (e) { - setParsedWidgetProps({}); - setPropsError(e.message); - } - }, [widgetProps]); - - const removeFromFiles = useCallback( - (path) => { - path = JSON.stringify(path); - setFiles((files) => - files.filter((file) => JSON.stringify(file) !== path) - ); - setLastPath(path); - }, - [setFiles, setLastPath] - ); - - const addToFiles = useCallback( - (path) => { - const jpath = JSON.stringify(path); - setFiles((files) => { - const newFiles = [...files]; - if (!files.find((file) => JSON.stringify(file) === jpath)) { - newFiles.push(path); - } - return newFiles; - }); - setLastPath(path); - }, - [setFiles, setLastPath] - ); - - useEffect(() => { - if (files && lastPath) { - cache.localStorageSet( - StorageDomain, - { - type: StorageType.Files, - }, - { files, lastPath } - ); - } - }, [files, lastPath, cache]); - - const openFile = useCallback( - (path, code) => { - setPath(path); - addToFiles(path); - setMetadata(undefined); - setRenderCode(null); - if (code !== undefined) { - updateCode(path, code); - } else { - setLoading(true); - cache - .asyncLocalStorageGet(StorageDomain, { - path, - type: StorageType.Code, - }) - .then(({ code }) => { - updateCode(path, code); - }) - .finally(() => { - setLoading(false); - }); - } - }, - [updateCode, addToFiles] - ); - - const toPath = useCallback((type, nameOrPath) => { - const name = - nameOrPath.indexOf("/") >= 0 - ? nameOrPath.split("/").slice(2).join("/") - : nameOrPath; - return { type, name }; - }, []); - - const loadFile = useCallback( - (nameOrPath) => { - if (!near) { - return; - } - const widgetSrc = - nameOrPath.indexOf("/") >= 0 - ? nameOrPath - : `${accountId}/widget/${nameOrPath}`; - const c = () => { - const code = cache.socialGet( - near, - widgetSrc, - false, - undefined, - undefined, - c - ); - if (code) { - const name = widgetSrc.split("/").slice(2).join("/"); - openFile(toPath(Filetype.Widget, widgetSrc), code); - } - }; - - c(); - }, - [accountId, openFile, toPath, near, cache] - ); - - const generateNewName = useCallback( - (type) => { - for (let i = 0; ; i++) { - const name = `Draft-${i}`; - const path = toPath(type, name); - path.unnamed = true; - const jPath = JSON.stringify(path); - if (!files?.find((file) => JSON.stringify(file) === jPath)) { - return path; - } - } - }, - [toPath, files] - ); - - const createFile = useCallback( - (type) => { - const path = generateNewName(type); - openFile(path, DefaultEditorCode); - }, - [generateNewName, openFile] - ); - - const renameFile = useCallback( - (newName, code) => { - const newPath = toPath(path.type, newName); - const jNewPath = JSON.stringify(newPath); - const jPath = JSON.stringify(path); - setFiles((files) => { - const newFiles = files.filter( - (file) => JSON.stringify(file) !== jNewPath - ); - const i = newFiles.findIndex((file) => JSON.stringify(file) === jPath); - if (i >= 0) { - newFiles[i] = newPath; - } - return newFiles; - }); - setLastPath(newPath); - setPath(newPath); - updateCode(newPath, code); - }, - [path, toPath, updateCode] - ); - - useEffect(() => { - cache - .asyncLocalStorageGet(StorageDomain, { type: StorageType.Files }) - .then((value) => { - const { files, lastPath } = value || {}; - setFiles(files || []); - setLastPath(lastPath); - }); - }, [cache]); - - useEffect(() => { - if (!near || !files) { - return; - } - if (widgetSrc) { - if (widgetSrc === "new") { - createFile(Filetype.Widget); - } else { - loadFile(widgetSrc); - } - analytics("edit", { - props: { - widget: widgetSrc, - }, - }); - history.replace(`/edit/`); - } else if (path === undefined) { - if (files.length === 0) { - createFile(Filetype.Widget); - } else { - openFile(lastPath, undefined); - } - } - }, [near, createFile, lastPath, files, path, widgetSrc, openFile, loadFile]); - - const reformat = useCallback( - (path, code) => { - try { - const formattedCode = prettier.format(code, { - parser: "babel", - plugins: [parserBabel], - }); - updateCode(path, formattedCode); - } catch (e) { - console.log(e); - } - }, - [updateCode] - ); - - const reformatProps = useCallback( - (props) => { - try { - const formattedProps = JSON.stringify(JSON.parse(props), null, 2); - setWidgetProps(formattedProps); - } catch (e) { - console.log(e); - } - }, - [setWidgetProps] - ); - - const layoutClass = layout === Layout.Split ? "col-lg-6" : ""; - - const onLayoutChange = useCallback( - (e) => { - const layout = e.target.value; - if (layout === Layout.Split && tab === Tab.Widget) { - setTab(Tab.Editor); - } - setLayout(layout); - }, - [setLayout, tab, setTab] - ); - - const widgetName = path?.name; - - const commitButton = ( - - Save Widget - - ); - - const widgetPath = `${accountId}/${path?.type}/${path?.name}`; - const jpath = JSON.stringify(path); - - return ( -
- renameFile(newName, code)} - onHide={() => setShowRenameModal(false)} - /> - loadFile(newName)} - onNew={(newName) => - newName - ? openFile(toPath(Filetype.Widget, newName), DefaultEditorCode) - : createFile(Filetype.Widget) - } - onHide={() => setShowOpenModal(false)} - /> -
- - {props.widgets.editorComponentSearch && ( -
- ({ - extraButtons: ({ widgetName, widgetPath, onHide }) => ( - - Open "{widgetName}" component in the editor - - } - > - - - ), - }), - [loadFile] - )} - /> -
- )} -
-
-
-
- - - - - -
-
-
-
-
-
    -
  • - -
  • -
  • - -
  • - {props.widgets.widgetMetadataEditor && ( -
  • - -
  • - )} - {layout === Layout.Tabs && ( -
  • - -
  • - )} -
- -
-
- updateCode(path, code)} - wrapperProps={{ - onBlur: () => reformat(path, code), - }} - /> -
-
- - {!path?.unnamed && commitButton} - - {path && accountId && ( - - Open Component in a new tab - - )} -
-
-
-
- setWidgetProps(props)} - wrapperProps={{ - onBlur: () => reformatProps(widgetProps), - }} - /> -
-
^^ Props for debugging (in JSON)
- {propsError && ( -
{propsError}
- )} -
-
-
- ({ - widgetPath, - onChange: setMetadata, - }), - [widgetPath] - )} - /> -
-
{commitButton}
-
-
-
-
-
-
- {renderCode ? ( - - ) : ( - 'Click "Render preview" button to render the widget' - )} -
-
-
-
-
-
-
-
- ({ metadata, accountId, widgetName }), - [metadata, accountId, widgetName] - )} - /> -
-
-
-
-
-
-
-
- ); -} diff --git a/src/pages/EmbedPage.js b/src/pages/EmbedPage.js deleted file mode 100644 index 25ff1de..0000000 --- a/src/pages/EmbedPage.js +++ /dev/null @@ -1,35 +0,0 @@ -import React, { useEffect, useState } from "react"; -import { Widget } from "near-social-vm"; -import { useParams } from "react-router-dom"; -import { useQuery } from "../hooks/useQuery"; - -export default function EmbedPage(props) { - const { widgetSrc } = useParams(); - const query = useQuery(); - const [widgetProps, setWidgetProps] = useState({}); - - const src = widgetSrc || props.widgets.default; - - useEffect(() => { - setWidgetProps( - [...query.entries()].reduce((props, [key, value]) => { - props[key] = value; - return props; - }, {}) - ); - }, [query]); - - useEffect(() => { - analytics("embed", { - props: { - widget: src, - }, - }); - }, [src]); - - return ( -
- {" "} -
- ); -} diff --git a/src/pages/ViewPage.js b/src/pages/ViewPage.js deleted file mode 100644 index 99b0b2b..0000000 --- a/src/pages/ViewPage.js +++ /dev/null @@ -1,55 +0,0 @@ -import React, { useEffect, useState } from "react"; -import { Widget } from "near-social-vm"; -import { useParams } from "react-router-dom"; -import { useQuery } from "../hooks/useQuery"; - -export default function ViewPage(props) { - const { widgetSrc } = useParams(); - const query = useQuery(); - const [widgetProps, setWidgetProps] = useState({}); - - const src = widgetSrc || props.widgets.default; - const setWidgetSrc = props.setWidgetSrc; - const viewSourceWidget = props.widgets.viewSource; - - useEffect(() => { - setWidgetProps(Object.fromEntries([...query.entries()])); - }, [query]); - - useEffect(() => { - setTimeout(() => { - setWidgetSrc( - src === viewSourceWidget && query.get("src") - ? { - edit: query.get("src"), - view: null, - } - : { - edit: src, - view: src, - } - ); - analytics("view", { - props: { - widget: src, - }, - }); - }, 1); - }, [src, query, setWidgetSrc, viewSourceWidget]); - - return ( -
-
-
- {" "} -
-
-
- ); -} diff --git a/webpack.config.js b/webpack.config.js index a76ed54..d018c03 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,14 +1,11 @@ const webpack = require("webpack"); const paths = require("./config/paths"); const path = require("path"); -const ManifestPlugin = require("webpack-manifest-plugin"); const { CleanWebpackPlugin } = require("clean-webpack-plugin"); -const HTMLWebpackPlugin = require("html-webpack-plugin"); -const CopyWebpackPlugin = require("copy-webpack-plugin"); const { merge } = require("webpack-merge"); const loadPreset = require("./config/presets/loadPreset"); -const { WebpackManifestPlugin } = require("webpack-manifest-plugin"); const loadConfig = (mode) => require(`./config/webpack.${mode}.js`)(mode); +const nodeExternals = require("webpack-node-externals"); module.exports = function (env) { const { mode = "production" } = env || {}; @@ -18,9 +15,26 @@ module.exports = function (env) { entry: `${paths.srcPath}/index.js`, output: { path: paths.distPath, - filename: "[name].bundle.js", - publicPath: "/", + filename: "index.js", + libraryTarget: "umd", }, + externals: [ + nodeExternals(), + { + react: { + commonjs: "react", + commonjs2: "react", + amd: "react", + root: "React", + }, + "react-dom": { + commonjs: "react-dom", + commonjs2: "react-dom", + amd: "react-dom", + root: "ReactDOM", + }, + }, + ], module: { rules: [ { @@ -45,56 +59,22 @@ module.exports = function (env) { modules: [paths.srcPath, "node_modules"], extensions: [".js", ".jsx", ".json"], fallback: { - // fs: false, - // path: require.resolve("path-browserify"), - // http: require.resolve("stream-http"), - // https: require.resolve("https-browserify"), - // zlib: require.resolve("browserify-zlib"), crypto: require.resolve("crypto-browserify"), stream: require.resolve("stream-browserify"), }, - alias: - mode === "production" - ? {} - : { - react: path.join(__dirname, "node_modules/react"), - "react-dom": path.join(__dirname, "node_modules/react-dom"), - "styled-components": path.join( - __dirname, - "node_modules/styled-components" - ), - }, }, + target: "node", plugins: [ - new webpack.EnvironmentPlugin({ - // Configure environment variables here. - ENVIRONMENT: "browser", - }), + // new webpack.EnvironmentPlugin({ + // // Configure environment variables here. + // ENVIRONMENT: "browser", + // }), new CleanWebpackPlugin(), - // Copies files from target to destination folder - new CopyWebpackPlugin({ - patterns: [ - { - from: paths.publicPath, - to: "assets", - globOptions: { - ignore: ["*.DS_Store"], - }, - noErrorOnMissing: true, - }, - ], - }), - new HTMLWebpackPlugin({ - template: `${paths.publicPath}/index.html`, - favicon: `${paths.publicPath}/favicon.png`, - robots: `${paths.publicPath}/robots.txt`, - }), new webpack.ProgressPlugin(), new webpack.ProvidePlugin({ process: "process/browser", Buffer: [require.resolve("buffer/"), "Buffer"], }), - new ManifestPlugin.WebpackManifestPlugin(), ], }, loadConfig(mode),