commit
134abbeba0
@ -1,10 +0,0 @@ |
||||
'use strict' |
||||
|
||||
// require('@babel/polyfill')
|
||||
var App = require('./app.js') |
||||
|
||||
var app = new App({}) |
||||
|
||||
document.body.appendChild(app.render()) |
||||
|
||||
app.init() // @TODO: refactor to remove
|
@ -0,0 +1,16 @@ |
||||
// eslint-disable-next-line no-use-before-define
|
||||
import React from 'react' |
||||
import ReactDOM from 'react-dom' |
||||
import AppComponent from './app' |
||||
// eslint-disable-next-line no-unused-vars
|
||||
import { RemixApp } from '@remix-ui/app' |
||||
|
||||
const appComponent = new AppComponent() |
||||
appComponent.run() |
||||
|
||||
ReactDOM.render( |
||||
<React.StrictMode> |
||||
<RemixApp app={appComponent}></RemixApp> |
||||
</React.StrictMode>, |
||||
document.getElementById('root') |
||||
) |
@ -1,56 +1,66 @@ |
||||
import { Plugin } from '@remixproject/engine' |
||||
import * as packageJson from '../../../package.json' |
||||
const introJs = require('intro.js') |
||||
|
||||
export class WalkthroughService { |
||||
constructor (params) { |
||||
this.params = params |
||||
} |
||||
const profile = { |
||||
name: 'walkthrough', |
||||
displayName: 'Walkthrough', |
||||
description: '', |
||||
version: packageJson.version, |
||||
methods: ['start'] |
||||
} |
||||
|
||||
start (params) { |
||||
document.addEventListener('doWalkThrough', (e) => { |
||||
if (!localStorage.getItem('hadTour_initial')) { |
||||
introJs().setOptions({ |
||||
steps: [{ |
||||
title: 'Welcome to Remix IDE', |
||||
intro: 'Click to launch the Home tab that contains links, tips, and shortcuts..', |
||||
element: document.querySelector('#verticalIconsHomeIcon'), |
||||
tooltipClass: 'bg-light text-dark', |
||||
position: 'right' |
||||
}, |
||||
{ |
||||
element: document.querySelector('#compileIcons'), |
||||
title: 'Solidity Compiler', |
||||
intro: 'Having selected a .sol file in the File Explorers (the icon above), compile it with the Solidity Compiler.', |
||||
tooltipClass: 'bg-light text-dark', |
||||
position: 'right' |
||||
}, |
||||
{ |
||||
title: 'Deploy your contract', |
||||
element: document.querySelector('#verticalIconsKindudapp'), |
||||
intro: 'Choose a chain, deploy a contract and play with your functions.', |
||||
tooltipClass: 'bg-light text-dark', |
||||
position: 'right' |
||||
} |
||||
] |
||||
}).onafterchange((targetElement) => { |
||||
const header = document.getElementsByClassName('introjs-tooltip-header')[0] |
||||
if (header) { |
||||
header.classList.add('d-flex') |
||||
header.classList.add('justify-content-between') |
||||
header.classList.add('text-nowrap') |
||||
header.classList.add('pr-0') |
||||
} |
||||
const skipbutton = document.getElementsByClassName('introjs-skipbutton')[0] |
||||
if (skipbutton) { |
||||
skipbutton.classList.add('ml-3') |
||||
skipbutton.classList.add('text-decoration-none') |
||||
skipbutton.id = 'remixTourSkipbtn' |
||||
} |
||||
}).start() |
||||
localStorage.setItem('hadTour_initial', true) |
||||
export class WalkthroughService extends Plugin { |
||||
constructor (appManager, showMatamo) { |
||||
super(profile) |
||||
appManager.event.on('activate', (plugin) => { |
||||
if (plugin.name === 'udapp' && !showMatamo) { |
||||
this.start() |
||||
} |
||||
}) |
||||
} |
||||
|
||||
startFeatureTour () { |
||||
start () { |
||||
if (!localStorage.getItem('hadTour_initial')) { |
||||
introJs().setOptions({ |
||||
steps: [{ |
||||
title: 'Welcome to Remix IDE', |
||||
intro: 'Click to launch the Home tab that contains links, tips, and shortcuts..', |
||||
element: document.querySelector('#verticalIconsHomeIcon'), |
||||
tooltipClass: 'bg-light text-dark', |
||||
position: 'right' |
||||
}, |
||||
{ |
||||
element: document.querySelector('#compileIcons'), |
||||
title: 'Solidity Compiler', |
||||
intro: 'Having selected a .sol file in the File Explorers (the icon above), compile it with the Solidity Compiler.', |
||||
tooltipClass: 'bg-light text-dark', |
||||
position: 'right' |
||||
}, |
||||
{ |
||||
title: 'Deploy your contract', |
||||
element: document.querySelector('#verticalIconsKindudapp'), |
||||
intro: 'Choose a chain, deploy a contract and play with your functions.', |
||||
tooltipClass: 'bg-light text-dark', |
||||
position: 'right' |
||||
} |
||||
] |
||||
}).onafterchange((targetElement) => { |
||||
const header = document.getElementsByClassName('introjs-tooltip-header')[0] |
||||
if (header) { |
||||
header.classList.add('d-flex') |
||||
header.classList.add('justify-content-between') |
||||
header.classList.add('text-nowrap') |
||||
header.classList.add('pr-0') |
||||
} |
||||
const skipbutton = document.getElementsByClassName('introjs-skipbutton')[0] |
||||
if (skipbutton) { |
||||
skipbutton.classList.add('ml-3') |
||||
skipbutton.classList.add('text-decoration-none') |
||||
skipbutton.id = 'remixTourSkipbtn' |
||||
} |
||||
}).start() |
||||
localStorage.setItem('hadTour_initial', true) |
||||
} |
||||
} |
||||
} |
||||
|
@ -0,0 +1,4 @@ |
||||
{ |
||||
"presets": ["@nrwl/react/babel"], |
||||
"plugins": [] |
||||
} |
@ -0,0 +1,248 @@ |
||||
{ |
||||
"rules": { |
||||
"array-callback-return": "warn", |
||||
"dot-location": ["warn", "property"], |
||||
"eqeqeq": ["warn", "smart"], |
||||
"new-parens": "warn", |
||||
"no-caller": "warn", |
||||
"no-cond-assign": ["warn", "except-parens"], |
||||
"no-const-assign": "warn", |
||||
"no-control-regex": "warn", |
||||
"no-delete-var": "warn", |
||||
"no-dupe-args": "warn", |
||||
"no-dupe-keys": "warn", |
||||
"no-duplicate-case": "warn", |
||||
"no-empty-character-class": "warn", |
||||
"no-empty-pattern": "warn", |
||||
"no-eval": "warn", |
||||
"no-ex-assign": "warn", |
||||
"no-extend-native": "warn", |
||||
"no-extra-bind": "warn", |
||||
"no-extra-label": "warn", |
||||
"no-fallthrough": "warn", |
||||
"no-func-assign": "warn", |
||||
"no-implied-eval": "warn", |
||||
"no-invalid-regexp": "warn", |
||||
"no-iterator": "warn", |
||||
"no-label-var": "warn", |
||||
"no-labels": ["warn", { "allowLoop": true, "allowSwitch": false }], |
||||
"no-lone-blocks": "warn", |
||||
"no-loop-func": "warn", |
||||
"no-mixed-operators": [ |
||||
"warn", |
||||
{ |
||||
"groups": [ |
||||
["&", "|", "^", "~", "<<", ">>", ">>>"], |
||||
["==", "!=", "===", "!==", ">", ">=", "<", "<="], |
||||
["&&", "||"], |
||||
["in", "instanceof"] |
||||
], |
||||
"allowSamePrecedence": false |
||||
} |
||||
], |
||||
"no-multi-str": "warn", |
||||
"no-native-reassign": "warn", |
||||
"no-negated-in-lhs": "warn", |
||||
"no-new-func": "warn", |
||||
"no-new-object": "warn", |
||||
"no-new-symbol": "warn", |
||||
"no-new-wrappers": "warn", |
||||
"no-obj-calls": "warn", |
||||
"no-octal": "warn", |
||||
"no-octal-escape": "warn", |
||||
"no-redeclare": "warn", |
||||
"no-regex-spaces": "warn", |
||||
"no-restricted-syntax": ["warn", "WithStatement"], |
||||
"no-script-url": "warn", |
||||
"no-self-assign": "warn", |
||||
"no-self-compare": "warn", |
||||
"no-sequences": "warn", |
||||
"no-shadow-restricted-names": "warn", |
||||
"no-sparse-arrays": "warn", |
||||
"no-template-curly-in-string": "warn", |
||||
"no-this-before-super": "warn", |
||||
"no-throw-literal": "warn", |
||||
"no-restricted-globals": [ |
||||
"error", |
||||
"addEventListener", |
||||
"blur", |
||||
"close", |
||||
"closed", |
||||
"confirm", |
||||
"defaultStatus", |
||||
"defaultstatus", |
||||
"event", |
||||
"external", |
||||
"find", |
||||
"focus", |
||||
"frameElement", |
||||
"frames", |
||||
"history", |
||||
"innerHeight", |
||||
"innerWidth", |
||||
"length", |
||||
"location", |
||||
"locationbar", |
||||
"menubar", |
||||
"moveBy", |
||||
"moveTo", |
||||
"name", |
||||
"onblur", |
||||
"onerror", |
||||
"onfocus", |
||||
"onload", |
||||
"onresize", |
||||
"onunload", |
||||
"open", |
||||
"opener", |
||||
"opera", |
||||
"outerHeight", |
||||
"outerWidth", |
||||
"pageXOffset", |
||||
"pageYOffset", |
||||
"parent", |
||||
"print", |
||||
"removeEventListener", |
||||
"resizeBy", |
||||
"resizeTo", |
||||
"screen", |
||||
"screenLeft", |
||||
"screenTop", |
||||
"screenX", |
||||
"screenY", |
||||
"scroll", |
||||
"scrollbars", |
||||
"scrollBy", |
||||
"scrollTo", |
||||
"scrollX", |
||||
"scrollY", |
||||
"self", |
||||
"status", |
||||
"statusbar", |
||||
"stop", |
||||
"toolbar", |
||||
"top" |
||||
], |
||||
"no-unexpected-multiline": "warn", |
||||
"no-unreachable": "warn", |
||||
"no-unused-expressions": [ |
||||
"error", |
||||
{ |
||||
"allowShortCircuit": true, |
||||
"allowTernary": true, |
||||
"allowTaggedTemplates": true |
||||
} |
||||
], |
||||
"no-unused-labels": "warn", |
||||
"no-useless-computed-key": "warn", |
||||
"no-useless-concat": "warn", |
||||
"no-useless-escape": "warn", |
||||
"no-useless-rename": [ |
||||
"warn", |
||||
{ |
||||
"ignoreDestructuring": false, |
||||
"ignoreImport": false, |
||||
"ignoreExport": false |
||||
} |
||||
], |
||||
"no-with": "warn", |
||||
"no-whitespace-before-property": "warn", |
||||
"react-hooks/exhaustive-deps": "warn", |
||||
"require-yield": "warn", |
||||
"rest-spread-spacing": ["warn", "never"], |
||||
"strict": ["warn", "never"], |
||||
"unicode-bom": ["warn", "never"], |
||||
"use-isnan": "warn", |
||||
"valid-typeof": "warn", |
||||
"no-restricted-properties": [ |
||||
"error", |
||||
{ |
||||
"object": "require", |
||||
"property": "ensure", |
||||
"message": "Please use import() instead. More info: https://facebook.github.io/create-react-app/docs/code-splitting" |
||||
}, |
||||
{ |
||||
"object": "System", |
||||
"property": "import", |
||||
"message": "Please use import() instead. More info: https://facebook.github.io/create-react-app/docs/code-splitting" |
||||
} |
||||
], |
||||
"getter-return": "warn", |
||||
"import/first": "error", |
||||
"import/no-amd": "error", |
||||
"import/no-webpack-loader-syntax": "error", |
||||
"react/forbid-foreign-prop-types": ["warn", { "allowInPropTypes": true }], |
||||
"react/jsx-no-comment-textnodes": "warn", |
||||
"react/jsx-no-duplicate-props": "warn", |
||||
"react/jsx-no-target-blank": "warn", |
||||
"react/jsx-no-undef": "error", |
||||
"react/jsx-pascal-case": ["warn", { "allowAllCaps": true, "ignore": [] }], |
||||
"react/jsx-uses-react": "warn", |
||||
"react/jsx-uses-vars": "warn", |
||||
"react/no-danger-with-children": "warn", |
||||
"react/no-direct-mutation-state": "warn", |
||||
"react/no-is-mounted": "warn", |
||||
"react/no-typos": "error", |
||||
"react/react-in-jsx-scope": "error", |
||||
"react/require-render-return": "error", |
||||
"react/style-prop-object": "warn", |
||||
"react/jsx-no-useless-fragment": "warn", |
||||
"jsx-a11y/accessible-emoji": "warn", |
||||
"jsx-a11y/alt-text": "warn", |
||||
"jsx-a11y/anchor-has-content": "warn", |
||||
"jsx-a11y/anchor-is-valid": [ |
||||
"warn", |
||||
{ "aspects": ["noHref", "invalidHref"] } |
||||
], |
||||
"jsx-a11y/aria-activedescendant-has-tabindex": "warn", |
||||
"jsx-a11y/aria-props": "warn", |
||||
"jsx-a11y/aria-proptypes": "warn", |
||||
"jsx-a11y/aria-role": "warn", |
||||
"jsx-a11y/aria-unsupported-elements": "warn", |
||||
"jsx-a11y/heading-has-content": "warn", |
||||
"jsx-a11y/iframe-has-title": "warn", |
||||
"jsx-a11y/img-redundant-alt": "warn", |
||||
"jsx-a11y/no-access-key": "warn", |
||||
"jsx-a11y/no-distracting-elements": "warn", |
||||
"jsx-a11y/no-redundant-roles": "warn", |
||||
"jsx-a11y/role-has-required-aria-props": "warn", |
||||
"jsx-a11y/role-supports-aria-props": "warn", |
||||
"jsx-a11y/scope": "warn", |
||||
"react-hooks/rules-of-hooks": "error", |
||||
"default-case": "off", |
||||
"no-dupe-class-members": "off", |
||||
"no-undef": "off", |
||||
"@typescript-eslint/consistent-type-assertions": "warn", |
||||
"no-array-constructor": "off", |
||||
"@typescript-eslint/no-array-constructor": "warn", |
||||
"@typescript-eslint/no-namespace": "error", |
||||
"no-use-before-define": "off", |
||||
"@typescript-eslint/no-use-before-define": [ |
||||
"warn", |
||||
{ |
||||
"functions": false, |
||||
"classes": false, |
||||
"variables": false, |
||||
"typedefs": false |
||||
} |
||||
], |
||||
"no-unused-vars": "off", |
||||
"@typescript-eslint/no-unused-vars": [ |
||||
"warn", |
||||
{ "args": "none", "ignoreRestSiblings": true } |
||||
], |
||||
"no-useless-constructor": "off", |
||||
"@typescript-eslint/no-useless-constructor": "warn" |
||||
}, |
||||
"env": { |
||||
"browser": true, |
||||
"commonjs": true, |
||||
"es6": true, |
||||
"jest": true, |
||||
"node": true |
||||
}, |
||||
"settings": { "react": { "version": "detect" } }, |
||||
"plugins": ["import", "jsx-a11y", "react", "react-hooks"], |
||||
"extends": ["../../../.eslintrc"], |
||||
"ignorePatterns": ["!**/*"] |
||||
} |
@ -0,0 +1 @@ |
||||
export { default as RemixApp } from './lib/remix-app/remix-app' |
@ -0,0 +1,5 @@ |
||||
import React from 'react' |
||||
|
||||
const AppContext = React.createContext(null) |
||||
|
||||
export default AppContext |
@ -0,0 +1,26 @@ |
||||
/* dragbar UI */ |
||||
|
||||
.dragbar { |
||||
display : block; |
||||
height : 100%; |
||||
position : absolute; |
||||
left: 0px; |
||||
top: 0px; |
||||
width: 0.3em; |
||||
z-index: 9999; |
||||
} |
||||
|
||||
.overlay { |
||||
position: absolute; |
||||
left: 0; |
||||
top: 0; |
||||
width: 100vw; |
||||
height: 100vh; |
||||
display: block; |
||||
z-index: 9998; |
||||
} |
||||
|
||||
.dragbar:hover, .dragbar.ondrag{ |
||||
background-color: var(--secondary); |
||||
cursor:col-resize; |
||||
} |
@ -0,0 +1,53 @@ |
||||
import React, { useEffect, useState } from 'react' |
||||
import Draggable from 'react-draggable' |
||||
import './dragbar.css' |
||||
|
||||
interface IRemixDragBarUi { |
||||
refObject: React.MutableRefObject<any>; |
||||
setHideStatus: (hide: boolean) => void; |
||||
hidden: boolean |
||||
minWidth: number |
||||
} |
||||
|
||||
const DragBar = (props: IRemixDragBarUi) => { |
||||
const [dragState, setDragState] = useState<boolean>(false) |
||||
const [dragBarPosX, setDragBarPosX] = useState<number>(0) |
||||
const [offset, setOffSet] = useState<number>(0) |
||||
const nodeRef = React.useRef(null) // fix for strictmode
|
||||
|
||||
useEffect(() => { |
||||
// arbitrary time out to wait the the UI to be completely done
|
||||
setTimeout(() => { |
||||
setOffSet(props.refObject.current.offsetLeft) |
||||
setDragBarPosX(offset + props.refObject.current.offsetWidth) |
||||
}, 1000) |
||||
}, []) |
||||
|
||||
useEffect(() => { |
||||
setDragBarPosX(offset + (props.hidden ? 0 : props.refObject.current.offsetWidth)) |
||||
}, [props.hidden, offset]) |
||||
|
||||
function stopDrag (e: MouseEvent, data: any) { |
||||
setDragState(false) |
||||
if (data.x < props.minWidth) { |
||||
setDragBarPosX(offset) |
||||
props.setHideStatus(true) |
||||
} else { |
||||
props.refObject.current.style.width = (data.x - offset) + 'px' |
||||
props.setHideStatus(false) |
||||
setDragBarPosX(offset + props.refObject.current.offsetWidth) |
||||
} |
||||
} |
||||
|
||||
function startDrag () { |
||||
setDragState(true) |
||||
} |
||||
return <> |
||||
<div className={`overlay ${dragState ? '' : 'd-none'}`} ></div> |
||||
<Draggable nodeRef={nodeRef} position={{ x: dragBarPosX, y: 0 }} onStart={startDrag} onStop={stopDrag} axis="x"> |
||||
<div ref={nodeRef} className={`dragbar ${dragState ? 'ondrag' : ''}`}></div> |
||||
</Draggable> |
||||
</> |
||||
} |
||||
|
||||
export default DragBar |
@ -0,0 +1,43 @@ |
||||
import React, { useEffect, useState } from 'react' |
||||
import { ModalDialog } from '@remix-ui/modal-dialog' |
||||
|
||||
const AlertModal = () => { |
||||
const [visible, setVisible] = useState<boolean>(true) |
||||
const [content, setContent] = useState<string>('') |
||||
|
||||
useEffect(() => { |
||||
// check the origin and warn message
|
||||
if (window.location.hostname === 'yann300.github.io') { |
||||
setContent('This UNSTABLE ALPHA branch of Remix has been moved to http://ethereum.github.io/remix-live-alpha.') |
||||
} else if (window.location.hostname === 'remix-alpha.ethereum.org' || |
||||
(window.location.hostname === 'ethereum.github.io' && window.location.pathname.indexOf('/remix-live-alpha') === 0)) { |
||||
setContent('Welcome to the Remix alpha instance. Please use it to try out latest features. But use preferably https://remix.ethereum.org for any production work.') |
||||
} else if (window.location.protocol.indexOf('http') === 0 && |
||||
window.location.hostname !== 'remix.ethereum.org' && |
||||
window.location.hostname !== 'localhost' && |
||||
window.location.hostname !== '127.0.0.1') { |
||||
setContent(`The Remix IDE has moved to http://remix.ethereum.org.\n
|
||||
This instance of Remix you are visiting WILL NOT BE UPDATED.\n |
||||
Please make a backup of your contracts and start using http://remix.ethereum.org`)
|
||||
} |
||||
setVisible(content !== '') |
||||
}, []) |
||||
|
||||
const closeModal = async () => { |
||||
setVisible(false) |
||||
} |
||||
const handleModalOkClick = async () => { |
||||
setVisible(false) |
||||
} |
||||
return (<ModalDialog |
||||
handleHide={closeModal} |
||||
id="appAlert" |
||||
hide={!visible} |
||||
title="Alert" |
||||
okLabel="Ok" |
||||
okFn={ handleModalOkClick } |
||||
cancelLabel="" |
||||
cancelFn={closeModal}>{content}</ModalDialog>) |
||||
} |
||||
|
||||
export default AlertModal |
@ -0,0 +1,51 @@ |
||||
import React, { useContext, useEffect, useState } from 'react' |
||||
import { ModalDialog } from '@remix-ui/modal-dialog' |
||||
import AppContext from '../context/context' |
||||
const _paq = window._paq = window._paq || [] |
||||
|
||||
const MatomoDialog = (props) => { |
||||
const { settings, showMatamo, appManager } = useContext(AppContext) |
||||
const [visible, setVisible] = useState<boolean>(props.hide) |
||||
useEffect(() => { |
||||
if (showMatamo) { |
||||
setVisible(true) |
||||
} else { |
||||
setVisible(false) |
||||
} |
||||
}, []) |
||||
const declineModal = async () => { |
||||
settings.updateMatomoAnalyticsChoice(false) |
||||
_paq.push(['optUserOut']) |
||||
appManager.call('walkthrough', 'start') |
||||
setVisible(false) |
||||
} |
||||
const hideModal = async () => { |
||||
setVisible(false) |
||||
} |
||||
const handleModalOkClick = async () => { |
||||
_paq.push(['forgetUserOptOut']) |
||||
// @TODO remove next line when https://github.com/matomo-org/matomo/commit/9e10a150585522ca30ecdd275007a882a70c6df5 is used
|
||||
document.cookie = 'mtm_consent_removed=; expires=Thu, 01 Jan 1970 00:00:01 GMT;' |
||||
settings.updateMatomoAnalyticsChoice(true) |
||||
appManager.call('walkthrough', 'start') |
||||
setVisible(false) |
||||
} |
||||
return (<ModalDialog |
||||
handleHide={hideModal} |
||||
id="matomoDialog" |
||||
hide={!visible} |
||||
title="Help us to improve Remix IDE" |
||||
okLabel="Accept" |
||||
okFn={ handleModalOkClick } |
||||
cancelLabel="Decline" |
||||
cancelFn={declineModal}> |
||||
<p>An Opt-in version of <a href="https://matomo.org" target="_blank" rel="noreferrer">Matomo</a>, an open source data analytics platform is being used to improve Remix IDE.</p> |
||||
<p>We realize that our users have sensitive information in their code and that their privacy - your privacy - must be protected.</p> |
||||
<p>All data collected through Matomo is stored on our own server - no data is ever given to third parties. Our analytics reports are public: <a href="https://matomo.ethereum.org/index.php?module=MultiSites&action=index&idSite=23&period=day&date=yesterday" target="_blank" rel="noreferrer">take a look</a>.</p> |
||||
<p>We do not collect nor store any personally identifiable information (PII).</p> |
||||
<p>For more info, see: <a href="https://medium.com/p/66ef69e14931/" target="_blank" rel="noreferrer">Matomo Analyitcs on Remix iDE</a>.</p> |
||||
<p>You can change your choice in the Settings panel anytime.</p> |
||||
</ModalDialog>) |
||||
} |
||||
|
||||
export default MatomoDialog |
@ -0,0 +1,16 @@ |
||||
import React from 'react' |
||||
|
||||
const RemixSplashScreen = (props) => { |
||||
return (<> <div style={{ display: props.hide ? 'none' : 'block' }} className='centered'> |
||||
<svg id="Ebene_2" data-name="Ebene 2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 105 100"> |
||||
<path d="M91.84,35a.09.09,0,0,1-.1-.07,41,41,0,0,0-79.48,0,.09.09,0,0,1-.1.07C9.45,35,1,35.35,1,42.53c0,8.56,1,16,6,20.32,2.16,1.85,5.81,2.3,9.27,2.22a44.4,44.4,0,0,0,6.45-.68.09.09,0,0,0,.06-.15A34.81,34.81,0,0,1,17,45c0-.1,0-.21,0-.31a35,35,0,0,1,70,0c0,.1,0,.21,0,.31a34.81,34.81,0,0,1-5.78,19.24.09.09,0,0,0,.06.15,44.4,44.4,0,0,0,6.45.68c3.46.08,7.11-.37,9.27-2.22,5-4.27,6-11.76,6-20.32C103,35.35,94.55,35,91.84,35Z"/> |
||||
<path d="M52,74,25.4,65.13a.1.1,0,0,0-.1.17L51.93,91.93a.1.1,0,0,0,.14,0L78.7,65.3a.1.1,0,0,0-.1-.17L52,74A.06.06,0,0,1,52,74Z"/> |
||||
<path d="M75.68,46.9,82,45a.09.09,0,0,0,.08-.09,29.91,29.91,0,0,0-.87-6.94.11.11,0,0,0-.09-.08l-6.43-.58a.1.1,0,0,1-.06-.18l4.78-4.18a.13.13,0,0,0,0-.12,30.19,30.19,0,0,0-3.65-6.07.09.09,0,0,0-.11,0l-5.91,2a.1.1,0,0,1-.12-.14L72.19,23a.11.11,0,0,0,0-.12,29.86,29.86,0,0,0-5.84-4.13.09.09,0,0,0-.11,0l-4.47,4.13a.1.1,0,0,1-.17-.07l.09-6a.1.1,0,0,0-.07-.1,30.54,30.54,0,0,0-7-1.47.1.1,0,0,0-.1.07l-2.38,5.54a.1.1,0,0,1-.18,0l-2.37-5.54a.11.11,0,0,0-.11-.06,30,30,0,0,0-7,1.48.12.12,0,0,0-.07.1l.08,6.05a.09.09,0,0,1-.16.07L37.8,18.76a.11.11,0,0,0-.12,0,29.75,29.75,0,0,0-5.83,4.13.11.11,0,0,0,0,.12l2.59,5.6a.11.11,0,0,1-.13.14l-5.9-2a.11.11,0,0,0-.12,0,30.23,30.23,0,0,0-3.62,6.08.11.11,0,0,0,0,.12l4.79,4.19a.1.1,0,0,1-.06.17L23,37.91a.1.1,0,0,0-.09.07A29.9,29.9,0,0,0,22,44.92a.1.1,0,0,0,.07.1L28.4,47a.1.1,0,0,1,0,.18l-5.84,3.26a.16.16,0,0,0,0,.11,30.17,30.17,0,0,0,2.1,6.76c.32.71.67,1.4,1,2.08a.1.1,0,0,0,.06,0L52,68.16H52l26.34-8.78a.1.1,0,0,0,.06-.05,30.48,30.48,0,0,0,3.11-8.88.1.1,0,0,0-.05-.11l-5.83-3.26A.1.1,0,0,1,75.68,46.9Z"/> |
||||
</svg> |
||||
<div className="info-secondary splash"> |
||||
REMIX IDE |
||||
</div> |
||||
</div></>) |
||||
} |
||||
|
||||
export default RemixSplashScreen |
@ -0,0 +1,90 @@ |
||||
import React, { useContext, useEffect, useRef, useState } from 'react' |
||||
import './style/remix-app.css' |
||||
import RemixSplashScreen from './modals/splashscreen' |
||||
import MatomoDialog from './modals/matomo' |
||||
import AlertModal from './modals/alert' |
||||
import AppContext from './context/context' |
||||
import DragBar from './dragbar/dragbar' |
||||
interface IRemixAppUi { |
||||
app: any |
||||
} |
||||
|
||||
const RemixApp = (props: IRemixAppUi) => { |
||||
const [appReady, setAppReady] = useState<boolean>(false) |
||||
const [hideSidePanel, setHideSidePanel] = useState<boolean>(false) |
||||
const sidePanelRef = useRef(null) |
||||
const mainPanelRef = useRef(null) |
||||
const iconPanelRef = useRef(null) |
||||
const hiddenPanelRef = useRef(null) |
||||
|
||||
useEffect(() => { |
||||
if (sidePanelRef.current) { |
||||
if (props.app.sidePanel) { |
||||
sidePanelRef.current.appendChild(props.app.sidePanel.render()) |
||||
} |
||||
} |
||||
if (mainPanelRef.current) { |
||||
if (props.app.mainview) { |
||||
mainPanelRef.current.appendChild(props.app.mainview.render()) |
||||
} |
||||
} |
||||
if (iconPanelRef.current) { |
||||
if (props.app.menuicons) { |
||||
iconPanelRef.current.appendChild(props.app.menuicons.render()) |
||||
} |
||||
} |
||||
if (hiddenPanelRef.current) { |
||||
if (props.app.hiddenPanel) { |
||||
hiddenPanelRef.current.appendChild(props.app.hiddenPanel.render()) |
||||
} |
||||
} |
||||
async function activateApp () { |
||||
props.app.themeModule.initTheme(() => { |
||||
setAppReady(true) |
||||
props.app.activate() |
||||
setListeners() |
||||
}) |
||||
} |
||||
if (props.app) { |
||||
activateApp() |
||||
} |
||||
}, []) |
||||
|
||||
function setListeners () { |
||||
props.app.sidePanel.events.on('toggle', () => { |
||||
setHideSidePanel(prev => { |
||||
return !prev |
||||
}) |
||||
}) |
||||
props.app.sidePanel.events.on('showing', () => { |
||||
setHideSidePanel(false) |
||||
}) |
||||
} |
||||
|
||||
const components = { |
||||
iconPanel: <div ref={iconPanelRef} id="icon-panel" data-id="remixIdeIconPanel" className="iconpanel bg-light"></div>, |
||||
sidePanel: <div ref={sidePanelRef} id="side-panel" data-id="remixIdeSidePanel" className={`sidepanel border-right border-left ${hideSidePanel ? 'd-none' : ''}`}></div>, |
||||
mainPanel: <div ref={mainPanelRef} id="main-panel" data-id="remixIdeMainPanel" className='mainpanel'></div>, |
||||
hiddenPanel: <div ref={hiddenPanelRef}></div> |
||||
} |
||||
|
||||
return ( |
||||
<AppContext.Provider value={{ settings: props.app.settings, showMatamo: props.app.showMatamo, appManager: props.app.appManager }}> |
||||
<RemixSplashScreen hide={appReady}></RemixSplashScreen> |
||||
<AlertModal></AlertModal> |
||||
<MatomoDialog hide={!appReady}></MatomoDialog> |
||||
|
||||
<div className={`remixIDE ${appReady ? '' : 'd-none'}`} data-id="remixIDE"> |
||||
{components.iconPanel} |
||||
{components.sidePanel} |
||||
<DragBar minWidth={250} refObject={sidePanelRef} hidden={hideSidePanel} setHideStatus={setHideSidePanel}></DragBar> |
||||
{components.mainPanel} |
||||
|
||||
</div> |
||||
{components.hiddenPanel} |
||||
</AppContext.Provider> |
||||
|
||||
) |
||||
} |
||||
|
||||
export default RemixApp |
@ -0,0 +1,71 @@ |
||||
html { box-sizing: border-box; } |
||||
*, *:before, *:after { box-sizing: inherit; } |
||||
body { |
||||
/* font: 14px/1.5 Lato, "Helvetica Neue", Helvetica, Arial, sans-serif; */ |
||||
font-size : .8rem; |
||||
} |
||||
pre { |
||||
overflow-x: auto; |
||||
} |
||||
.remixIDE { |
||||
width : 100vw; |
||||
height : 100vh; |
||||
overflow : hidden; |
||||
flex-direction : row; |
||||
display : flex; |
||||
} |
||||
.mainpanel { |
||||
display : flex; |
||||
flex-direction : column; |
||||
overflow : hidden; |
||||
flex : 1; |
||||
min-width : 320px; |
||||
} |
||||
.iconpanel { |
||||
display : flex; |
||||
flex-direction : column; |
||||
overflow : hidden; |
||||
width : 50px; |
||||
user-select : none; |
||||
} |
||||
.sidepanel { |
||||
display : flex; |
||||
flex-direction : row-reverse; |
||||
width: 320px; |
||||
} |
||||
|
||||
.highlightcode { |
||||
position : absolute; |
||||
z-index : 20; |
||||
background-color : var(--info); |
||||
} |
||||
.highlightcode_fullLine { |
||||
position : absolute; |
||||
z-index : 20; |
||||
background-color : var(--info); |
||||
opacity : 0.5; |
||||
} |
||||
.centered { |
||||
position : fixed; |
||||
top : 20%; |
||||
left : 45%; |
||||
width : 200px; |
||||
height : 200px; |
||||
} |
||||
.centered svg path { |
||||
fill: var(--secondary); |
||||
} |
||||
.centered svg polygon { |
||||
fill : var(--secondary); |
||||
} |
||||
.onboarding { |
||||
color : var(--text-info); |
||||
background-color : var(--info); |
||||
} |
||||
.matomoBtn { |
||||
width : 100px; |
||||
} |
||||
|
||||
.splash { |
||||
text-align: center; |
||||
} |
@ -0,0 +1,19 @@ |
||||
{ |
||||
"extends": "../../../tsconfig.base.json", |
||||
"compilerOptions": { |
||||
"jsx": "react", |
||||
"allowJs": true, |
||||
"esModuleInterop": true, |
||||
"allowSyntheticDefaultImports": true |
||||
}, |
||||
"files": [], |
||||
"include": [], |
||||
"references": [ |
||||
{ |
||||
"path": "./tsconfig.lib.json" |
||||
}, |
||||
{ |
||||
"path": "./tsconfig.spec.json" |
||||
} |
||||
] |
||||
} |
@ -0,0 +1,13 @@ |
||||
{ |
||||
"extends": "./tsconfig.json", |
||||
"compilerOptions": { |
||||
"outDir": "../../../dist/out-tsc", |
||||
"types": ["node"] |
||||
}, |
||||
"files": [ |
||||
"../../../node_modules/@nrwl/react/typings/cssmodule.d.ts", |
||||
"../../../node_modules/@nrwl/react/typings/image.d.ts" |
||||
], |
||||
"exclude": ["**/*.spec.ts", "**/*.spec.tsx"], |
||||
"include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"] |
||||
} |
@ -0,0 +1,15 @@ |
||||
{ |
||||
"extends": "./tsconfig.json", |
||||
"compilerOptions": { |
||||
"outDir": "../../../dist/out-tsc", |
||||
"module": "commonjs", |
||||
"types": ["jest", "node"] |
||||
}, |
||||
"include": [ |
||||
"**/*.spec.ts", |
||||
"**/*.spec.tsx", |
||||
"**/*.spec.js", |
||||
"**/*.spec.jsx", |
||||
"**/*.d.ts" |
||||
] |
||||
} |
File diff suppressed because it is too large
Load Diff
Loading…
Reference in new issue