Skip to content

Commit

Permalink
Resolve patch/MOOD-91: explicit content filter (#98)
Browse files Browse the repository at this point in the history
* added explicit icon, switch to settings, and updated result list item test

* fixed spotify helper tests

* fixed tests

* fixed build errors

* added in explicit content filtering

* added to tests
  • Loading branch information
lorenzoz23 authored Dec 30, 2020
1 parent 47a32c6 commit cc000c2
Show file tree
Hide file tree
Showing 14 changed files with 133 additions and 26 deletions.
9 changes: 7 additions & 2 deletions common/QueueProcessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,13 @@ interface ProcessQueueProps {
entities: PropertyTrack[]
comparator: any
count: number
explicit: boolean
}
export const processQueue = (props: ProcessQueueProps) => {
const { entities, comparator, count } = props
return entities.sort(comparator).slice(0, count)
const { entities, comparator, count, explicit } = props
if (explicit) return entities.sort(comparator).slice(0, count)
else {
const filteredEntities = entities.filter((entity) => !entity.explicit)
return filteredEntities.sort(comparator).slice(0, count)
}
}
14 changes: 14 additions & 0 deletions common/QueueProcessors.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,29 @@ describe("QueueProcessors", () => {
entities: mockPropertyTracks,
comparator: happyComparator,
count: 4,
explicit: true,
}).length
).toEqual(4)
})

it("returns an array that is less than count because of explicit content filtering", () => {
expect(
processQueue({
entities: mockPropertyTracks,
comparator: happyComparator,
count: 9,
explicit: false,
}).length
).toEqual(8)
})

it("returns array that is sorted to given comparator", () => {
expect(
processQueue({
entities: mockPropertyTracks,
comparator: happyComparator,
count: 1,
explicit: true,
})
).toEqual([
{
Expand Down Expand Up @@ -47,6 +60,7 @@ describe("QueueProcessors", () => {
type: "audio_features",
uri: "spotify:track:2SPxgEush9C8GS5RqgXdqi",
valence: 0.831,
explicit: false,
},
])
})
Expand Down
6 changes: 6 additions & 0 deletions common/SpotifyHelper.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ describe("SpotifyHelper", () => {
imageLink: track.album.images[0].url,
id: track.id,
uri: track.uri,
explicit: track.explicit,
}
expect(await helper.getRecommendedFromSeed("tracks", "seed", 1)).toEqual([expected])
expect(spy).toHaveBeenCalledWith(
Expand All @@ -135,6 +136,7 @@ describe("SpotifyHelper", () => {
imageLink: track.album.images[0].url,
id: track.id,
uri: track.uri,
explicit: track.explicit,
}
expect(await helper.getRecommendedFromSeed("artists", "seed", 1)).toEqual([expected])
expect(spy).toHaveBeenCalledWith(
Expand All @@ -152,6 +154,7 @@ describe("SpotifyHelper", () => {
imageLink: track.album.images[0].url,
id: track.id,
uri: track.uri,
explicit: track.explicit,
}
expect(await helper.getRecommendedFromSeed("genres", "seed", 1)).toEqual([expected])
expect(spy).toHaveBeenCalledWith(
Expand Down Expand Up @@ -192,6 +195,7 @@ describe("SpotifyHelper", () => {
imageLink: track.album.images[0].url,
id: track.id,
uri: track.uri,
explicit: track.explicit,
}
expect(await helper.getRecommendedSongs(["whatever"])).toEqual([expected])
})
Expand Down Expand Up @@ -226,6 +230,7 @@ describe("SpotifyHelper", () => {
imageLink: track.album.images[0].url,
id: track.id,
uri: track.uri,
explicit: track.explicit,
}
expect(await helper.getTopArtistsTopSongs(1)).toEqual([expected])
})
Expand All @@ -252,6 +257,7 @@ describe("SpotifyHelper", () => {
imageLink: "",
id: "abc",
uri: "xyz",
explicit: true,
}
const pTrack: PropertyTrack = {
...track,
Expand Down
7 changes: 6 additions & 1 deletion common/SpotifyHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export class SpotifyHelper {
imageLink: track.album.images[0] ? track.album.images[0].url : "",
id: track.id,
uri: track.uri,
explicit: track.explicit,
}))
})
tracks.push(...temp)
Expand All @@ -66,6 +67,7 @@ export class SpotifyHelper {
imageLink: track.album.images[0] ? track.album.images[0].url : "",
id: track.id,
uri: track.uri,
explicit: track.explicit,
}))
})
tracks.push(...temp)
Expand Down Expand Up @@ -126,6 +128,7 @@ export class SpotifyHelper {
imageLink: item.track.album.images[0] ? item.track.album.images[0].url : "",
id: item.track.id,
uri: item.track.uri,
explicit: item.track.explicit,
}))
})
if (temp.length !== 0) {
Expand Down Expand Up @@ -159,6 +162,7 @@ export class SpotifyHelper {
imageLink: track.album.images[0] ? track.album.images[0].url : "",
id: track.id,
uri: track.uri,
explicit: track.explicit,
}))
})
} catch (e) {
Expand All @@ -168,7 +172,7 @@ export class SpotifyHelper {

async getRecommendedSongs(genres: string[]): Promise<Track[]> {
try {
return await this.getRecommendedFromSeed("genres", genres.join(","), 50)
return await this.getRecommendedFromSeed("genres", genres.join(","), 100)
} catch (e) {
throw e
}
Expand All @@ -195,6 +199,7 @@ export class SpotifyHelper {
: "",
id: data.tracks[0].id,
uri: data.tracks[0].uri,
explicit: data.tracks[0].explicit,
}
})
})
Expand Down
2 changes: 2 additions & 0 deletions common/hooks/useSpotify.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ export const SpotifyProvider: React.FunctionComponent<SpotifyProviderProps> = (p
genres: string[]
): Promise<Track[]> => {
let tracks = []
const explicit = localStorage.getItem("allowExplicit") === "1" ? true : false

if (trackSource.includes(TrackSource.TOP_SONGS)) {
Sentry.captureMessage(`source includes top songs`)
Expand Down Expand Up @@ -351,6 +352,7 @@ export const SpotifyProvider: React.FunctionComponent<SpotifyProviderProps> = (p
entities: trackSet,
comparator: comparator,
count: count,
explicit: explicit,
})
}

Expand Down
9 changes: 9 additions & 0 deletions common/mocks/PropertyTracks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export const mockPropertyTracks = [
type: "audio_features",
uri: "spotify:track:2SPxgEush9C8GS5RqgXdqi",
valence: 0.831,
explicit: false,
},
{
acousticness: 0.107,
Expand All @@ -48,6 +49,7 @@ export const mockPropertyTracks = [
type: "audio_features",
uri: "spotify:track:7zoZd2MuTaQEdF1rlq6Vv1",
valence: 0.76,
explicit: true,
},
{
acousticness: 0.559,
Expand All @@ -73,6 +75,7 @@ export const mockPropertyTracks = [
type: "audio_features",
uri: "spotify:track:73SBAGI4fPFm4VkB3NjXq8",
valence: 0.712,
explicit: false,
},
{
acousticness: 0.422,
Expand All @@ -98,6 +101,7 @@ export const mockPropertyTracks = [
type: "audio_features",
uri: "spotify:track:01EZT06EIdnVOLl96Parta",
valence: 0.706,
explicit: false,
},
{
acousticness: 0.828,
Expand All @@ -123,6 +127,7 @@ export const mockPropertyTracks = [
type: "audio_features",
uri: "spotify:track:2GmGy1eJTvPACm3ekX0hxD",
valence: 0.118,
explicit: false,
},
{
acousticness: 0.722,
Expand All @@ -148,6 +153,7 @@ export const mockPropertyTracks = [
type: "audio_features",
uri: "spotify:track:2GCt4EYq76bDtuOyYxC2AD",
valence: 0.119,
explicit: false,
},
{
acousticness: 0.76,
Expand All @@ -173,6 +179,7 @@ export const mockPropertyTracks = [
type: "audio_features",
uri: "spotify:track:0Kp0CPUzFcEqhBbHoRKtbm",
valence: 0.144,
explicit: false,
},
{
acousticness: 0.864,
Expand All @@ -198,6 +205,7 @@ export const mockPropertyTracks = [
type: "audio_features",
uri: "spotify:track:5uQRmdIqyMmKPWJcot4UmV",
valence: 0.158,
explicit: false,
},
{
acousticness: 0.643,
Expand All @@ -223,5 +231,6 @@ export const mockPropertyTracks = [
type: "audio_features",
uri: "spotify:track:2OsypaDnRwVyJdWrytx9Qr",
valence: 0.167,
explicit: false,
},
]
9 changes: 9 additions & 0 deletions components/results/result-list-item/result-list-item.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const mockTrack: Track = {
imageLink: "",
id: "1",
uri: "",
explicit: true,
}

describe("<ResultListItem />", () => {
Expand All @@ -26,6 +27,14 @@ describe("<ResultListItem />", () => {
expect(wrapper.text()).to.contain(mockTrack.name)
})

it("renders explicit icon if track is explicit", () => {
const wrapper = render(
<ResultListItem size={"large"} dispatch={jest.fn()} track={mockTrack} />
)

expect(wrapper.find("#explicit-icon")).to.have.length(1)
})

it("renders the track artist", () => {
const wrapper = render(
<ResultListItem size={"large"} dispatch={jest.fn()} track={mockTrack} />
Expand Down
1 change: 1 addition & 0 deletions types/Track.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export interface Track {
imageLink: string
id: string
uri: string
explicit: boolean
}

export interface AudioFeatures {
Expand Down
2 changes: 2 additions & 0 deletions ui/results-overview/ResultsOverview.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const mockTracks: Track[] = [
imageLink: "",
id: "1",
uri: "",
explicit: true,
},
{
previewUrl: "",
Expand All @@ -20,6 +21,7 @@ const mockTracks: Track[] = [
imageLink: "",
id: "2",
uri: "",
explicit: false,
},
]

Expand Down
2 changes: 2 additions & 0 deletions ui/results-overview/ResultsOverview.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const mockTracks: Track[] = [
imageLink: "",
id: "1",
uri: "",
explicit: true,
},
{
previewUrl: "",
Expand All @@ -24,6 +25,7 @@ const mockTracks: Track[] = [
imageLink: "",
id: "2",
uri: "",
explicit: false,
},
]

Expand Down
1 change: 1 addition & 0 deletions ui/track/Track.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const mockTrack: TrackType = {
imageLink: "https://i.scdn.co/image/ab67616d0000b273e9a375a80097985178b73c4d",
id: "1",
uri: "",
explicit: true,
}

export default { title: "Track" }
Expand Down
64 changes: 44 additions & 20 deletions ui/track/Track.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { useDrag } from "react-use-gesture"
import { motion, useMotionValue, useTransform } from "framer-motion"
import { MoreHoriz as More } from "@styled-icons/material/MoreHoriz"
import { RemoveCircle } from "@styled-icons/material-twotone/RemoveCircle"
import { Explicit } from "@styled-icons/material-twotone/Explicit"
//@styled-icons/material-rounded/RemoveCircle
//@styled-icons/material-rounded/RemoveCircleOutline

Expand Down Expand Up @@ -121,16 +122,27 @@ export const Track: React.FunctionComponent<TrackProps> = (trackProps) => {
)}
</Box>
<Box align="start">
<Box overflow="hidden">
<Text
truncate
style={{ userSelect: "none" }}
textAlign="start"
weight="bold"
size="small"
>
{track.name}
</Text>
<Box direction="row" align="center" gap="xsmall">
<Box overflow="hidden">
<Text
truncate
style={{ userSelect: "none" }}
textAlign="start"
weight="bold"
size="small"
>
{track.name}
</Text>
</Box>
{track.explicit && (
<Box>
<Explicit
width="16px"
height="16px"
id="explicit-icon"
/>
</Box>
)}
</Box>
<Box overflow="hidden">
<Text
Expand Down Expand Up @@ -232,16 +244,28 @@ export const Track: React.FunctionComponent<TrackProps> = (trackProps) => {
)}
</Box>
<Box align="start">
<Box overflow="hidden">
<Text
truncate
style={{ userSelect: "none" }}
textAlign="start"
weight="bold"
size={size === "large" ? "xxlarge" : "xlarge"}
>
{track.name}
</Text>
<Box direction="row" align="center" gap="xsmall">
<Box overflow="hidden">
<Text
truncate
style={{ userSelect: "none" }}
textAlign="start"
weight="bold"
size={size === "large" ? "xxlarge" : "xlarge"}
>
{track.name}
</Text>
</Box>
{track.explicit && (
<Box>
<Explicit
width="24px"
height="24px"
title="explicit"
id="explicit-icon"
/>
</Box>
)}
</Box>
<Box overflow="hidden">
<Text
Expand Down
Loading

0 comments on commit cc000c2

Please sign in to comment.