diff --git a/js/blocks/RhythmBlockPaletteBlocks.js b/js/blocks/RhythmBlockPaletteBlocks.js
index bec8ce768a..2eaa5aecba 100644
--- a/js/blocks/RhythmBlockPaletteBlocks.js
+++ b/js/blocks/RhythmBlockPaletteBlocks.js
@@ -277,7 +277,15 @@ function setupRhythmBlockPaletteBlocks(activity) {
* Constructs a SixtyFourthNoteBlock.
*/
constructor() {
- super("sixtyfourthNote", _("1/64 note") + " 𝅘𝅥𝅱");
+ if (isAppleBrowser()) {
+ super("sixtyfourthNote", _("1/64 note"));
+ // Custom generator only needed for Apple devices
+ this.appleNoteBlock();
+ } else {
+ // TRANS: Do not modify the following line
+ super("sixtyfourthNote", _("1/64 note") + " 𝅘𝅥𝅱");
+ }
+
this.setPalette(rhythmBlockPalette, activity);
this.setHelpString();
this.makeMacro((x, y) => [
@@ -300,8 +308,14 @@ function setupRhythmBlockPaletteBlocks(activity) {
* Constructs a ThirtySecondNoteBlock instance.
*/
constructor() {
- // TRANS: Do not modify the following line
- super("thirtysecondNote", _("1/32 note") + " 𝅘𝅥𝅰");
+ if (isAppleBrowser()) {
+ super("thirtysecondNote", _("1/32 note"));
+ // Custom generator only needed for Apple devices
+ this.appleNoteBlock();
+ } else {
+ // TRANS: Do not modify the following line
+ super("thirtysecondNote", _("1/32 note") + " 𝅘𝅥𝅰");
+ }
// Set the palette and activity for the block
this.setPalette(rhythmBlockPalette, activity);
@@ -328,8 +342,14 @@ function setupRhythmBlockPaletteBlocks(activity) {
* Constructs a SixteenthNoteBlock instance.
*/
constructor() {
- // TRANS: Do not modify the following line
- super("sixteenthNote", _("1/16 note") + " 𝅘𝅥𝅯");
+ if (isAppleBrowser()) {
+ super("sixteenthNote", _("1/16 note"));
+ // Custom generator only needed for Apple devices
+ this.appleNoteBlock();
+ } else {
+ // TRANS: Do not modify the following line
+ super("sixteenthNote", _("1/16 note") + " 𝅘𝅥𝅯");
+ }
// Set the palette and activity for the block
this.setPalette(rhythmBlockPalette, activity);
@@ -412,8 +432,14 @@ function setupRhythmBlockPaletteBlocks(activity) {
* Constructs a HalfNoteBlock instance.
*/
constructor() {
- // TRANS: Do not modify the following line
- super("halfNote", _("half note") + " 𝅗𝅥");
+ if (isAppleBrowser()) {
+ super("halfNote", _("half note"));
+ // Custom generator only needed for Apple devices
+ this.appleNoteBlock();
+ } else {
+ // TRANS: Do not modify the following line
+ super("halfNote", _("half note") + " 𝅗𝅥");
+ }
// Set the palette and activity for the block
this.setPalette(rhythmBlockPalette, activity);
@@ -440,8 +466,14 @@ function setupRhythmBlockPaletteBlocks(activity) {
* Constructs a WholeNoteBlock instance.
*/
constructor() {
- // TRANS: Do not modify the following line
- super("wholeNote", _("whole note") + " 𝅝");
+ if (isAppleBrowser()) {
+ super("wholeNote", _("whole note"));
+ // Custom generator only needed for Apple devices
+ this.appleNoteBlock();
+ } else {
+ // TRANS: Do not modify the following line
+ super("wholeNote", _("whole note") + " 𝅝");
+ }
// Set the palette and activity for the block
this.setPalette(rhythmBlockPalette, activity);
@@ -996,3 +1028,13 @@ function setupRhythmBlockPaletteBlocks(activity) {
new TripletBlock().setup(activity);
new STupletBlock().setup(activity);
}
+
+// Function to check if the browser is Safari or Chrome on a Mac or iPad
+function isAppleBrowser() {
+ const userAgent = navigator.userAgent;
+ const isMac = userAgent.includes('Macintosh');
+ const isIPad = userAgent.includes('iPad') || (userAgent.includes('Macintosh') && 'ontouchend' in document); // Detects iPad in desktop mode
+ const isSafari = userAgent.includes('Safari') && !userAgent.includes('Chrome');
+ const isChrome = userAgent.includes('Chrome');
+ return (isMac || isIPad) && (isSafari || isChrome);
+}
\ No newline at end of file
diff --git a/js/protoblocks.js b/js/protoblocks.js
index 485320b0c5..65bc675400 100644
--- a/js/protoblocks.js
+++ b/js/protoblocks.js
@@ -2050,6 +2050,88 @@ class BaseBlock extends ProtoBlock {
this.beginnerModeBlock = value;
}
+ /**
+ * Used for blocks that need custom SVG note symbols (Apple Devices only).
+ */
+ appleNoteBlock() {
+ this.style = "basic";
+ this.size = 1;
+ this.args = 0;
+ this.dockTypes.push("out");
+ this.dockTypes.push("in");
+ this.generator = this.appleNoteBlockGenerator;
+ }
+
+ /**
+ * Generates SVG for a note block with custom musical notation.
+ * @returns {array} - Array containing SVG elements and dimensions.
+ */
+ appleNoteBlockGenerator() {
+ const svg = new SVG();
+ svg.setScale(this.scale);
+ svg.setTab(true);
+ svg.setSlot(true);
+ svg.setExpand(30 + this.extraWidth, 0, 0, 0);
+
+ if (this.fontsize) {
+ svg.setFontSize(this.fontsize);
+ }
+
+ // Get the basic block shape
+ const block = svg.basicBlock();
+
+ // Add the note symbol as SVG based on the block name
+ let noteSymbol;
+ switch(this.name) {
+ case "wholeNote":
+ noteSymbol = `
+
+
+
+ `;
+ break;
+ case "halfNote":
+ noteSymbol = `
+
+
+
+ `;
+ break;
+ case "sixteenthNote":
+ noteSymbol = `
+
+
+
+ `;
+ break;
+ case "thirtysecondNote":
+ noteSymbol = `
+
+
+
+ `;
+ break;
+ case "sixtyfourthNote":
+ noteSymbol = `
+
+
+
+ `;
+ break;
+ }
+
+ // Insert the note symbol after the text
+ const blockWithNote = block.replace('', `${noteSymbol}`);
+
+ return [
+ blockWithNote,
+ svg.docks,
+ svg.getWidth(),
+ svg.getHeight(),
+ svg.getHeight()
+ ];
+ }
+
/**
* Performs setup for the block within the provided activity.
* @param {object} activity - The activity context to set up the block in.