diff --git a/changelogs/v0-50-3.md b/changelogs/v0-50-3.md new file mode 100644 index 00000000..f4ae6faf --- /dev/null +++ b/changelogs/v0-50-3.md @@ -0,0 +1,17 @@ +* [+10/-10][app | chat_server | comty.js | file_server | marketplace_server | music_server | server | wrapper] [Bump version to 0.50.3](https://github.com/ragestudio/comty/commit/ae985c4960742e8df318871493148e487cad9943) - by [@SrGooglo](https://github.com/srgooglo) + +* [+2/-1][app] [added `lru-cache`](https://github.com/ragestudio/comty/commit/2dfcd945d64f2598e95ba09e96c36dd617ad76cf) - by [@SrGooglo](https://github.com/srgooglo) + +* [+7/-1][app] [set `latencyHint` to `playback`](https://github.com/ragestudio/comty/commit/fcef9a9683426d2acef7dbfb4b3c0350846b7a3e) - by [@SrGooglo](https://github.com/srgooglo) + +* [+7/-6][app] [filter non numbers values](https://github.com/ragestudio/comty/commit/7d13c94cfbba56d9bcf779bae140b9e06017a3b2) - by [@SrGooglo](https://github.com/srgooglo) + +* [+9/-2][app] [added `usePadding` option](https://github.com/ragestudio/comty/commit/42548d2af718c57fa675862790a38cb8e26c2041) - by [@SrGooglo](https://github.com/srgooglo) + +* [+17/-10][app] [improve label display](https://github.com/ragestudio/comty/commit/e5fdc90a9ee26486d7c1a310e78793111188bdd6) - by [@SrGooglo](https://github.com/srgooglo) + +* [+11/-2][app] [add step && marks](https://github.com/ragestudio/comty/commit/76dd480254282f98678a1d081fc1b6651a03207c) - by [@SrGooglo](https://github.com/srgooglo) + +* [+1/-1][app] [decrease default sample rate to `48000` to avoid device related issues](https://github.com/ragestudio/comty/commit/e1ef3ff2ac109d9674137dbbf99cf1aba729ad31) - by [@SrGooglo](https://github.com/srgooglo) + +* [+31/-0][v0-50-2.md] [added changelog](https://github.com/ragestudio/comty/commit/e339c98986a8ce6fb6366272dbcaa1f29bb797e8) - by [@SrGooglo](https://github.com/srgooglo) \ No newline at end of file diff --git a/package.json b/package.json index 65e20846..252bbee0 100755 --- a/package.json +++ b/package.json @@ -31,5 +31,5 @@ "form-data": "^4.0.0", "pm2": "5.3.0" }, - "version": "0.50.3" + "version": "0.50.4" } \ No newline at end of file diff --git a/packages/app/constants/settings/about/index.jsx b/packages/app/constants/settings/about/index.jsx index 51caafc7..ada173a6 100755 --- a/packages/app/constants/settings/about/index.jsx +++ b/packages/app/constants/settings/about/index.jsx @@ -70,6 +70,15 @@ export default { const [serverHealth, setServerHealth] = React.useState(null) const [secureConnection, setSecureConnection] = React.useState(false) const [connectionPing, setConnectionPing] = React.useState({}) + const [capInfo, setCapInfo] = React.useState(null) + + const setCapacitorInfo = async () => { + if (Capacitor.Plugins.App) { + const info = await Capacitor.Plugins.App.getInfo() + + setCapInfo(info) + } + } const checkServerVersion = async () => { const serverManifest = await app.cores.api.customRequest() @@ -117,6 +126,8 @@ export default { fetchServerHealth() measurePing() + setCapacitorInfo() + const measureInterval = setInterval(() => { fetchServerHealth() measurePing() @@ -191,6 +202,8 @@ export default { alignItems: "center", gap: "0.5rem", fontSize: "1.4rem", + justifyContent: "space-evenly", + width: "100%", }} >
+ + { + capInfo &&
+
+
+ +
+ +

App ID

+
+ +
+ {capInfo.id} +
+
+ } + + { + capInfo &&
+
+
+ +
+ +

App Build

+
+ +
+ {capInfo.build} +
+
+ } + + { + capInfo &&
+
+
+ +
+ +

App Version

+
+ +
+ {capInfo.version} +
+
+ } } diff --git a/packages/app/package.json b/packages/app/package.json index c8bcbe06..cd5a9906 100755 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -1,6 +1,6 @@ { "name": "@comty/web-app", - "version": "0.50.3", + "version": "0.50.4", "license": "LGPL-2.1", "main": "electron/main", "author": "RageStudio", @@ -51,6 +51,7 @@ "antd-mobile": "^5.31.0", "axios": "^1.4.0", "buffer": "^6.0.3", + "capacitor-music-controls-plugin-v3": "^1.1.0", "classnames": "2.3.1", "dexie": "^3.2.3", "dompurify": "^3.0.0", diff --git a/packages/app/src/cores/player/player.core.js b/packages/app/src/cores/player/player.core.js index 175797f4..1a5abb01 100755 --- a/packages/app/src/cores/player/player.core.js +++ b/packages/app/src/cores/player/player.core.js @@ -1,6 +1,8 @@ import Core from "evite/src/core" import { Observable } from "object-observer" import { FastAverageColor } from "fast-average-color" +import { CapacitorMusicControls } from 'capacitor-music-controls-plugin-v3' + //import { LRUCache } from "lru-cache/dist/mjs/index" import PlaylistModel from "comty.js/models/playlists" @@ -34,6 +36,125 @@ const defaultAudioProccessors = [ CompressorProcessorNode, ] +class MediaSession { + initialize() { + CapacitorMusicControls.addListener("controlsNotification", (info) => { + console.log(info) + + this.handleControlsEvent(info) + }) + + // ANDROID (13, see bug above as to why it's necessary) + document.addEventListener("controlsNotification", (event) => { + console.log(event) + + const info = { message: event.message, position: 0 } + + this.handleControlsEvent(info) + }) + } + + update(manifest) { + if ("mediaSession" in navigator) { + return navigator.mediaSession.metadata = new MediaMetadata({ + title: manifest.title, + artist: manifest.artist, + album: manifest.album, + artwork: [ + { + src: manifest.cover ?? manifest.thumbnail, + sizes: "512x512", + type: "image/jpeg", + } + ], + }) + } + + return CapacitorMusicControls.create({ + track: manifest.title, + artist: manifest.artist, + album: manifest.album, + cover: manifest.cover, + + hasPrev: false, + hasNext: false, + hasClose: true, + + isPlaying: true, + dismissable: false, + + playIcon: "media_play", + pauseIcon: "media_pause", + prevIcon: "media_prev", + nextIcon: "media_next", + closeIcon: "media_close", + notificationIcon: "notification" + }) + } + + updateIsPlaying(to, timeElapsed = 0) { + if ("mediaSession" in navigator) { + return navigator.mediaSession.playbackState = to ? "playing" : "paused" + } + + return CapacitorMusicControls.updateIsPlaying({ + isPlaying: to, + elapsed: timeElapsed, + }) + } + + destroy() { + if ("mediaSession" in navigator) { + navigator.mediaSession.playbackState = "none" + } + + this.active = false + + return CapacitorMusicControls.destroy() + } + + handleControlsEvent(action) { + const message = action.message + + switch (message) { + case "music-controls-next": { + return app.cores.player.playback.next() + } + case "music-controls-previous": { + return app.cores.player.playback.previous() + } + case "music-controls-pause": { + return app.cores.player.playback.pause() + } + case "music-controls-play": { + return app.cores.player.playback.play() + } + case "music-controls-destroy": { + return app.cores.player.playback.stop() + } + + // External controls (iOS only) + case "music-controls-toggle-play-pause": { + return app.cores.player.playback.toogle() + } + + // Headset events (Android only) + // All media button events are listed below + case "music-controls-media-button": { + return app.cores.player.playback.toogle() + } + case "music-controls-headset-unplugged": { + return app.cores.player.playback.pause() + } + case "music-controls-headset-plugged": { + return app.cores.player.playback.play() + } + default: + break; + } + } +} + // TODO: Check if source playing is a stream. Also handle if it's a stream resuming after a pause will seek to the last position export default class Player extends Core { static dependencies = [ @@ -49,6 +170,8 @@ export default class Player extends Core { static defaultSampleRate = 48000 + native_controls = new MediaSession() + currentDomWindow = null audioContext = new AudioContext({ @@ -370,6 +493,7 @@ export default class Player extends Core { async onInitialize() { this.initializeAudioProcessors() this.observeStateChanges() + this.native_controls.initialize() } async initializeBeforeRuntimeInitialize() { @@ -646,7 +770,6 @@ export default class Player extends Core { // storage media data on browser cache to improve performance instanceObj.media.data = instanceObj.audioElement - return instanceObj } @@ -736,33 +859,12 @@ export default class Player extends Core { instance.audioElement.play() // set navigator metadata - if ("mediaSession" in navigator) { - navigator.mediaSession.metadata = new MediaMetadata({ - title: instance.manifest.title, - artist: instance.manifest.artist, - album: instance.manifest.album, - artwork: [ - { - src: instance.manifest.cover ?? instance.manifest.thumbnail, - sizes: "512x512", - type: "image/jpeg", - } - ], - }) - } + this.native_controls.update(instance.manifest) // check if the audio is a live stream when metadata is loaded instance.audioElement.addEventListener("loadedmetadata", () => { console.log("loadedmetadata", instance.audioElement.duration) - // if ("mediaSesion" in navigator) { - // navigator.mediaSession.setPositionState({ - // duration: instance.audioElement.duration, - // playbackRate: instance.audioElement.playbackRate, - // position: instance.audioElement.currentTime, - // }) - // } - if (instance.audioElement.duration === Infinity) { instance.manifest.stream = true @@ -923,9 +1025,7 @@ export default class Player extends Core { resolve() }, gradualFadeMs) - if ("mediaSession" in navigator) { - navigator.mediaSession.playbackState = "paused" - } + this.native_controls.updateIsPlaying(false) }) } @@ -949,9 +1049,7 @@ export default class Player extends Core { this.audioContext.currentTime + (gradualFadeMs / 1000) ) - if ("mediaSession" in navigator) { - navigator.mediaSession.playbackState = "playing" - } + this.native_controls.updateIsPlaying(true) }) } @@ -967,9 +1065,7 @@ export default class Player extends Core { this.audioQueue = [] - if ("mediaSession" in navigator) { - navigator.mediaSession.playbackState = "none" - } + this.native_controls.destroy() } close() { diff --git a/packages/chat_server/package.json b/packages/chat_server/package.json index c48983e4..740c9adc 100755 --- a/packages/chat_server/package.json +++ b/packages/chat_server/package.json @@ -1,6 +1,6 @@ { "name": "@comty/chat_server", - "version": "0.50.3", + "version": "0.50.4", "main": "dist/index.js", "scripts": { "build": "corenode-cli build", diff --git a/packages/comty.js/package.json b/packages/comty.js/package.json index 2342a72e..51e2f03b 100644 --- a/packages/comty.js/package.json +++ b/packages/comty.js/package.json @@ -1,6 +1,6 @@ { "name": "comty.js", - "version": "0.50.3", + "version": "0.50.4", "main": "./dist/index.js", "author": "RageStudio ", "scripts": { diff --git a/packages/file_server/package.json b/packages/file_server/package.json index 1139d3e3..2eea3e79 100644 --- a/packages/file_server/package.json +++ b/packages/file_server/package.json @@ -1,6 +1,6 @@ { "name": "@comty/file_server", - "version": "0.50.3", + "version": "0.50.4", "main": "dist/index.js", "scripts": { "build": "corenode-cli build", diff --git a/packages/marketplace_server/package.json b/packages/marketplace_server/package.json index 903cc2b2..8b3bb36a 100644 --- a/packages/marketplace_server/package.json +++ b/packages/marketplace_server/package.json @@ -1,6 +1,6 @@ { "name": "@comty/marketplace_server", - "version": "0.50.3", + "version": "0.50.4", "main": "dist/index.js", "scripts": { "build": "corenode-cli build", diff --git a/packages/music_server/package.json b/packages/music_server/package.json index cd15d31b..76fcfa97 100644 --- a/packages/music_server/package.json +++ b/packages/music_server/package.json @@ -1,6 +1,6 @@ { "name": "@comty/music_server", - "version": "0.50.3", + "version": "0.50.4", "main": "dist/index.js", "scripts": { "build": "corenode-cli build", diff --git a/packages/server/package.json b/packages/server/package.json index 1e1f1fb8..c0731ae6 100755 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -1,6 +1,6 @@ { "name": "@comty/server", - "version": "0.50.3", + "version": "0.50.4", "main": "dist/index.js", "scripts": { "build": "corenode-cli build", diff --git a/packages/wrapper/package.json b/packages/wrapper/package.json index 59b958bd..d4ce2734 100755 --- a/packages/wrapper/package.json +++ b/packages/wrapper/package.json @@ -1,6 +1,6 @@ { "name": "@comty/web-wrapper", - "version": "0.50.3", + "version": "0.50.4", "main": "./src/index.js", "license": "MIT", "scripts": {