Skip to content

Commit

Permalink
[3851] - Implement functionality of collaboration mouse along with cu…
Browse files Browse the repository at this point in the history
…stom and random names. (#3984)

* fixes #3913

* fix:resolves grid position on hamburger opening(#3914) (#3924)

* fix:resolves hamburger opening(#3914)

* fix:fixes #3914(suggested changes done)

* adjust size of grid element repositioning when using aux toolbar

---------

Co-authored-by: Walter Bender <[email protected]>

* Fix input boxes (#3927)

* bump version

* enhancement: scale on hover (#3926)

Co-authored-by: anas2357 <[email protected]>

* calculate frequencies from ratio

* Add close button to extended-menu pie menu (fixes #3933) (#3934)

* Bump braces and gulp (#3903)

Bumps [braces](https://github.com/micromatch/braces) to 3.0.3 and updates ancestor dependency [gulp](https://github.com/gulpjs/gulp). These dependencies need to be updated together.


Updates `braces` from 2.3.2 to 3.0.3
- [Changelog](https://github.com/micromatch/braces/blob/master/CHANGELOG.md)
- [Commits](https://github.com/micromatch/braces/commits/3.0.3)

Updates `gulp` from 4.0.2 to 5.0.0
- [Release notes](https://github.com/gulpjs/gulp/releases)
- [Changelog](https://github.com/gulpjs/gulp/blob/master/CHANGELOG.md)
- [Commits](gulpjs/gulp@v4.0.2...v5.0.0)

---
updated-dependencies:
- dependency-name: braces
  dependency-type: indirect
- dependency-name: gulp
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* add support for solfege accidentals in phrasemaker

* Add support for cents (#3937)

* add support for cents through semi-tone transposition

* add 50 cents macro

* add cents example

* add output frequencies

* fix issue with ratio cents

* add a ratio-cents example

* Ratio transpose and Ratio interval (#3936)

* use processPitch for all pitch types

* Add support for cents (#3937)

* add support for cents through semi-tone transposition

* add 50 cents macro

* add cents example

* add output frequencies

* fix issue with ratio cents

* add a ratio-cents example

* use processPitch for all pitch types

* convert freq to note before scalar step

* fix note convert

* remove extra comma throwing off indexing

* Hyperscore link update (#3939) (#3947)

* Update Hyperscore example link in guide.html (#3944)

* Update README.md (#3943)

* left_and_back_images (#3950)

* Updated Dockerfile  (#3949)

* Update README.md

* Update dockerfile

* remove yjs and socket.io dependecies

* Fixed #3956 Auto increasing and decreasing input block (#3957)

* fixes #3941

* fixes #3958

* Fixes collapsed state of note block (#3961)

* fixes issue with extra line number in JavaScript Editor (#3962)

* fixes sample block duplication issue (#3965)

* fixes sample block duplication issue

* changed error message

* updated error message

* updated planet image on documentation (#3971)

* updated planet image on documentation

fixes issue number: 3968

* updated images

* removed overlap between two images

* fix 1MB file size limit on audio sample imports (#3976)

* enforce 1MB limit on audio sample imports

* update sampler.js

* updated error msg

* update wheelnav.js (#3977)

* Fixes #3972 Highlight should not activate when code is being run (#3975)

* Fixes #3972 Highlight should not activate when code is being run

* optimized the code by using existing flag

* optimized the code by using existing flag

* fixes #3972

* removed extra code (#3980)

* Fixes #3973 Right click menu only opens in the advanced mode (#3978)

* Contextmenu only opens in advanced mode

* Added indentation and changed the if condition

* FIXES ISSUE #3895 Add alphabet "G" as a block found in easy mode  (#3979)

* FIXES ISSUE #3895 Add alphabet "G" as a block found in easy mode 

The requirement of this bug is to add the pitch G4 nad Alphabet G block in pitch menu of the beginner mode.

* FIXES ISSUE #3895 Add alphabet "G" and Sol as a block found in easy mode 

It adds the sol pitch block in the pitch menu of beginner's mode

* AI BLOCK and Documentation on How to add widget in MB (#3964)

* clean code , added comments

* added abc lib

* added debug statement

* fix : Formatting , Function method & method Func

* add function description

* added AI BLOCKS and DOCS

* change canvas to editor text

* changed canvas to edit text,added hint

* Fix: suggestion in AI Block & AI block structure

* added groq api

* Added midi support to MB (#3904)

* added midi support

* made corrections

* added note approximations

* added action blocks to start block

* added action block to start blk

* made corrections

* break also into multiple action block when noteblock count exceeds 24

* added break statement in case of no of  tracks more than 1

* added start blocks corresponding each track

* added meter and tempo information

* added scaling factor and load as midi feture

* added default timesignatures

* added drum mapper

* removed set instrument in case of percussion

* added an extra condtion when the new note start is less than previous note

* added minor changes

* removed the scaling factor earlier added

* added names to start blocks

* modifications for clarity

* create a new class for collaboration cursor

* Import collabcursor file

* Add logic to take name from the user

* Implement collaboration mouse functionality

* Implement random name functionality

* add abacus example

* Rhythm block doesn't repeat issue update (#3982)

* Rhythm block doesn't repeat issue update

* removed console log messages

* added console log message for testing

* fixes #3931 Rhythm block doesn't repeat when outside of PhraseMaker

* add more steps to new palette instructions

* Fix scrolling issue

---------

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: Walter Bender <[email protected]>
Co-authored-by: Nikhil <[email protected]>
Co-authored-by: Anas <[email protected]>
Co-authored-by: anas2357 <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Walter Bender <[email protected]>
Co-authored-by: Harshit Verma <[email protected]>
Co-authored-by: Geeten Parab <[email protected]>
Co-authored-by: akilesh1706 <[email protected]>
Co-authored-by: Khadar vali <[email protected]>
Co-authored-by: Muhammad Haroon <[email protected]>
Co-authored-by: AnupamGaur <[email protected]>
Co-authored-by: omsuneri <[email protected]>
Co-authored-by: abhijeet <[email protected]>
Co-authored-by: Mubashir  Shariq <[email protected]>
  • Loading branch information
16 people authored Aug 29, 2024
1 parent 77ca477 commit dd3e410
Show file tree
Hide file tree
Showing 19 changed files with 2,548 additions and 52 deletions.
Empty file added ,
Empty file.
Binary file modified documentation/planet-3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified documentation/planet-4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,8 @@ Music Blocks has handy widgets for various musical concepts to create musical co
| stocks.html | Generated from a Python script, this project is a musical representation of the price of a stock over time |
| Morse-code-rhythms.html | Generate Morse code rhythms by typing in letters that generate rhythmic patterns |
| typing-game.html | Catch the falling alphabets/letters before they reach ground by inputting them correctly |
| abacus-prototype.html | Working abacus example... remix to enrich this example. |


# Utilities

Expand Down
1 change: 1 addition & 0 deletions examples/abacus-prototype.html

Large diffs are not rendered by default.

8 changes: 7 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@

<script src="lib/Tone.js" defer></script>

<script src="lib/midi.js" defer></script>

<script src="lib/jquery.ruler.js" defer></script>

<script src="lib/modernizr-2.6.2.min.js" defer></script>
Expand All @@ -48,6 +50,8 @@

<script src="lib/wheelnav.js" defer></script>

<script src="lib/abc.min.js" defer></script>

<script src="lib/codejar/codejar.min.js" defer></script>

<script src="lib/codejar/highlight.pack.js" defer></script>
Expand All @@ -56,6 +60,8 @@

<script src="./js/collaboration/collaboration.js"></script>

<script src="./js/collaboration/collabcursor.js"></script>

<link rel="prefetch" type="application/l10n" href="./localization.ini"/>

<script data-main="js/loader" src="lib/require.js" defer></script>
Expand Down Expand Up @@ -411,7 +417,7 @@
class="file"
type="file"
id="myOpenFile"
accept=".ta, .tb, .html"
accept=".ta, .tb, .html,.mid,.midi"
tabindex="-1"
/>
<input
Expand Down
6 changes: 6 additions & 0 deletions js/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,12 @@ meaningful name, e.g. `setupGraphicsBlocks()`.
4. Call that setup function in `js/basicblocks.js` from the
`initBasicProtoBlocks()` function.

5. Add artwork for the palette icon in `js/artwork.js`. There are
several dictionaries that need to be updated as well: `PALETTECOLORS`
and `PALETTEICONS`.

6. Assign colors in `js/utils/platformstyle.js`.

After the above steps are complete, move to [defining a new
block](#how-to-define-a-new-block)

Expand Down
1,128 changes: 1,110 additions & 18 deletions js/activity.js

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions js/blocks/PitchBlocks.js
Original file line number Diff line number Diff line change
Expand Up @@ -875,6 +875,7 @@ function setupPitchBlocks(activity) {
"note2"
]);
this.formBlock({ outType: "noteout" });
this.beginnerBlock(true);
}
}

Expand All @@ -889,6 +890,7 @@ function setupPitchBlocks(activity) {
"note1"
]);
this.formBlock({ outType: "solfegeout" });
this.beginnerBlock(true);
}
}

Expand Down Expand Up @@ -1841,6 +1843,7 @@ function setupPitchBlocks(activity) {
[1, ["notename", { value: "G" }], 0, 0, [0]],
[2, ["number", { value: 4 }], 0, 0, [0]]
]);
this.beginnerBlock(true);
}
}

Expand Down
3 changes: 2 additions & 1 deletion js/blocks/RhythmBlockPaletteBlocks.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,8 @@ function setupRhythmBlockPaletteBlocks(activity) {
const bpmFactor =
TONEBPM / tur.singer.bpm.length > 0 ? last(tur.singer.bpm) : Singer.masterBPM;

const beatValue = bpmFactor / noteBeatValue;
const beatValue =
bpmFactor == null ? 1 : bpmFactor / noteBeatValue;

/**
* Plays a note in the rhythm.
Expand Down
61 changes: 60 additions & 1 deletion js/blocks/WidgetBlocks.js
Original file line number Diff line number Diff line change
Expand Up @@ -1555,7 +1555,65 @@ function setupWidgetBlocks(activity) {
if (args.length === 1) return [args[0], 1];
}
}

/**
* Represents a block for inspecting the status of Music Blocks during execution.
* @extends StackClampBlock
*/
class AIMusicBlocks extends StackClampBlock {
/**
* Creates a SamplerBlock instance.
*/
constructor() {
super("aimusic");
this.setPalette("widgets", activity);
this.parameter = true;
this.beginnerBlock(false);

this.setHelpString([
_("Upload a sample and adjust its pitch center."),
"documentation",
null,
"aimusic"
]);

//.TRANS: the speed at music is should be played.
this.formBlock({ name: _("aimusic"), canCollapse: true });
this.makeMacro((x, y) => [
[0, "aimusic", x, y, [null, 1]],

[1, "print", 0, 0, [0,2,null]],
[2, ["text",{"value":"Music Generated By AI"}], 0, 0, [1]]
]);
}

/**
* Handles the flow of data for the sampler block.
* @param {any[]} args - The arguments passed to the block.
* @param {object} logo - The logo object.
* @param {object} turtle - The turtle object.
* @param {object} blk - The block object.
* @returns {number[]} - The output values.
*/
flow(args, logo, turtle, blk) {
if (logo.sample === null) {
logo.sample = new AIWidget();
}
logo.inSample = true;
logo.sample = new AIWidget();

const listenerName = "_sampler_" + turtle;
logo.setDispatchBlock(blk, turtle, listenerName);

// eslint-disable-next-line no-unused-vars
const __listener = event => {
logo.sample.init(activity);
};

logo.setTurtleListener(turtle, listenerName, __listener);

return [args[0], 1];
}
}
// Set up blocks if this is Music Blocks environment
if (_THIS_IS_MUSIC_BLOCKS_) {
new EnvelopeBlock().setup(activity);
Expand All @@ -1579,6 +1637,7 @@ function setupWidgetBlocks(activity) {
new MatrixGMajorBlock().setup(activity);
new MatrixCMajorBlock().setup(activity);
new MatrixBlock().setup(activity);
new AIMusicBlocks().setup(activity);
}
// Instantiate and set up the StatusBlock
new StatusBlock().setup(activity);
Expand Down
100 changes: 100 additions & 0 deletions js/collaboration/collabcursor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/* eslint-disable no-unused-vars */
// Copyright (c) 2024 Ajeet Pratap Singh
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the The GNU Affero General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// You should have received a copy of the GNU Affero General Public
// License along with this library; if not, write to the Free Software
// Foundation, 51 Franklin Street, Suite 500 Boston, MA 02110-1335 USA

class Cursor {
constructor(activity) {
this.activity = activity;
this.cursorContainer = new Map();
this.nameContainer = new Map();
}

createCursor(id) {
const cursorDiv = document.createElement("div");
const nameDiv = document.createElement("div");
const name = document.createElement("h6");
const collaboratorName = this.nameContainer.get(id);
const arrowHtml = `<i class="material-icons" style="font-size: 25px; color: rgb(178, 190, 181); opacity: 0.8; margin-top: 1px;">navigation</i>`;

cursorDiv.style.cssText = `
display: flex;
justify-content: center;
left: 60vh;
bottom: 60vh;
position: absolute;
background-color: rgba(0,0,0,0);
padding: 5px;
width: 80px;
z-index: 1;
height: 60px
`;
// eslint-disable-next-line quotes
nameDiv.style.cssText = `
position: absolute;
background-color: rgb(178, 190, 181);
opacity: 0.8;
padding: 5px;
border: 1px solid #ccc;
border-radius: 50px;
width: 70px;
z-index: 1;
height: 15px;
display: flex;
justify-content: center;
top: 35px;
`;

name.textContent = collaboratorName;
name.style.cssText = `
position: absolute;
font-size: 12px;
color: black;
z-index: 2;
top: -22px;
`;

const arrowSign = document.createRange().createContextualFragment(arrowHtml);
nameDiv.appendChild(name);
cursorDiv.appendChild(arrowSign);
cursorDiv.appendChild(nameDiv);
document.body.appendChild(cursorDiv);
this.cursorContainer.set(id, cursorDiv);
}

removeCursor(id) {
const cursor = this.cursorContainer.get(id);
if (cursor) {
document.body.removeChild(cursor);
this.nameContainer.delete(id);
this.cursorContainer.delete(id);
}
}

trackCursor() {
if (this.activity.collaboration.hasCollaborationStarted) {
let counter = 0
const EMIT_THRESHOLD = 5;
const emitMouseMove = (e) => {
counter++;
if (counter >= EMIT_THRESHOLD) {
const roomID = this.activity.room_id;
const xScroll = this.activity.blocksContainer.x;
const yScroll = this.activity.blocksContainer.y;
const data = { room_id: roomID, x: e.pageX, y: e.pageY, scrollx: xScroll, scrolly: yScroll };
this.activity.collaboration.socket.emit("mouse-move", data);
counter = 0;
};
};
document.addEventListener("mousemove", emitMouseMove);
}
}

}
82 changes: 78 additions & 4 deletions js/collaboration/collaboration.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,23 @@ class Collaboration {
this.PORT = "http://localhost:8080/";
this.hasCollaborationStarted = false;
this.updatedProjectHtml = null;
this.randomNames = [
'Macrotis',
'Setonix',
'Petaurus',
'Marmosa',
'Macropus',
'Dasyurus',
'Caluromys',
'Acrobates',
'Didelphis',
'Philander',
'Lutreolina',
'Notoryctes',
'Metachirus',
'Dromiciops',
'Chaeropus'
];
}

// Convert the blockList into html
Expand All @@ -44,20 +61,65 @@ class Collaboration {
};

// Make calls to the socket server
makeConnection = (ID) => {
makeConnection = (room_id, name) => {
// connect to the local server
const socket = io(this.PORT);
socket.on("connect", () => {
this.socket = socket;
try {
console.log("connected to the server");
this.hasCollaborationStarted = true;
socket.emit("joinRoom", ID);
socket.emit("joinRoom", {room_id, name});
this.activity.collabCursor.trackCursor();
} catch (error) {
console.log("Connection failed", error);
}
});

socket.on("existing-cursor", (cursorArray) => {
if (cursorArray.length > 1) {
cursorArray.forEach(({id}) => {
const ID = id[0];
if (ID !== this.socket.id){
this.activity.collabCursor.createCursor(ID);
}
});
}
});

socket.on("new-cursor", ({id}) => {
this.activity.collabCursor.createCursor(id);
});

socket.on("remove-cursor", (id) => {
this.activity.collabCursor.removeCursor(id);
})

socket.on("mouse-move", (data) => {
const { socket_id, x, y, scrollx, scrolly } = data;
const cursor = this.activity.collabCursor.cursorContainer.get(socket_id);
if (cursor) {
const currentScrollX = this.activity.blocksContainer.x;
const currentScrollY = this.activity.blocksContainer.y;
const adjustedX = x - (scrollx - currentScrollX);
const adjustedY = y - (scrolly - currentScrollY);
cursor.style.left = `${adjustedX}px`;
cursor.style.top = `${adjustedY}px`;
}
});

socket.on("add-new-name", ({id, name}) => {
this.activity.collabCursor.nameContainer.set(id, name);
})

socket.on("add-existing-names", ((namesArray) => {
if (namesArray.length > 1) {
namesArray.forEach(({id, name}) => {
this.activity.collabCursor.nameContainer.set(id, name);
});
}
}));

socket.on("connect_error", () => {
this.attempts++;
console.log("Failed to connect to the socket server. Retrying in few seconds...");
Expand All @@ -81,9 +143,21 @@ class Collaboration {
});
};

// Generate a random name for the user
generateRandomName = () => {
const randomNum = Math.floor(Math.random() * 14);
const prefix = this.randomNames[randomNum];
const suffix = Math.floor(Math.random() * 50);
const name = prefix + suffix;
return name;
}

// Start the collaboration
startCollaboration = (ID) => {
this.makeConnection(ID);
startCollaboration = (ID, name) => {
if (!name) {
name = this.generateRandomName();
}
this.makeConnection(ID, name);
};
}

Loading

0 comments on commit dd3e410

Please sign in to comment.