const path = props.path; // every piece of data on social contract has a path const blockHeight = props.blockHeight || "final"; // and a blockHeight (~version) // split the path const parts = path.split("/"); const creatorId = parts[0]; let type; if (parts.length === 1) { // every root of a path is an account type = "account"; } else { // otherwise the "standard" is the type (widget, post, type, thing...) // for thing, we'll extract the actual "Type" later type = parts[1]; } const Container = styled.div` // border: 1px solid #ccc; height: fit-content; `; const Header = styled.div` display: flex; align-items: center; justify-content: flex-end; border-bottom: 1px solid #ccc; `; const IconBox = styled.div` font-family: "Times New Roman"; font-size: 2em; line-height: 1.25; font-weight: 400; cursor: pointer; `; const Content = styled.div` padding: 1px; min-height: 10px; `; const Button = styled.button` text-transform: lowercase !important; `; const ButtonRow = styled.div` display: flex; flex-direction: row; flex-wrap: wrap; justify-content: flex-end; gap: 4px; `; const Row = styled.div` display: flex; margin-bottom: 5px; `; const Key = styled.span` font-weight: bold; margin-right: 5px; `; const Value = styled.span` color: #888; `; const Item = styled.div` padding: 0; .btn { width: 100%; border: 0; text-align: left; &:hover, &:focus { background-color: #ecedee; text-decoration: none; outline: none; } i { color: #7e868c; } span { font-weight: 500; } } `; // DROPDOWN // // where can I put this? I'd like a better editor // this is a separate plugin // put in settings acording to the type function toggleEdit() { if (state.showEdit) { return ( <button className={`btn`} onClick={() => State.update({ showEdit: false })} > <i className="bi bi-arrow-counterclockwise me-1" /> <span>Cancel Edit</span> </button> ); } else { return ( <button className={`btn`} onClick={() => State.update({ showEdit: true, showRaw: true })} > <i className="bi bi-pencil me-1" /> <span>Edit</span> </button> ); } } // These are two very similiar functions function toggleRaw() { if (state.showRaw) { return ( <button className={`btn`} onClick={() => State.update({ showRaw: false })} > <i className="bi bi-arrow-up-left-circle me-1" /> <span>Show Thing</span> </button> ); } else { return ( <button className={`btn`} onClick={() => State.update({ showRaw: true })}> <i className="bi bi-filetype-raw me-1" /> <span>Raw</span> </button> ); } } function toggleHistory() { if (state.showHistory) { return ( <button className={`btn`} onClick={() => State.update({ showHistory: false })} > <i className="bi bi-clock me-1" /> <span>Hide History</span> </button> ); } else { return ( <button className={`btn`} onClick={() => State.update({ showHistory: true })} > <i className="bi bi-clock-history me-1" /> <span>Show History</span> </button> ); } } function nearPad() { if (type === "widget") { return ( <a className={`btn`} href={`https://nearpad.dev/editor/${path}`} target="_blank" > <i className=" me-1"> <svg focusable="false" aria-hidden="true" viewBox="2 2 18 18" width="16px" height="16px" > <path d="M12.16 3h-.32L9.21 8.25h5.58zm4.3 5.25h5.16l-2.07-4.14C19.21 3.43 18.52 3 17.76 3h-3.93l2.63 5.25zm4.92 1.5h-8.63V20.1zM11.25 20.1V9.75H2.62zM7.54 8.25 10.16 3H6.24c-.76 0-1.45.43-1.79 1.11L2.38 8.25h5.16z"></path> </svg> </i> <span>Open NEARpad</span> </a> ); } } function toggleView(path, blockHeight) {} // We need it to be able to change state. // I need a widget referenced in state // const plugins = []; // const typeParts = type.split("/"); // if (typeParts.length > 1) { // plugins = Social.get( // `${context.accountId}/settings/every/${type}/plugins` // ) || ; // } function Modifier() { const renderIcon = () => { const icon = Social.get(`${context.accountId}/settings/every/thing/icon`) || `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="black" width="24px" height="24px" > <circle cx="12" cy="12" r="8" /> </svg>`; return <Widget code={`return (${icon})`} />; }; const renderPlugins = () => { return [toggleEdit(), toggleRaw(), toggleHistory(), nearPad()]; }; return ( <Widget src="efiz.near/widget/Common.Dropdown" props={{ renderIcon: renderIcon, elements: renderPlugins(), }} /> ); } function Thing() { // Renders the path according to type (VM doesn't offer switch-case w/ default) if (type === "widget") { // TODO: Verify that props are passed // How to allow user to lock at a specific height? return <Widget src={path} props={props} />; } if (type === "settings") { // Standardize path to {accountId}/settings/** parts.splice(2); parts.push("**"); path = parts.join("/"); return ( <Widget src="efiz.near/widget/Every.Setting" props={{ path, blockHeight }} /> ); } if (type === "thing") { // get the thing data const thing = Social.get(path, blockHeight); thing = JSON.parse(thing || "null"); type = thing.type || null; // get the type data const type = JSON.parse(Social.get(type, blockHeight) || "null"); if (type === null) { console.log(`edge case: thing ${path} had an invalid type: ${thingType}`); } // get the widget to render this thing const widgetSrc = type?.widgets?.view; return ( <Widget src={widgetSrc} props={{ data: thing.data, path, blockHeight }} /> ); } // DEFAULT: return <p>The type: {type} is not yet supported.</p>; } return ( <Container id={path}> {/** <Header> <ButtonRow> <Modifier /> </ButtonRow> </Header> */} <Content> <Thing /> </Content> </Container> ); // I think that there should be a standard install // You start with some default settings // Type = "every.near/type/plugin" // plugins apply to types... // pluginType =