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.