Skip to content

Commit

Permalink
Merge pull request #19 from andrewmcgivery/beta
Browse files Browse the repository at this point in the history
Version 1.2.0
  • Loading branch information
andrewmcgivery committed Feb 17, 2024
2 parents 98316ae + 9a5bdb0 commit 9f66899
Show file tree
Hide file tree
Showing 28 changed files with 3,035 additions and 465 deletions.
12 changes: 12 additions & 0 deletions README.md
Expand Up @@ -26,6 +26,18 @@ Additionally, when listening to a custom soundscape, you can use the new "next"
![Screenshot of editing a custom soundscape](screenshot4.png)
![Screenshot of soundscapes player while playing a custom soundscape](screenshot5.png)

### My Music - Local Music Library

The "My Music" soundscape allows you to have a full music player experience right within Obsidian using your local MP3 music files. Upon selecting your local music folder, the plugin will index your music and occasionally re-index it in the background.

My Music supports playing with the mini-player in the status bar as well as a new dedicated My Music view with a new icon on the Ribbon sidebar once the "My Music" soundscape is selected. You can close this view and the music will continue playing.

Within the My Music view, you can play, pause, next, previous, seek, shuffle, and search.

![Settings view with My Music selected](screenshot6.png)

![My Music view within Obsidian](screenshot7.png)

## Requesting New Soundscapes

Have an idea for a new Soundscape? [Open an issue](https://github.com/andrewmcgivery/obsidian-soundscapes/issues/new) and link a Youtube video and why we should add it!
Expand Down
79 changes: 79 additions & 0 deletions React/Components/App/App.scss
@@ -0,0 +1,79 @@
.soundscapesmymusic {
.view-header {
display: none;
}

.view-content {
padding: 0;
}

.soundscapesmymusic-musiclist {
overflow: scroll;
position: absolute;
top: 60px;
left: 0;
right: 0;
bottom: 0;
z-index: 400;
padding-bottom: 40px;

.soundscapesmymusic-musiclist-table {
border-collapse: collapse;
width: 100%;

thead {
tr {
text-align: left;
background-color: var(--background-secondary);
position: sticky;
top: 0;
z-index: 400;

th {
padding: 8px 12px;
font-size: 0.7em;
}
}
}

tbody {
tr {
&:nth-child(odd) {
background-color: var(--background-primary);
}

&:nth-child(even) {
background-color: var(--background-primary-alt);
}

td {
padding: 6px 12px;
font-size: 1em;
cursor: pointer;
vertical-align: middle;
line-height: 1;

&:first-child {
width: 0;
padding-right: 0;
}

.lucide-icon {
display: block;
line-height: 0;
color: var(--text-accent);

svg {
height: 15px;
}
}
}

&:hover {
background-color: var(--background-modifier-hover);
}
}
}
}
}
}
104 changes: 104 additions & 0 deletions React/Components/App/App.tsx
@@ -0,0 +1,104 @@
import React, { useEffect, useState } from "react";
import { useObsidianPluginContext } from "../../Context/ObsidianPluginContext";
import Icon from "../Icon/Icon";
import Header from "../Header/Header";
import secondsToMinutesAndSeconds from "../../Utils/secondsToMinutesAndSeconds";
import { LocalPlayerState } from "src/Types/Interfaces";
import { PLAYER_STATE } from "src/Types/Enums";
import { SoundscapesPluginSettings } from "src/Settings/Settings";

const App = () => {
const { settingsObservable, localPlayerStateObservable, plugin } =
useObsidianPluginContext();
const [settings, setSettings] = useState<SoundscapesPluginSettings>(
settingsObservable?.getValue()
);
const [localPlayerState, setLocalPlayerState] = useState<LocalPlayerState>(
localPlayerStateObservable?.getValue()
);

/**
* Subscribe to settings from Obsidian
*/
useEffect(() => {
const unsubscribe = settingsObservable?.onChange(
(newSettings: SoundscapesPluginSettings) => {
setSettings(newSettings);
}
);

return () => {
unsubscribe?.();
};
}, [setSettings]);

/**
* Subscribe to local player state from Obsidian
*/
useEffect(() => {
const unsubscribe = localPlayerStateObservable?.onChange(
(newState: LocalPlayerState) => {
setLocalPlayerState(newState);
}
);

return () => {
unsubscribe?.();
};
}, [setLocalPlayerState]);

return (
<>
<Header />
<div className="soundscapesmymusic-musiclist">
<table className="soundscapesmymusic-musiclist-table">
<thead>
<tr>
<th></th>
<th>Title</th>
<th>Artist</th>
<th>Album</th>
<th>Time</th>
</tr>
</thead>
<tbody>
{settings.myMusicIndex.map((song) => (
<tr
key={song.fullPath}
onDoubleClick={() =>
plugin?.changeMyMusicTrack(song.fileName)
}
>
<td>
{localPlayerState.currentTrack?.fileName ===
song.fileName &&
localPlayerState.playerState ===
PLAYER_STATE.PLAYING && (
<Icon name="volume-2" />
)}

{localPlayerState.currentTrack?.fileName ===
song.fileName &&
localPlayerState.playerState ===
PLAYER_STATE.PAUSED && (
<Icon name="volume" />
)}
</td>
<td>{song.title}</td>
<td>{song.artist}</td>
<td>{song.album}</td>
<td>
{secondsToMinutesAndSeconds(
song.duration || 0
)}
</td>
</tr>
))}
</tbody>
</table>
</div>
</>
);
};

export default App;
159 changes: 159 additions & 0 deletions React/Components/Header/Header.scss
@@ -0,0 +1,159 @@
.soundscapesmymusic {
.soundscapesmymusic-header {
background-color: var(--background-primary);
display: flex;
align-items: center;
padding: 0 42px;
height: 60px;
position: absolute;
top: 0;
left: 0;
right: 0;
gap: 1%;

.soundscapesmymusic-left {
flex: 1;
display: flex;
align-items: center;

.soundscapesmymusic-left-controls {
display: flex;
align-items: center;
gap: 12px;

.soundscapesmymusic-left-controls-button {
color: var(--text-muted);
background-color: transparent;
border: none;
box-shadow: none;
cursor: pointer;
padding: 0;
display: block;
line-height: 1;
--icon-size: 1.5em;

&:hover {
color: var(--text-normal);
}

&.soundscapesmymusic-left-controls-button--large {
--icon-size: 2em;
}
}
}
}

.soundscapesmymusic-volume {
flex: 1;
align-items: left;
}

.soundscapesmymusic-middle {
flex: 3;
height: 100%;
border-left: 1px solid var(--background-modifier-border);
border-right: 1px solid var(--background-modifier-border);
background-color: var(--background-primary-alt);
display: flex;
flex-direction: column;
height: 100%;
justify-content: space-between;
overflow: hidden;
min-width: 250px;

.soundscapesmymusic-middle-line1 {
display: flex;
align-items: center;
justify-content: space-between;
font-size: 1em;
padding: 8px 8px 0 8px;

.soundscapesmymusic-middle-line1-button {
color: var(--text-muted);
background-color: transparent;
border: none;
box-shadow: none;
cursor: pointer;
padding: 0;
display: block;
line-height: 1;
--icon-size: 1em;
height: auto;

&:hover {
color: var(--text-normal);
}

&.soundscapesmymusic-middle-line1-button--active {
color: var(--text-accent);
}
}

.soundscapesmymusic-middle-line1-left {
width: 30px;
}

.soundscapesmymusic-middle-line1-title {
flex: 1;
text-align: center;
white-space: nowrap;
overflow: hidden;
position: relative;

&.soundscapesmymusic-middle-line1-title--scroll {
.soundscapesmymusic-middle-line1-title-text {
display: inline-block;
animation: marquee 10s linear infinite;
}
}
}

.soundscapesmymusic-middle-line1-right {
width: 30px;
text-align: right;
}
}

.soundscapesmymusic-middle-line2 {
display: flex;
align-items: center;
justify-content: space-between;
font-size: 0.8em;
color: var(--text-muted);
padding: 0 8px;

.soundscapesmymusic-middle-line2-left {
width: 60px;
}

.soundscapesmymusic-middle-line2-artist {
flex: 1;
text-align: center;
white-space: nowrap;
overflow: hidden;
}

.soundscapesmymusic-middle-line2-right {
width: 60px;
text-align: right;
}
}

.soundscapesmymusic-middle-seekbar {
width: 100%;
margin: 0;

&::-webkit-slider-thumb {
border-radius: 8px;
width: 8px;
}
}
}

.soundscapesmymusic-right {
flex: 2;
display: flex;
justify-content: end;
}
}
}

0 comments on commit 9f66899

Please sign in to comment.