Compare commits
No commits in common. "main" and "v1.1" have entirely different histories.
BIN
img/linux.png
BIN
img/linux.png
Binary file not shown.
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 34 KiB |
BIN
img/macos.png
BIN
img/macos.png
Binary file not shown.
Before Width: | Height: | Size: 135 KiB After Width: | Height: | Size: 248 KiB |
BIN
img/windows.png
BIN
img/windows.png
Binary file not shown.
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 35 KiB |
65
src/main.cpp
65
src/main.cpp
|
@ -16,7 +16,6 @@
|
|||
std::string lastPlayingSong = "";
|
||||
std::string lastMediaSource = "";
|
||||
std::string currentSongTitle = "";
|
||||
utils::SongInfo songInfo;
|
||||
LastFM* lastfm = nullptr;
|
||||
|
||||
void handleRPCTasks() {
|
||||
|
@ -60,7 +59,6 @@ void handleMediaTasks() {
|
|||
while (true) {
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
auto mediaInformation = backend::getMediaInformation();
|
||||
auto settings = utils::getSettings();
|
||||
if (!mediaInformation) {
|
||||
currentSongTitle = "";
|
||||
Discord_ClearPresence(); // Nothing is playing rn, clear presence
|
||||
|
@ -114,15 +112,15 @@ void handleMediaTasks() {
|
|||
activity.details = mediaInformation->songTitle.c_str();
|
||||
activity.state = activityState.c_str();
|
||||
activity.smallImageText = serviceName.c_str();
|
||||
songInfo = utils::getSongInfo(mediaInformation->songTitle + " " + mediaInformation->songArtist + " " +
|
||||
mediaInformation->songAlbum);
|
||||
std::string artworkURL = utils::getArtworkURL(mediaInformation->songTitle + " " + mediaInformation->songArtist +
|
||||
" " + mediaInformation->songAlbum);
|
||||
|
||||
activity.smallImageKey = "appicon";
|
||||
if (songInfo.artworkURL == "") {
|
||||
if (artworkURL == "") {
|
||||
activity.smallImageKey = "";
|
||||
activity.largeImageKey = "appicon";
|
||||
} else {
|
||||
activity.largeImageKey = songInfo.artworkURL.c_str();
|
||||
activity.largeImageKey = artworkURL.c_str();
|
||||
}
|
||||
activity.largeImageText = mediaInformation->songAlbum.c_str();
|
||||
|
||||
|
@ -142,12 +140,6 @@ void handleMediaTasks() {
|
|||
activity.button1link = buttonText.c_str();
|
||||
}
|
||||
|
||||
std::string odesliUrl = utils::getOdesliURL(songInfo);
|
||||
if(settings.odesli && songInfo.artworkURL != "") {
|
||||
activity.button2name = "Show on Song.link";
|
||||
activity.button2link = odesliUrl.c_str();
|
||||
}
|
||||
|
||||
Discord_UpdatePresence(&activity);
|
||||
}
|
||||
}
|
||||
|
@ -160,8 +152,6 @@ public:
|
|||
settingsFrame->Raise();
|
||||
}
|
||||
|
||||
void OnCopyOdesliURL(wxCommandEvent& evt) { utils::copyToClipboard(utils::getOdesliURL(songInfo)); }
|
||||
|
||||
void OnMenuExit(wxCommandEvent& evt) { settingsFrame->Close(true); }
|
||||
|
||||
void OnMenuAbout(wxCommandEvent& evt) {
|
||||
|
@ -174,14 +164,10 @@ protected:
|
|||
menu->Append(10004, currentSongTitle == "" ? _("Not Playing") : wxString::FromUTF8(currentSongTitle));
|
||||
menu->Enable(10004, false);
|
||||
menu->AppendSeparator();
|
||||
menu->Append(10005, _("Copy Odesli URL"));
|
||||
if (songInfo.artworkURL == "" || currentSongTitle == "")
|
||||
menu->Enable(10005, false);
|
||||
menu->Append(10001, _("Settings"));
|
||||
menu->Append(10003, _("About PlayerLink"));
|
||||
menu->AppendSeparator();
|
||||
menu->Append(10002, _("Quit PlayerLink..."));
|
||||
Bind(wxEVT_MENU, &PlayerLinkIcon::OnCopyOdesliURL, this, 10005);
|
||||
Bind(wxEVT_MENU, &PlayerLinkIcon::OnMenuOpen, this, 10001);
|
||||
Bind(wxEVT_MENU, &PlayerLinkIcon::OnMenuExit, this, 10002);
|
||||
Bind(wxEVT_MENU, &PlayerLinkIcon::OnMenuAbout, this, 10003);
|
||||
|
@ -198,17 +184,18 @@ public:
|
|||
const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
|
||||
long style = 0, const wxValidator& validator = wxDefaultValidator,
|
||||
const wxString& name = "textCtrl")
|
||||
: wxTextCtrl(parent, id, value, pos, size, style, validator, name),
|
||||
placeholder(""),
|
||||
showPlaceholder(true),
|
||||
: wxTextCtrl(parent, id, value, pos, size, style, validator, name),
|
||||
placeholder(""),
|
||||
showPlaceholder(true),
|
||||
isPassword((style & wxTE_PASSWORD) != 0) {
|
||||
|
||||
Bind(wxEVT_SET_FOCUS, &wxTextCtrlWithPlaceholder::OnFocus, this);
|
||||
Bind(wxEVT_KILL_FOCUS, &wxTextCtrlWithPlaceholder::OnBlur, this);
|
||||
}
|
||||
|
||||
void SetPlaceholderText(const wxString& p) {
|
||||
placeholder = p;
|
||||
if (GetValue().IsEmpty() || showPlaceholder)
|
||||
if (GetValue().IsEmpty() || showPlaceholder)
|
||||
UpdatePlaceholder();
|
||||
}
|
||||
|
||||
|
@ -216,7 +203,7 @@ protected:
|
|||
void OnFocus(wxFocusEvent& event) {
|
||||
if (showPlaceholder && GetValue() == placeholder) {
|
||||
Clear();
|
||||
if (isPassword)
|
||||
if (isPassword)
|
||||
SetStyleToPassword();
|
||||
}
|
||||
|
||||
|
@ -238,14 +225,18 @@ private:
|
|||
bool isPassword;
|
||||
|
||||
void UpdatePlaceholder() {
|
||||
if (isPassword)
|
||||
if (isPassword)
|
||||
SetStyleToNormal();
|
||||
SetValue(placeholder);
|
||||
}
|
||||
|
||||
void SetStyleToPassword() { SetWindowStyle(GetWindowStyle() | wxTE_PASSWORD); }
|
||||
void SetStyleToPassword() {
|
||||
SetWindowStyle(GetWindowStyle() | wxTE_PASSWORD);
|
||||
}
|
||||
|
||||
void SetStyleToNormal() { SetWindowStyle(GetWindowStyle() & ~wxTE_PASSWORD); }
|
||||
void SetStyleToNormal() {
|
||||
SetWindowStyle(GetWindowStyle() & ~wxTE_PASSWORD);
|
||||
}
|
||||
};
|
||||
|
||||
class PlayerLinkFrame : public wxFrame {
|
||||
|
@ -396,14 +387,11 @@ public:
|
|||
mainContainer->Add(appsDivider, 0, wxEXPAND | wxALL, 5);
|
||||
|
||||
wxBoxSizer* settingsContainer;
|
||||
settingsContainer = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
wxBoxSizer* startupContainer;
|
||||
startupContainer = new wxBoxSizer(wxHORIZONTAL);
|
||||
settingsContainer = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
auto startupText = new wxStaticText(this, wxID_ANY, _("Startup:"), wxDefaultPosition, wxDefaultSize, 0);
|
||||
startupText->Wrap(-1);
|
||||
startupContainer->Add(startupText, 0, wxALL, 5);
|
||||
settingsContainer->Add(startupText, 0, wxALL, 5);
|
||||
|
||||
auto autostartCheckbox =
|
||||
new wxCheckBox(this, wxID_ANY, _("Launch at login"), wxDefaultPosition, wxDefaultSize, 0);
|
||||
|
@ -416,21 +404,8 @@ public:
|
|||
utils::saveSettings(settings);
|
||||
});
|
||||
|
||||
auto odesliCheckbox =
|
||||
new wxCheckBox(this, wxID_ANY, _("Odesli integration"), wxDefaultPosition, wxDefaultSize, 0);
|
||||
odesliCheckbox->SetValue(settings.odesli);
|
||||
odesliCheckbox->Bind(wxEVT_CHECKBOX, [](wxCommandEvent& event) {
|
||||
bool isChecked = event.IsChecked();
|
||||
auto settings = utils::getSettings();
|
||||
settings.odesli = isChecked;
|
||||
utils::saveSettings(settings);
|
||||
});
|
||||
|
||||
settingsContainer->Add(autostartCheckbox, 0, wxALL, 5);
|
||||
settingsContainer->Add(odesliCheckbox, 0, wxALL, 5);
|
||||
startupContainer->Add(settingsContainer);
|
||||
mainContainer->Add(startupContainer, 0, wxEXPAND, 5);
|
||||
|
||||
mainContainer->Add(settingsContainer, 0, wxEXPAND, 5);
|
||||
// settings end
|
||||
this->SetSizerAndFit(mainContainer);
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
#include <curl/include/curl/curl.h>
|
||||
#include <wx/mstream.h>
|
||||
#include <wx/wx.h>
|
||||
#include <wx/clipbrd.h>
|
||||
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
|
@ -36,26 +35,12 @@ namespace utils {
|
|||
};
|
||||
|
||||
struct Settings {
|
||||
bool odesli;
|
||||
bool autoStart;
|
||||
bool anyOtherEnabled;
|
||||
LastFMSettings lastfm;
|
||||
std::vector<App> apps;
|
||||
};
|
||||
|
||||
struct SongInfo {
|
||||
std::string artworkURL;
|
||||
int64_t trackId;
|
||||
};
|
||||
|
||||
inline void copyToClipboard(const wxString& text) {
|
||||
if (wxTheClipboard->Open()) {
|
||||
wxTheClipboard->Clear();
|
||||
wxTheClipboard->SetData(new wxTextDataObject(text));
|
||||
wxTheClipboard->Close();
|
||||
}
|
||||
}
|
||||
|
||||
inline wxIcon loadIconFromMemory(const unsigned char* data, size_t size) {
|
||||
wxMemoryInputStream stream(data, size);
|
||||
wxImage img(stream, wxBITMAP_TYPE_PNG);
|
||||
|
@ -140,23 +125,17 @@ namespace utils {
|
|||
return buf;
|
||||
}
|
||||
|
||||
inline SongInfo getSongInfo(std::string query) {
|
||||
SongInfo ret{};
|
||||
inline std::string getArtworkURL(std::string query) {
|
||||
std::string response =
|
||||
httpRequest("https://itunes.apple.com/search?media=music&entity=song&term=" + urlEncode(query));
|
||||
nlohmann::json j = nlohmann::json::parse(response);
|
||||
auto results = j["results"];
|
||||
if (results.size() > 0) {
|
||||
ret.artworkURL = results[0]["artworkUrl100"].get<std::string>();
|
||||
ret.trackId = results[0]["trackId"].get<int64_t>();
|
||||
return results[0]["artworkUrl100"].get<std::string>();
|
||||
}
|
||||
return ret;
|
||||
return "";
|
||||
}
|
||||
|
||||
inline std::string getOdesliURL(SongInfo& song) {
|
||||
return std::string("https://song.link/i/" + std::to_string(song.trackId));
|
||||
}
|
||||
|
||||
inline void saveSettings(const App* newApp) {
|
||||
nlohmann::json j;
|
||||
|
||||
|
@ -210,7 +189,6 @@ namespace utils {
|
|||
nlohmann::json j;
|
||||
j["autostart"] = settings.autoStart;
|
||||
j["any_other"] = settings.anyOtherEnabled;
|
||||
j["odesli"] = settings.odesli;
|
||||
|
||||
j["lastfm"]["enabled"] = settings.lastfm.enabled;
|
||||
j["lastfm"]["api_key"] = settings.lastfm.api_key;
|
||||
|
@ -240,7 +218,6 @@ namespace utils {
|
|||
if (!std::filesystem::exists(CONFIG_FILENAME)) {
|
||||
ret.anyOtherEnabled = true;
|
||||
ret.autoStart = false;
|
||||
ret.odesli = false;
|
||||
saveSettings(ret);
|
||||
return ret;
|
||||
}
|
||||
|
@ -252,7 +229,6 @@ namespace utils {
|
|||
|
||||
ret.autoStart = j.value("autostart", false);
|
||||
ret.anyOtherEnabled = j.value("any_other", false);
|
||||
ret.odesli = j.value("odesli", false);
|
||||
|
||||
if (j.contains("lastfm")) {
|
||||
auto lastfm = j["lastfm"];
|
||||
|
|
Loading…
Reference in New Issue