add: profile connections, spotify connection
This commit is contained in:
parent
a5c2356940
commit
33ba576d4a
31 changed files with 931 additions and 19 deletions
40
crates/app/src/public/html/auth/connection.html
Normal file
40
crates/app/src/public/html/auth/connection.html
Normal file
|
@ -0,0 +1,40 @@
|
|||
{% extends "auth/base.html" %} {% block head %}
|
||||
<title>Connection</title>
|
||||
{% endblock %} {% block title %}Connection{% endblock %} {% block content %}
|
||||
<div class="w-full flex-col gap-2" id="status"><b>Working...</b></div>
|
||||
|
||||
{% if connection_type == "Spotify" and user and user.connections.Spotify and
|
||||
config.connections.spotify_client_id %}
|
||||
<script>
|
||||
setTimeout(async () => {
|
||||
const code = new URLSearchParams(window.location.search).get("code");
|
||||
const client_id = "{{ config.connections.spotify_client_id }}";
|
||||
const verifier = "{{ user.connections.Spotify[0].data.verifier }}";
|
||||
|
||||
if (!code) {
|
||||
alert("Connection failed (did not get code from Spotify)");
|
||||
return;
|
||||
}
|
||||
|
||||
const [token, refresh_token, expires_in] = await trigger(
|
||||
"spotify::get_token",
|
||||
[client_id, verifier, code],
|
||||
);
|
||||
|
||||
const profile = await trigger("spotify::profile", [token]);
|
||||
|
||||
const { message } = await trigger("connections::push_con_data", [
|
||||
"Spotify",
|
||||
{
|
||||
token,
|
||||
refresh_token,
|
||||
expires_in: expires_in.toString(),
|
||||
name: profile.display_name,
|
||||
},
|
||||
]);
|
||||
|
||||
document.getElementById("status").innerHTML =
|
||||
`<b>${message}.</b> You can now close this tab.`;
|
||||
}, 150);
|
||||
</script>
|
||||
{% endif %} {% endblock %}
|
|
@ -801,4 +801,50 @@ secondary=false, show_community=true) -%}
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{%- endmacro %}
|
||||
{%- endmacro %} {% macro spotify_playing(state, size="60px") -%} {% if state and
|
||||
state.data %}
|
||||
<div class="card-nest">
|
||||
<div class="card flex items-center justify-between gap-2 small">
|
||||
<div class="flex items-center gap-2">
|
||||
<b>Listening on</b>
|
||||
{{ icon "spotify" }}
|
||||
</div>
|
||||
|
||||
<span class="fade date short">{{ state.data.timestamp }}</span>
|
||||
</div>
|
||||
|
||||
<div class="card secondary flex gap-2">
|
||||
<a href="{{ state.external_urls.album }}">
|
||||
<img
|
||||
src="{{ state.external_urls.album_img }}"
|
||||
alt="Album cover"
|
||||
loading="lazy"
|
||||
class="avatar"
|
||||
style="--size: {{ size }}"
|
||||
/>
|
||||
</a>
|
||||
|
||||
<div class="flex flex-col">
|
||||
<h5 class="w-full">
|
||||
<a href="{{ state.external_urls.track }}" class="flush"
|
||||
>{{ state.data.track }}</a
|
||||
>
|
||||
</h5>
|
||||
|
||||
<span class="fade"
|
||||
><a href="{{ state.external_urls.artist }}" class="flush"
|
||||
>{{ state.data.artist }}</a
|
||||
></span
|
||||
>
|
||||
|
||||
<span
|
||||
hook="spotify_time_text"
|
||||
hook-arg:updated="{{ state.data.timestamp }}"
|
||||
hook-arg:progress="{{ state.data.progress_ms }}"
|
||||
hook-arg:duration="{{ state.data.duration_ms }}"
|
||||
hook-arg:display="full"
|
||||
></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %} {%- endmacro %}
|
||||
|
|
|
@ -105,6 +105,13 @@
|
|||
</div>
|
||||
|
||||
<div class="card flex flex-col gap-2">
|
||||
<!-- prettier-ignore -->
|
||||
<div style="display: contents;">
|
||||
{% if profile.connections.Spotify and profile.connections.Spotify[0].data.name and profile.connections.Spotify[0].show_on_profile %}
|
||||
{{ components::spotify_playing(state=profile.connections.Spotify[1]) }}
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="w-full flex justify-between items-center">
|
||||
<span class="notification chip">ID</span>
|
||||
<button
|
||||
|
|
|
@ -29,6 +29,11 @@
|
|||
{{ icon "cookie" }}
|
||||
<span>{{ text "settings:tab.sessions" }}</span>
|
||||
</a>
|
||||
|
||||
<a data-tab-button="connections" href="#/connections">
|
||||
{{ icon "cable" }}
|
||||
<span>{{ text "settings:tab.connections" }}</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="w-full flex flex-col gap-2" data-tab="account">
|
||||
|
@ -496,6 +501,46 @@
|
|||
</button>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="card w-full tertiary hidden flex flex-col gap-2"
|
||||
data-tab="connections"
|
||||
>
|
||||
<div class="card w-full flex flex-wrap gap-2">
|
||||
{% if config.connections.spotify_client_id and not
|
||||
user.connections.Spotify %}
|
||||
<button
|
||||
class="quaternary"
|
||||
onclick="trigger('spotify::create_connection', ['{{ config.connections.spotify_client_id }}'])"
|
||||
>
|
||||
{{ icon "spotify" }}
|
||||
<span>Spotify</span>
|
||||
</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% for key, value in user.connections %}
|
||||
<div class="card-nest">
|
||||
<div class="card small flex items-center gap-2">
|
||||
{% if key == "Spotify" %} {{ icon "spotify" }} {% endif %}
|
||||
|
||||
<b>
|
||||
{% if value[0].data.name %} {{ value[0].data.name }} {% else
|
||||
%} {{ key }} {% endif %}
|
||||
</b>
|
||||
</div>
|
||||
|
||||
<div class="card flex items-center gap-2">
|
||||
<button
|
||||
class="quaternary red small"
|
||||
onclick="trigger('connections::delete', ['{{ key }}'])"
|
||||
>
|
||||
{{ text "general:action.delete" }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
<script type="application/json" id="settings_json">{{ user_settings_serde|safe }}</script>
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ macros -%}
|
|||
|
||||
<meta
|
||||
http-equiv="content-security-policy"
|
||||
content="default-src 'self' blob:; img-src * data:; media-src *; font-src *; style-src 'unsafe-inline' 'self' blob: *; script-src 'self' 'unsafe-inline' blob: *; object-src 'self' blob: *; upgrade-insecure-requests; connect-src * localhost; frame-src 'self' blob: data: *"
|
||||
content="default-src 'self' blob: *.spotify.com; img-src * data:; media-src *; font-src *; style-src 'unsafe-inline' 'self' blob: *; script-src 'self' 'unsafe-inline' blob: *; object-src 'self' blob: *; upgrade-insecure-requests; connect-src * localhost; frame-src 'self' blob: data: *"
|
||||
/>
|
||||
|
||||
<link rel="icon" href="/public/favicon.svg" />
|
||||
|
@ -111,6 +111,7 @@ macros -%}
|
|||
atto["hooks::check_reactions"]();
|
||||
atto["hooks::tabs"]();
|
||||
atto["hooks::partial_embeds"]();
|
||||
atto["hooks::spotify_time_text"](); // spotify durations
|
||||
|
||||
if (document.getElementById("tokens")) {
|
||||
trigger("me::render_token_picker", [
|
||||
|
@ -325,6 +326,61 @@ macros -%}
|
|||
trigger("atto::use_theme_preference");
|
||||
}, 150);
|
||||
</script>
|
||||
{% endif %} {% if user and user.connections.Spotify and
|
||||
config.connections.spotify_client_id and
|
||||
user.connections.Spotify[0].data.token and
|
||||
user.connections.Spotify[0].data.refresh_token %}
|
||||
<script>
|
||||
setTimeout(async () => {
|
||||
if (window.spotify_init) {
|
||||
return;
|
||||
}
|
||||
|
||||
window.spotify_init = true;
|
||||
const client_id = "{{ config.connections.spotify_client_id }}";
|
||||
let token = "{{ user.connections.Spotify[0].data.token }}";
|
||||
let refresh_token =
|
||||
"{{ user.connections.Spotify[0].data.refresh_token }}";
|
||||
|
||||
if (token) {
|
||||
// we already have a token
|
||||
const pull_playing = async () => {
|
||||
const playing = await trigger("spotify::get_playing", [
|
||||
token,
|
||||
]);
|
||||
|
||||
if (playing.error) {
|
||||
// refresh token
|
||||
const [new_token, new_refresh_token, expires_in] =
|
||||
await trigger("spotify::refresh_token", [
|
||||
client_id,
|
||||
refresh_token,
|
||||
]);
|
||||
|
||||
await trigger("connections::push_con_data", [
|
||||
"Spotify",
|
||||
{
|
||||
token: new_token,
|
||||
expires_in: expires_in.toString(),
|
||||
name: profile.display_name,
|
||||
},
|
||||
]);
|
||||
|
||||
token = new_token;
|
||||
refresh_token = new_refresh_token;
|
||||
return;
|
||||
}
|
||||
|
||||
await trigger("spotify::publish_playing", [playing]);
|
||||
};
|
||||
|
||||
await pull_playing();
|
||||
setInterval(pull_playing, 30_000);
|
||||
} else {
|
||||
window.spotify_needs_token = true;
|
||||
}
|
||||
}, 150);
|
||||
</script>
|
||||
{% endif %}
|
||||
</body>
|
||||
</html>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue