-
Notifications
You must be signed in to change notification settings - Fork 32
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(synapse-interface): Added /returntomonke pfp generator #2460
Conversation
WalkthroughThe latest update enhances the Synapse interface with a new feature that allows users to create Synaptic Profile Pictures. This feature enables users to generate personalized profile pictures by interacting with the Changes
Recent Review DetailsConfiguration used: .coderabbit.yaml Files selected for processing (1)
Additional comments not posted (5)
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (invoked as PR comments)
Additionally, you can add CodeRabbit Configration File (
|
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #2460 +/- ##
===================================================
- Coverage 47.05001% 46.98425% -0.06576%
===================================================
Files 384 382 -2
Lines 29373 28948 -425
Branches 83 83
===================================================
- Hits 13820 13601 -219
+ Misses 14102 13910 -192
+ Partials 1451 1437 -14
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
Deploying sanguine-fe with Cloudflare Pages
|
Deploying sanguine with Cloudflare Pages
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
Review Status
Configuration used: .coderabbit.yaml
Files ignored due to path filters (1)
packages/synapse-interface/public/synpfpborder.png
is excluded by!**/*.png
Files selected for processing (3)
- packages/synapse-interface/pages/returntomonke/ImageUploader.tsx (1 hunks)
- packages/synapse-interface/pages/returntomonke/PfpGeneratorCard.tsx (1 hunks)
- packages/synapse-interface/pages/returntomonke/index.tsx (1 hunks)
Additional comments not posted (3)
packages/synapse-interface/pages/returntomonke/PfpGeneratorCard.tsx (1)
1-20
: LGTM! ThePfpGeneratorCard
component is well-structured and integrates theImageUploader
component effectively.packages/synapse-interface/pages/returntomonke/index.tsx (1)
1-55
: LGTM! TheReturnToMonkePage
component is correctly set up to fetch user information and render the page with thePfpGeneratorCard
.packages/synapse-interface/pages/returntomonke/ImageUploader.tsx (1)
51-51
: Verify the path to the overlay image (./synpfpborder.png
) to ensure it's correctly accessible from this component's location.
const applyImageOverlay = () => { | ||
const canvas = imgRef.current; | ||
const ctx = canvas.getContext('2d'); | ||
|
||
// Clear the canvas | ||
ctx.clearRect(0, 0, canvas.width, canvas.height); | ||
|
||
// Load the uploaded image | ||
const img = new Image(); | ||
img.src = URL.createObjectURL(uploadedImage); | ||
img.onload = () => { | ||
// Set the canvas size to match the uploaded image | ||
canvas.width = img.width; | ||
canvas.height = img.height; | ||
ctx.drawImage(img, 0, 0); | ||
|
||
// Load the overlay image | ||
const overlay = new Image(); | ||
overlay.src = './synpfpborder.png'; | ||
overlay.onload = () => { | ||
// Draw the overlay image on top of the uploaded image | ||
ctx.drawImage(overlay, 0, 0, canvas.width, canvas.height); | ||
|
||
// Convert the canvas to a Blob and update the state | ||
canvas.toBlob((blob) => { | ||
setProcessedImage(blob); | ||
}, 'image/jpeg'); | ||
}; | ||
}; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider adding error handling for the image processing logic to gracefully handle cases where image loading fails.
img.onload = () => {
+ img.onerror = (error) => {
+ console.error('Error loading image:', error);
+ // Handle the error appropriately
+ };
// Set the canvas size to match the uploaded image
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(img, 0, 0);
// Load the overlay image
const overlay = new Image();
overlay.src = './synpfpborder.png';
overlay.onload = () => {
// Draw the overlay image on top of the uploaded image
ctx.drawImage(overlay, 0, 0, canvas.width, canvas.height);
// Convert the canvas to a Blob and update the state
canvas.toBlob((blob) => {
setProcessedImage(blob);
}, 'image/jpeg');
};
+ overlay.onerror = (error) => {
+ console.error('Error loading overlay image:', error);
+ // Handle the error appropriately
+ };
};
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.
const applyImageOverlay = () => { | |
const canvas = imgRef.current; | |
const ctx = canvas.getContext('2d'); | |
// Clear the canvas | |
ctx.clearRect(0, 0, canvas.width, canvas.height); | |
// Load the uploaded image | |
const img = new Image(); | |
img.src = URL.createObjectURL(uploadedImage); | |
img.onload = () => { | |
// Set the canvas size to match the uploaded image | |
canvas.width = img.width; | |
canvas.height = img.height; | |
ctx.drawImage(img, 0, 0); | |
// Load the overlay image | |
const overlay = new Image(); | |
overlay.src = './synpfpborder.png'; | |
overlay.onload = () => { | |
// Draw the overlay image on top of the uploaded image | |
ctx.drawImage(overlay, 0, 0, canvas.width, canvas.height); | |
// Convert the canvas to a Blob and update the state | |
canvas.toBlob((blob) => { | |
setProcessedImage(blob); | |
}, 'image/jpeg'); | |
}; | |
}; | |
}; | |
const applyImageOverlay = () => { | |
const canvas = imgRef.current; | |
const ctx = canvas.getContext('2d'); | |
// Clear the canvas | |
ctx.clearRect(0, 0, canvas.width, canvas.height); | |
// Load the uploaded image | |
const img = new Image(); | |
img.src = URL.createObjectURL(uploadedImage); | |
img.onload = () => { | |
img.onerror = (error) => { | |
console.error('Error loading image:', error); | |
// Handle the error appropriately | |
}; | |
// Set the canvas size to match the uploaded image | |
canvas.width = img.width; | |
canvas.height = img.height; | |
ctx.drawImage(img, 0, 0); | |
// Load the overlay image | |
const overlay = new Image(); | |
overlay.src = './synpfpborder.png'; | |
overlay.onload = () => { | |
// Draw the overlay image on top of the uploaded image | |
ctx.drawImage(overlay, 0, 0, canvas.width, canvas.height); | |
// Convert the canvas to a Blob and update the state | |
canvas.toBlob((blob) => { | |
setProcessedImage(blob); | |
}, 'image/jpeg'); | |
}; | |
overlay.onerror = (error) => { | |
console.error('Error loading overlay image:', error); | |
// Handle the error appropriately | |
}; | |
}; | |
}; |
@@ -0,0 +1,134 @@ | |||
import _ from 'lodash' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't think lodash used in this file
img.src = URL.createObjectURL(uploadedImage); | ||
img.onload = () => { | ||
// Set the canvas size to match the uploaded image | ||
canvas.width = img.width; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently uploading an image that doesn't have equal image width and height will cause for the PFP to distort (see screenshot attached below)
To fix this to always create a square PFP output, we could set the canvas.width
and canvas.height
equal to each other.
As an example, updated the applyImageOverlay()
function to achieve that effect: https://github.com/synapsecns/sanguine/pull/2465/files#diff-1f5949bc4b332bdd1d21bc1fccf989474ccf9b40c36d9b78bbae84a5f7a89b71R44-R50
Given that an uploaded image could differ in height or width, chose to set both canvas.width
and canvas.height
to whichever was greater, image.width
or image.height
so that we could always generate a square PFP output image.
Can test out here: https://fe-center-synape-pf.sanguine-fe.pages.dev/returntomonke
[do not merge] center generated synape pfp example
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
packages/synapse-interface/pages/returntomonke/ImageUploader.tsx
Outdated
Show resolved
Hide resolved
const applyImageOverlay = () => { | ||
const canvas = imgRef.current | ||
const ctx = canvas.getContext('2d') | ||
|
||
// Clear the canvas | ||
ctx.clearRect(0, 0, canvas.width, canvas.height) | ||
|
||
// Load the uploaded image | ||
const img = new Image() | ||
img.src = URL.createObjectURL(uploadedImage) | ||
img.onload = () => { | ||
if (img.width >= img.height) { | ||
canvas.width = img.width | ||
canvas.height = img.width | ||
} else { | ||
canvas.width = img.height | ||
canvas.height = img.height | ||
} | ||
|
||
// Calculate the start positions to center the image | ||
const startX = (canvas.width - img.width) / 2 | ||
const startY = (canvas.height - img.height) / 2 | ||
|
||
// Draw the uploaded image centered | ||
ctx.drawImage(img, startX, startY) | ||
|
||
// Load the overlay image | ||
const overlay = new Image() | ||
overlay.src = './synpfpborder.png' | ||
overlay.onload = () => { | ||
// Draw the overlay image on top of the uploaded image | ||
ctx.drawImage(overlay, 0, 0, canvas.width, canvas.height) | ||
|
||
// Convert the canvas to a Blob and update the state | ||
canvas.toBlob((blob) => { | ||
setProcessedImage(blob) | ||
}, 'image/jpeg') | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ensure error handling is added for image loading failures. Consider implementing the error handling as suggested in previous comments.
img.onload = () => {
+ img.onerror = (error) => {
+ console.error('Error loading image:', error);
+ // Handle the error appropriately
+ };
// Set the canvas size to match the uploaded image
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(img, 0, 0);
// Load the overlay image
const overlay = new Image();
overlay.src = './synpfpborder.png';
overlay.onload = () => {
// Draw the overlay image on top of the uploaded image
ctx.drawImage(overlay, 0, 0, canvas.width, canvas.height);
// Convert the canvas to a Blob and update the state
canvas.toBlob((blob) => {
setProcessedImage(blob);
}, 'image/jpeg');
};
+ overlay.onerror = (error) => {
+ console.error('Error loading overlay image:', error);
+ // Handle the error appropriately
+ };
};
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.
const applyImageOverlay = () => { | |
const canvas = imgRef.current | |
const ctx = canvas.getContext('2d') | |
// Clear the canvas | |
ctx.clearRect(0, 0, canvas.width, canvas.height) | |
// Load the uploaded image | |
const img = new Image() | |
img.src = URL.createObjectURL(uploadedImage) | |
img.onload = () => { | |
if (img.width >= img.height) { | |
canvas.width = img.width | |
canvas.height = img.width | |
} else { | |
canvas.width = img.height | |
canvas.height = img.height | |
} | |
// Calculate the start positions to center the image | |
const startX = (canvas.width - img.width) / 2 | |
const startY = (canvas.height - img.height) / 2 | |
// Draw the uploaded image centered | |
ctx.drawImage(img, startX, startY) | |
// Load the overlay image | |
const overlay = new Image() | |
overlay.src = './synpfpborder.png' | |
overlay.onload = () => { | |
// Draw the overlay image on top of the uploaded image | |
ctx.drawImage(overlay, 0, 0, canvas.width, canvas.height) | |
// Convert the canvas to a Blob and update the state | |
canvas.toBlob((blob) => { | |
setProcessedImage(blob) | |
}, 'image/jpeg') | |
} | |
} | |
const applyImageOverlay = () => { | |
const canvas = imgRef.current | |
const ctx = canvas.getContext('2d') | |
// Clear the canvas | |
ctx.clearRect(0, 0, canvas.width, canvas.height) | |
// Load the uploaded image | |
const img = new Image() | |
img.src = URL.createObjectURL(uploadedImage) | |
img.onload = () => { | |
img.onerror = (error) => { | |
console.error('Error loading image:', error); | |
// Handle the error appropriately | |
}; | |
if (img.width >= img.height) { | |
canvas.width = img.width | |
canvas.height = img.width | |
} else { | |
canvas.width = img.height | |
canvas.height = img.height | |
} | |
// Calculate the start positions to center the image | |
const startX = (canvas.width - img.width) / 2 | |
const startY = (canvas.height - img.height) / 2 | |
// Draw the uploaded image centered | |
ctx.drawImage(img, startX, startY) | |
// Load the overlay image | |
const overlay = new Image() | |
overlay.src = './synpfpborder.png' | |
overlay.onload = () => { | |
// Draw the overlay image on top of the uploaded image | |
ctx.drawImage(overlay, 0, 0, canvas.width, canvas.height) | |
// Convert the canvas to a Blob and update the state | |
canvas.toBlob((blob) => { | |
setProcessedImage(blob) | |
}, 'image/jpeg') | |
} | |
overlay.onerror = (error) => { | |
console.error('Error loading overlay image:', error); | |
// Handle the error appropriately | |
}; | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
const ReturnToMonkePage = () => { | ||
const { address: currentAddress, chain } = useAccount() | ||
const [connectedChainId, setConnectedChainId] = useState(0) | ||
const [address, setAddress] = useState(undefined) | ||
|
||
useEffect(() => { | ||
setConnectedChainId(chain?.id ?? DEFAULT_FROM_CHAIN) | ||
}, [chain]) | ||
|
||
useEffect(() => { | ||
setAddress(currentAddress) | ||
}, [currentAddress]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ensure that the initial state for address
is explicitly set to null
or an empty string for clarity and to avoid potential issues with undefined
.
- const [address, setAddress] = useState(undefined)
+ const [address, setAddress] = useState('')
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.
const ReturnToMonkePage = () => { | |
const { address: currentAddress, chain } = useAccount() | |
const [connectedChainId, setConnectedChainId] = useState(0) | |
const [address, setAddress] = useState(undefined) | |
useEffect(() => { | |
setConnectedChainId(chain?.id ?? DEFAULT_FROM_CHAIN) | |
}, [chain]) | |
useEffect(() => { | |
setAddress(currentAddress) | |
}, [currentAddress]) | |
const ReturnToMonkePage = () => { | |
const { address: currentAddress, chain } = useAccount() | |
const [connectedChainId, setConnectedChainId] = useState(0) | |
const [address, setAddress] = useState('') | |
useEffect(() => { | |
setConnectedChainId(chain?.id ?? DEFAULT_FROM_CHAIN) | |
}, [chain]) | |
useEffect(() => { | |
setAddress(currentAddress) | |
}, [currentAddress]) |
Adds a page for /returntomonke, that allows users to upload an image, and have an image returned with the synapse profile picture background.
Summary by CodeRabbit
131e9c649ebe7ec1a96b4c6c9a701fc859fa9cce: synapse-interface preview link
49ca6f57f73afb8d89d6f22fc66602d2cb0e045f: synapse-interface preview link
ba420a853fe11c655255d2a1244f82a22b15bb2b: synapse-interface preview link
fa2bf5411b57ca169a05a66e5c7c8da24dc27beb: synapse-interface preview link