Skip to content

Commit

Permalink
Copyright external uri revisions (#439)
Browse files Browse the repository at this point in the history
* language updates (plz work)

* preview page display update

* token display update (displays all clauses all the time now)

---------

Co-authored-by: Zir0h <[email protected]>
  • Loading branch information
ryangtanaka-org and Zir0h authored Dec 17, 2024
1 parent 40ae9e5 commit f10d8ea
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 90 deletions.
150 changes: 69 additions & 81 deletions src/components/form/CustomCopyrightForm.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -113,58 +113,52 @@ export const ClausesDescriptions = ({ clauses }) => {
<div>
<strong>Copyright Permissions Granted on Ownership:</strong>
<ul>
{clauses?.customUriEnabled ? (
<>
<li key="customUriEnabled">
Custom URI Enabled: {descriptions?.customUriEnabled[true]}
</li>
<li key="customUri">
Custom URI: {clauses?.customUri || 'No URI Set'}
</li>
</>
) : (
Object.entries(clauses).map(([key, value]) => {
if (key === 'exclusiveRights') {
const exclusiveLabel =
exclusiveRightsOptions.find((option) => option?.value === value)
?.label || 'None'
return <li key={key}>Exclusive Rights: {exclusiveLabel}</li>
} else if (key === 'customUri' || key === 'expirationDate') {
return null
} else if (key === 'expirationDateExists') {
return (
<>
<li key={key}>
{clauseLabels[key]}: {descriptions[key][value]}
</li>
<li key="expirationDate">
{clauseLabels.expirationDate}:{' '}
{clauses.expirationDateExists && clauses.expirationDate
? new Date(clauses.expirationDate).toLocaleDateString(
'en-US',
{
year: 'numeric',
month: 'long',
day: 'numeric',
}
)
: 'None'}
</li>
</>
)
} else if (key === 'addendum') {
return <li key={key}>Addendum: {value ? '✅ Yes' : '🚫 No'}</li>
} else {
const displayValue =
descriptions[key]?.[value] || 'Unknown Status'
return (
{Object.entries(clauses).map(([key, value]) => {
if (key === 'exclusiveRights') {
const exclusiveLabel =
exclusiveRightsOptions.find((option) => option?.value === value)
?.label || 'None'
return <li key={key}>Exclusive Rights: {exclusiveLabel}</li>
} else if (key === 'customUri' || key === 'expirationDate') {
return null
} else if (key === 'expirationDateExists') {
return (
<>
<li key={key}>
{clauseLabels[key]}: {displayValue}
{clauseLabels[key]}: {descriptions[key][value]}
</li>
)
}
})
)}
<li key="expirationDate">
{clauseLabels.expirationDate}:{' '}
{clauses.expirationDateExists && clauses.expirationDate
? new Date(clauses.expirationDate).toLocaleDateString(
'en-US',
{
year: 'numeric',
month: 'long',
day: 'numeric',
}
)
: 'None'}
</li>
</>
)
} else if (key === 'addendum') {
return <li key={key}>Addendum: {value ? '✅ Yes' : '🚫 No'}</li>
} else if (key === 'customUriEnabled') {
return value ? (
<li key={key}>
Custom URI Enabled: {descriptions?.customUriEnabled[true]}
</li>
) : null
} else {
const displayValue = descriptions[key]?.[value] || 'Unknown Status'
return (
<li key={key}>
{clauseLabels[key]}: {displayValue}
</li>
)
}
})}
</ul>
<br />
</div>
Expand Down Expand Up @@ -284,6 +278,20 @@ Despite reaching the threshold for exclusive rights, the Creator retains certain
documentText += `\n\n${clauseNumber++}. Expiration Date:\nThis Agreement is effective until the date of ${readableDate} (relative to the time of mint of the Work), after which the rights granted herein will terminate unless expressly renewed or extended in writing by the Creator. Upon expiration, all rights (including exclusive rights) returns back to the Creator's ownership and control.`
}

if (clauses.customUriEnabled && clauses.customUri) {
documentText += `\n\n${clauseNumber++}. Custom URI Reference and Retroactive Application:
The Work is subject to additional terms, conditions, and declarations specified at: ${
clauses.customUri
}. These external terms are hereby incorporated by reference into this Agreement and shall be considered binding to the same extent as if they were fully set forth herein.
This URI may serve one or both of the following purposes:
a) External Reference: The URI may contain supplementary terms, conditions, restrictions, or declarations that apply to this Work. These additional terms shall be considered as an extension of this Agreement.
b) Retroactive Application: If the URI points to a previous work by the same Creator, and the Creator can conclusively demonstrate through cryptographic proof that they control both the wallet address associated with this Work and the wallet address associated with the referenced work ${minterInfo}, then all terms, rights, and restrictions specified in this Agreement shall apply retroactively to the referenced work. Such proof must be verifiable through blockchain records or other cryptographic means that establish an undeniable connection between the Creator's wallet addresses and both works.
The Creator bears the burden of proving ownership of both works through wallet address verification, transaction histories, or other blockchain-based evidence. In the absence of such proof, the retroactive application shall be considered void while the external reference shall remain in effect. Any conflicts between the terms specified in the URI and this Agreement shall be resolved in favor of the more restrictive terms, unless explicitly stated otherwise in either document.`
}

documentText += `\n\n${clauseNumber++}. Jurisdiction and Legal Authority:
This Agreement is subject to and shall be interpreted in accordance with the laws of the jurisdiction in which the Creator and Owner(s) are domiciled. The rights granted hereunder are subject to any applicable international, national, and local copyright and distribution laws.`

Expand Down Expand Up @@ -321,31 +329,15 @@ Unless stated otherwise (in this Agreement itself), this Agreement remains effec
} else {
newValue = value
}

if (name === 'customUriEnabled') {
if (newValue) {
setClauses((prev) => ({
...prev,
reproduce: null,
broadcast: null,
publicDisplay: null,
createDerivativeWorks: null,
exclusiveRights: null,
retainCreatorRights: null,
requireAttribution: null,
rightsAreTransferable: null,
expirationDateExists: null,
expirationDate: '',
releasePublicDomain: null,
customUriEnabled: true,
}))
} else {
setClauses((prev) => ({
...prev,
customUriEnabled: false,
customUri: prev.customUri,
}))
}
setClauses((prev) => ({
...prev,
customUriEnabled: newValue === true, // Set to true or false
...(newValue === false && { customUri: '' }), // Clear URI when disabled
}))
}

// Handle 'Release to Public Domain' logic
else if (name === 'releasePublicDomain' && newValue === true) {
setClauses({
Expand Down Expand Up @@ -424,9 +416,7 @@ Unless stated otherwise (in this Agreement itself), this Agreement remains effec
clauses.releasePublicDomain ||
clauses.requireAttribution

if (clauses.customUriEnabled) {
documentText = `Custom URI: ${clauses.customUri}`
} else if (!hasActiveRights) {
if (!hasActiveRights && !clauses.customUriEnabled) {
documentText =
'No Permissions Chosen (For Addendum or Expiration Date sections to show, choose at least one option in the checkboxes above.)'
} else {
Expand Down Expand Up @@ -527,9 +517,8 @@ Unless stated otherwise (in this Agreement itself), this Agreement remains effec
checked={clauses[clauseName]}
onCheck={(checked) => handleChange(checked, clauseName)}
disabled={
clauses.customUriEnabled ||
(clauses.releasePublicDomain &&
clauseName !== 'releasePublicDomain')
clauses.releasePublicDomain &&
clauseName !== 'releasePublicDomain'
}
/>
<span
Expand Down Expand Up @@ -583,7 +572,6 @@ Unless stated otherwise (in this Agreement itself), this Agreement remains effec
}
placeholder="Select Ownership Share Type"
isDisabled={
clauses.customUriEnabled ||
!Object.values(clauses).some((value) => value && value !== 'none')
}
styles={select_style}
Expand Down Expand Up @@ -663,7 +651,7 @@ Unless stated otherwise (in this Agreement itself), this Agreement remains effec
role="button"
tabIndex={0}
className={styles.modalInfoIcon}
onClick={() => handleModalOpen(clauseLabels['customUriEnabled'])}
onClick={() => handleModalOpen('customUri')}
onKeyPress={(event) =>
handleKeyPress(event, clauseLabels['customUriEnabled'])
}
Expand Down
36 changes: 32 additions & 4 deletions src/components/form/copyrightmodaltext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,36 @@ export const copyrightModalText = {
<p>In professional contexts, expiration dates are typically set on a case-to-case basis (when an artist signs a "deal" with a label or company these details come into play), but if the Creator wants to create a blanket policy for their rights to be effective only during a limited time period, this option can be used to set a standard for all editions that apply to all Owners at once.</p>
`,
customUri: `
<p>This feature allows creators to set a custom URI/URL for additional resources or information related to the NFT.</p>
<p>The custom URI can link to a variety of content, such as detailed metadata, licensing information, or the creator's personal website.</p>
<p>Note that the reference to the URI itself may be permanent (a link to someone's website, for example), but the destination itself may be editable, so unless modularity is what is needed, treat HTTP-based Custom URIs. (Destination links could be edited, or disappear.)</p>
<p>Custom URIs can be made fully decentralized by using IPFS CIDs (hashes) or other decentralized storage systems, for full immutability.</p>`
<p>The Custom URI feature serves two important functions for creators:</p>
<p><strong>1. External Reference:</strong><br>
- Link to additional terms, restrictions, or declarations for the Work
- Provide supplementary documentation or metadata
- Reference creator's canonical information or portfolio</p>
<p><strong>2. Retroactive Application:</strong><br>
- Point to a previous work by the same creator
- Apply current license terms to the referenced work
- Must be verifiable through wallet address ownership</p>
<p><strong>Important Considerations:</strong></p>
<ul>
<li>For standard web links (http://, https://):
<ul>
<li>- The URI reference is permanent, but destination content may change</li>
<li>- Consider carefully if changeable content aligns with your intentions</li>
<li>- Best for dynamic information that may need updates</li>
</ul>
</li>
<li>For decentralized storage (ipfs://, etc.):
<ul>
<li>- Content is immutable and permanently stored</li>
<li>- Ideal for fixed terms or historical references</li>
<li>- Recommended for legal documents and permanent declarations</li>
</ul>
</li>
</ul>
<p><strong>Verification Requirements:</strong><br>
When using this feature for retroactive application, creators must be able to prove ownership of both the current and referenced works through their wallet addresses. This typically requires maintaining access to both wallet addresses and being able to sign transactions or messages that verify ownership.</p>`
};
8 changes: 3 additions & 5 deletions src/pages/objkt-display/tabs/Copyright.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ export const Copyright = () => {
rightsAreTransferable: 'Rights are Transferable (Secondary Sales)',
releasePublicDomain: 'Release to Public Domain',
customUriEnabled: 'Custom URI Enabled',
customUri: 'Custom URI',
customUri:
'Custom URI (External Terms & Works Connected To This Agreement)',
}

const descriptions = {
Expand Down Expand Up @@ -136,9 +137,6 @@ export const Copyright = () => {
<ul>
{licenseData?.clauses &&
Object.entries(licenseData?.clauses).map(([key, value]) => {
if (isCustomUriOnly() && key !== 'customUri') {
return null // Do not render other clauses if customUriEnabled is true
}
const title = clauseLabels[key]
const displayValue = descriptions[key]
? descriptions[key][value]
Expand Down Expand Up @@ -213,7 +211,7 @@ export const Copyright = () => {
</Container>
</>
)}
{nft?.rights !== 'custom' && nft?.rights && (
{nft?.rights && (
<Container>
<h3>License Information</h3>
<p>{nft?.rights}</p>
Expand Down

0 comments on commit f10d8ea

Please sign in to comment.