From 0bcc7779b8d0bc85ea76abd1c9852db7340da42f Mon Sep 17 00:00:00 2001 From: lukeIam <2lukeiam@gmail.com> Date: Fri, 18 Dec 2015 19:13:01 +0100 Subject: [PATCH 1/6] Allow multiple threads simultaneous access to Acinerella - should fix freezes and lags on the song selection screen (fixes #167) --- Vocaluxe/Lib/Video/Acinerella/CAcinerella.cs | 45 ++++++++++++++------ 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/Vocaluxe/Lib/Video/Acinerella/CAcinerella.cs b/Vocaluxe/Lib/Video/Acinerella/CAcinerella.cs index 8d421b91..08d908c3 100644 --- a/Vocaluxe/Lib/Video/Acinerella/CAcinerella.cs +++ b/Vocaluxe/Lib/Video/Acinerella/CAcinerella.cs @@ -16,6 +16,7 @@ #endregion using System; +using System.Collections.Generic; using System.Runtime.InteropServices; namespace Vocaluxe.Lib.Video.Acinerella @@ -191,6 +192,20 @@ namespace Vocaluxe.Lib.Video.Acinerella #endif private static readonly Object _Lock = new Object(); + private static readonly Dictionary _AcInstanceLocks = new Dictionary(20); + + private static object _GetLockToken(IntPtr pAcDecoder) + { + object l = null; + _AcInstanceLocks.TryGetValue(pAcDecoder.ToInt64(), out l); + if (l == null) + { + l = new object(); + _AcInstanceLocks.Add(pAcDecoder.ToInt64(), l); + } + return l; + } + // Defines the type of an Acinerella media stream. Currently only video and // audio streams are supported, subtitle and data streams will be marked as @@ -216,7 +231,7 @@ namespace Vocaluxe.Lib.Video.Acinerella public static void AcFree(IntPtr pAcInstance) { - lock (_Lock) + lock (_GetLockToken(pAcInstance)) { _ac_free(pAcInstance); } @@ -261,7 +276,7 @@ namespace Vocaluxe.Lib.Video.Acinerella IntPtr proberesult ) { - lock (_lock) + lock (_GetLockToken(pAcDecoder)) { return _ac_open(PAc_instance, sender, open_proc, read_proc, seek_proc, close_proc, proberesult); } @@ -274,7 +289,7 @@ namespace Vocaluxe.Lib.Video.Acinerella public static Int32 AcOpen2(IntPtr pAcInstance, string filename) // ReSharper restore UnusedMethodReturnValue.Global { - lock (_Lock) + lock (_GetLockToken(pAcInstance)) { return _ac_open2(pAcInstance, filename); } @@ -287,7 +302,7 @@ namespace Vocaluxe.Lib.Video.Acinerella public static void AcClose(IntPtr pAcInstance) { - lock (_Lock) + lock (_GetLockToken(pAcInstance)) { _ac_close(pAcInstance); } @@ -300,7 +315,7 @@ namespace Vocaluxe.Lib.Video.Acinerella public static void AcGetStreamInfo(IntPtr pAcInstance, Int32 nb, out SACStreamInfo info) { - lock (_Lock) + lock (_GetLockToken(pAcInstance)) { _ac_get_stream_info(pAcInstance, nb, out info); } @@ -321,7 +336,7 @@ namespace Vocaluxe.Lib.Video.Acinerella public static IntPtr AcCreateVideoDecoder(IntPtr pAcInstance) { - lock (_Lock) + lock (_GetLockToken(pAcInstance)) { return _ac_create_video_decoder(pAcInstance); } @@ -332,7 +347,7 @@ namespace Vocaluxe.Lib.Video.Acinerella public static IntPtr AcCreateAudioDecoder(IntPtr pAcInstance) { - lock (_Lock) + lock (_GetLockToken(pAcInstance)) { return _ac_create_audio_decoder(pAcInstance); } @@ -347,8 +362,12 @@ namespace Vocaluxe.Lib.Video.Acinerella { lock (_Lock) { - _ac_free_decoder(pAcDecoder); + lock (_GetLockToken(pAcDecoder)) + { + _ac_free_decoder(pAcDecoder); + } } + } // Decodes a package using the specified decoder. The decodec data is stored in the @@ -359,7 +378,7 @@ namespace Vocaluxe.Lib.Video.Acinerella public static bool AcDecodePackage(IntPtr pAcPackage, IntPtr pAcDecoder) { - lock (_Lock) + lock (_GetLockToken(pAcDecoder)) { return _ac_decode_package(pAcPackage, pAcDecoder) != 0; } @@ -370,7 +389,7 @@ namespace Vocaluxe.Lib.Video.Acinerella public static bool AcGetAudioFrame(IntPtr pAcInstance, IntPtr pAcDecoder) { - lock (_Lock) + lock (_GetLockToken(pAcDecoder)) { return _ac_get_audio_frame(pAcInstance, pAcDecoder) != 0; } @@ -381,7 +400,7 @@ namespace Vocaluxe.Lib.Video.Acinerella public static bool AcGetFrame(IntPtr pAcInstance, IntPtr pAcDecoder) { - lock (_Lock) + lock (_GetLockToken(pAcDecoder)) { return _ac_get_frame(pAcInstance, pAcDecoder) != 0; } @@ -392,7 +411,7 @@ namespace Vocaluxe.Lib.Video.Acinerella public static bool AcSkipFrames(IntPtr pAcInstance, IntPtr pAcDecoder, Int32 num) { - lock (_Lock) + lock (_GetLockToken(pAcDecoder)) { return _ac_skip_frames(pAcInstance, pAcDecoder, num) != 0; } @@ -408,7 +427,7 @@ namespace Vocaluxe.Lib.Video.Acinerella public static bool AcSeek(IntPtr pAcDecoder, Int32 dir, Int64 targetPos) { - lock (_Lock) + lock (_GetLockToken(pAcDecoder)) { return _ac_seek(pAcDecoder, dir, targetPos) != 0; } From d17fe4b039de8e1dca65c1422e009690346cc7e3 Mon Sep 17 00:00:00 2001 From: lukeIam <2lukeiam@gmail.com> Date: Sat, 19 Dec 2015 16:58:08 +0100 Subject: [PATCH 2/6] Fix: access to _AcInstanceLocks was not threadsafe --- Vocaluxe/Lib/Video/Acinerella/CAcinerella.cs | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/Vocaluxe/Lib/Video/Acinerella/CAcinerella.cs b/Vocaluxe/Lib/Video/Acinerella/CAcinerella.cs index 08d908c3..91d4e4e1 100644 --- a/Vocaluxe/Lib/Video/Acinerella/CAcinerella.cs +++ b/Vocaluxe/Lib/Video/Acinerella/CAcinerella.cs @@ -192,17 +192,23 @@ namespace Vocaluxe.Lib.Video.Acinerella #endif private static readonly Object _Lock = new Object(); + private static readonly Object _DictionaryLock = new Object(); private static readonly Dictionary _AcInstanceLocks = new Dictionary(20); private static object _GetLockToken(IntPtr pAcDecoder) { - object l = null; - _AcInstanceLocks.TryGetValue(pAcDecoder.ToInt64(), out l); - if (l == null) + object l; + + lock (_DictionaryLock) { - l = new object(); - _AcInstanceLocks.Add(pAcDecoder.ToInt64(), l); + _AcInstanceLocks.TryGetValue(pAcDecoder.ToInt64(), out l); + if (l == null) + { + l = new object(); + _AcInstanceLocks.Add(pAcDecoder.ToInt64(), l); + } } + return l; } From dc375de63200230531c7062af6b292864ad096fa Mon Sep 17 00:00:00 2001 From: z3ro01 Date: Mon, 21 Dec 2015 10:50:19 +0100 Subject: [PATCH 3/6] Fix: Crash after starting a second challenge mode #169 --- PartyModes/PartyModeChallenge/CPartyModeChallenge.cs | 12 +++++++++--- .../CPartyModeChallengeMedley.cs | 11 ++++++++--- PartyModes/PartyModeTicTacToe/CPartyModeTicTacToe.cs | 12 +++++++++--- Vocaluxe/Base/CParty.cs | 4 +++- VocaluxeLib/PartyModes/CPartyMode.cs | 5 +++++ VocaluxeLib/PartyModes/IPartyMode.cs | 1 + 6 files changed, 35 insertions(+), 10 deletions(-) diff --git a/PartyModes/PartyModeChallenge/CPartyModeChallenge.cs b/PartyModes/PartyModeChallenge/CPartyModeChallenge.cs index f92f2dea..e336d4de 100644 --- a/PartyModes/PartyModeChallenge/CPartyModeChallenge.cs +++ b/PartyModes/PartyModeChallenge/CPartyModeChallenge.cs @@ -153,10 +153,8 @@ namespace VocaluxeLib.PartyModes.Challenge GameData = new SData {NumPlayer = 4, NumPlayerAtOnce = 2, NumRounds = 12, NumJokers = 5, RefillJokers = true, CurrentRoundNr = 1, ProfileIDs = new List(), CatSongIndices = null, Results = null}; } - public override bool Init() + public override void SetDefaults() { - if (!base.Init()) - return false; _Stage = EStage.Config; _ScreenSongOptions.Sorting.IgnoreArticles = CBase.Config.GetIgnoreArticles(); @@ -168,7 +166,15 @@ namespace VocaluxeLib.PartyModes.Challenge _ScreenSongOptions.Sorting.Tabs = EOffOn.TR_CONFIG_ON; GameData.ResultTable = new List(); + } + public override bool Init() + { + if (!base.Init()) + return false; + _Stage = EStage.Config; + + SetDefaults(); return true; } diff --git a/PartyModes/PartyModeChallengeMedley/CPartyModeChallengeMedley.cs b/PartyModes/PartyModeChallengeMedley/CPartyModeChallengeMedley.cs index 38c49aa8..78da5f05 100644 --- a/PartyModes/PartyModeChallengeMedley/CPartyModeChallengeMedley.cs +++ b/PartyModes/PartyModeChallengeMedley/CPartyModeChallengeMedley.cs @@ -168,14 +168,19 @@ namespace VocaluxeLib.PartyModes.ChallengeMedley GameData = new SData {NumPlayer = 4, NumPlayerAtOnce = 2, NumRounds = 12, CurrentRoundNr = 1, ProfileIDs = new List(), NumSongs = 5, Songs = new List(), SongSource = ESongSource.TR_ALLSONGS, CatSongIndices = null, Results = null}; } + public override void SetDefaults() + { + _Stage = EStage.Config; + GameData.CurrentRoundNr = 1; + GameData.ResultTable = new List(); + } + public override bool Init() { if (!base.Init()) return false; - _Stage = EStage.Config; - - GameData.ResultTable = new List(); + SetDefaults(); return true; } diff --git a/PartyModes/PartyModeTicTacToe/CPartyModeTicTacToe.cs b/PartyModes/PartyModeTicTacToe/CPartyModeTicTacToe.cs index 81d3c308..6cf643e5 100644 --- a/PartyModes/PartyModeTicTacToe/CPartyModeTicTacToe.cs +++ b/PartyModes/PartyModeTicTacToe/CPartyModeTicTacToe.cs @@ -168,10 +168,8 @@ namespace VocaluxeLib.PartyModes.TicTacToe }; } - public override bool Init() + public override void SetDefaults() { - if (!base.Init()) - return false; _Stage = EStage.Config; _ScreenSongOptions.Sorting.IgnoreArticles = CBase.Config.GetIgnoreArticles(); @@ -186,6 +184,14 @@ namespace VocaluxeLib.PartyModes.TicTacToe GameData.Rounds.Clear(); GameData.PlayerTeam1.Clear(); GameData.PlayerTeam2.Clear(); + } + + public override bool Init() + { + if (!base.Init()) + return false; + + SetDefaults(); return true; } diff --git a/Vocaluxe/Base/CParty.cs b/Vocaluxe/Base/CParty.cs index c3bffe57..f8e498c8 100644 --- a/Vocaluxe/Base/CParty.cs +++ b/Vocaluxe/Base/CParty.cs @@ -63,8 +63,10 @@ namespace Vocaluxe.Base get { return _CurrentPartyMode.ID; } set { - if (_CurrentPartyMode.ID == value) + if (_CurrentPartyMode.ID == value) { + _CurrentPartyMode.SetDefaults(); return; + } if (value != -1 && !_PartyModes.ContainsKey(value)) throw new ArgumentException("Partymode with ID=" + value + " does not exist!"); IPartyMode pm = _PartyModes[value].PartyMode; diff --git a/VocaluxeLib/PartyModes/CPartyMode.cs b/VocaluxeLib/PartyModes/CPartyMode.cs index 5a4d2b14..7fb529c0 100644 --- a/VocaluxeLib/PartyModes/CPartyMode.cs +++ b/VocaluxeLib/PartyModes/CPartyMode.cs @@ -48,6 +48,11 @@ namespace VocaluxeLib.PartyModes return true; } + public virtual void SetDefaults() + { + return; + } + public void LoadTheme() { string xmlPath = CBase.Themes.GetThemeScreensPath(ID); diff --git a/VocaluxeLib/PartyModes/IPartyMode.cs b/VocaluxeLib/PartyModes/IPartyMode.cs index d1aa7e1f..c2c431a2 100644 --- a/VocaluxeLib/PartyModes/IPartyMode.cs +++ b/VocaluxeLib/PartyModes/IPartyMode.cs @@ -99,6 +99,7 @@ namespace VocaluxeLib.PartyModes bool Init(); + void SetDefaults(); void LoadTheme(); void ReloadSkin(); void ReloadTheme(); From ada7a236684b2f6bdabd4cdffcfb3bb327be0270 Mon Sep 17 00:00:00 2001 From: z3ro01 Date: Wed, 23 Dec 2015 18:44:29 +0100 Subject: [PATCH 4/6] App QR codes removed #180 --- .../Ambient/Screens/PopupScreenServerQR.xml | 112 +----------------- Vocaluxe/Screens/CPopupScreenServerQR.cs | 33 +----- 2 files changed, 8 insertions(+), 137 deletions(-) diff --git a/Output/Themes/Ambient/Screens/PopupScreenServerQR.xml b/Output/Themes/Ambient/Screens/PopupScreenServerQR.xml index dd0d120f..b8490044 100644 --- a/Output/Themes/Ambient/Screens/PopupScreenServerQR.xml +++ b/Output/Themes/Ambient/Screens/PopupScreenServerQR.xml @@ -2,7 +2,7 @@ PopupScreenServerQR - 1 + 2 @@ -26,54 +26,10 @@ Menu - 490 + 465 210 - 300 - 300 - -2 - - - - Menu - - - 25 - 25 - 200 - 200 - -2 - - - - Menu - - - 1055 - 25 - 200 - 200 - -2 - - - - Menu - - - 25 - 495 - 200 - 200 - -2 - - - - Menu - - - 1055 - 495 - 200 - 200 + 350 + 350 -2 @@ -81,7 +37,7 @@ 640 - 180 + 170 -2 35 300 @@ -93,65 +49,9 @@ Outline TR_SCREENPSERVERQR_ADDRESS - - 125 - 230 - -2 - 27 - 200 - - - Center - Center - - Outline - Android - - - 1155 - 230 - -2 - 27 - 200 - - - Center - Center - - Outline - Symbian - - - 125 - 460 - -2 - 27 - 200 - - - Center - Center - - Outline - WebOS - - - 1155 - 460 - -2 - 27 - 200 - - - Center - Center - - Outline - Windows Phone - 640 - 515 + 570 -2 35 300 diff --git a/Vocaluxe/Screens/CPopupScreenServerQR.cs b/Vocaluxe/Screens/CPopupScreenServerQR.cs index fce4ed96..6c198aaa 100644 --- a/Vocaluxe/Screens/CPopupScreenServerQR.cs +++ b/Vocaluxe/Screens/CPopupScreenServerQR.cs @@ -30,20 +30,11 @@ namespace Vocaluxe.Screens // Version number for theme files. Increment it, if you've changed something on the theme files! protected override int _ScreenVersion { - get { return 1; } + get { return 2; } } private CTextureRef _QRServerAddress; - private CTextureRef _QRAndroidLink; - private CTextureRef _QRSymbianLink; - private CTextureRef _QRWebOSLink; - private CTextureRef _QRWindowsPhoneLink; - private const string _StaticQRServer = "StaticQRServer"; - private const string _StaticQRAndroid = "StaticQRAndroid"; - private const string _StaticQRSymbian = "StaticQRSymbian"; - private const string _StaticQRWebOS = "StaticQRWebOS"; - private const string _StaticQRWindowsPhone = "StaticQRWindowsPhone"; private const string _TextServerAddress = "TextServerAddress"; private const string _TextServerNotRunning = "TextServerNotRunning"; @@ -52,7 +43,7 @@ namespace Vocaluxe.Screens { base.Init(); - _ThemeStatics = new string[] {_StaticQRServer, _StaticQRAndroid, _StaticQRSymbian, _StaticQRWebOS, _StaticQRWindowsPhone}; + _ThemeStatics = new string[] {_StaticQRServer}; _ThemeTexts = new string[] {_TextServerAddress, _TextServerNotRunning}; } @@ -63,10 +54,6 @@ namespace Vocaluxe.Screens { _GenerateQRs(); _Statics[_StaticQRServer].Texture = _QRServerAddress; - _Statics[_StaticQRAndroid].Texture = _QRAndroidLink; - _Statics[_StaticQRSymbian].Texture = _QRSymbianLink; - _Statics[_StaticQRWebOS].Texture = _QRWebOSLink; - _Statics[_StaticQRWindowsPhone].Texture = _QRWindowsPhoneLink; _Texts[_TextServerAddress].Text = CVocaluxeServer.GetServerAddress(); } _Texts[_TextServerAddress].Visible = CVocaluxeServer.IsServerRunning(); @@ -108,22 +95,6 @@ namespace Vocaluxe.Screens //ServerAddress QRCodeGenerator.QRCode qrcode = qr.CreateQrCode(CVocaluxeServer.GetServerAddress(), QRCodeGenerator.ECCLevel.H); _QRServerAddress = CDraw.AddTexture(qrcode.GetGraphic(20)); - - //Android - qrcode = qr.CreateQrCode(CSettings.LinkAndroidApp, QRCodeGenerator.ECCLevel.H); - _QRAndroidLink = CDraw.AddTexture(qrcode.GetGraphic(20)); - - //Symbian - qrcode = qr.CreateQrCode(CSettings.LinkSymbianApp, QRCodeGenerator.ECCLevel.H); - _QRSymbianLink = CDraw.AddTexture(qrcode.GetGraphic(20)); - - //WebOS - qrcode = qr.CreateQrCode(CSettings.LinkWebOSApp, QRCodeGenerator.ECCLevel.H); - _QRWebOSLink = CDraw.AddTexture(qrcode.GetGraphic(20)); - - //WindowsPhone - qrcode = qr.CreateQrCode(CSettings.LinkWindowsPhoneApp, QRCodeGenerator.ECCLevel.H); - _QRWindowsPhoneLink = CDraw.AddTexture(qrcode.GetGraphic(20)); } } } \ No newline at end of file From a02cafae2b2bc5d8bd09c1af6ec37292985269c1 Mon Sep 17 00:00:00 2001 From: lukeIam Date: Wed, 30 Dec 2015 10:58:23 +0100 Subject: [PATCH 5/6] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 10cce868..9007121b 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Vocaluxe is a free and open source singing game, inspired by the original UltraStar (developed by corvus5) and the great Ultrastar Deluxe project - yet it is an entirely new development in C#. It allows up to six players to sing along with music using microphones in order to score points, depending on the pitch of the voice and the rhythm of singing. It features mouse, keyboard, gamepad and Wiimote navigation, a multi-language interface, and singer profiles with avatars and supports songs in CP1250/52 and UTF8 encodings. -Vocaluxe offers diversified party modes and can optionally be controlled via Browser/App. +Vocaluxe offers diversified party modes and can optionally be controlled via a browser (desktop and mobile supported). Supported Operating Systems / Requirements: - WinXP, Vista, Windows 7, Windows 8, Windows 8.1 and Windows 10 with .NET 4.0 From 3c0a284e9a67329b945dd335fc17213ea74dbea9 Mon Sep 17 00:00:00 2001 From: lukeIam <2lukeiam@gmail.com> Date: Fri, 15 Jan 2016 17:31:26 +0100 Subject: [PATCH 6/6] Removed external links in the app (Wiki, Youtube, ...) as the links where broken and the feature is not used very often. (Closes #172) --- Vocaluxe/Website/index.html | 4 -- Vocaluxe/Website/js/main.js | 124 +----------------------------------- 2 files changed, 1 insertion(+), 127 deletions(-) diff --git a/Vocaluxe/Website/index.html b/Vocaluxe/Website/index.html index 6bfd5460..6e2fcf31 100644 --- a/Vocaluxe/Website/index.html +++ b/Vocaluxe/Website/index.html @@ -232,10 +232,6 @@
-
- - - diff --git a/Vocaluxe/Website/js/main.js b/Vocaluxe/Website/js/main.js index 39b38b49..1bafe29e 100644 --- a/Vocaluxe/Website/js/main.js +++ b/Vocaluxe/Website/js/main.js @@ -2,7 +2,6 @@ /// (function () { var imageLoader; - var externalServices; var translator; var pageHandler; var sessionHandler; @@ -30,7 +29,6 @@ sessionHandler = new SessionHandler(); imageLoader = new ImageLoader(); - externalServices = new ExternalServices(); pageHandler = new PageHandler(); pageHandler.init(); @@ -160,115 +158,6 @@ }; } - function ExternalServices() { - var popupVideoHeight = 390; - var popupVideoWidth = 640; - - var init = function () { - initVideoPopup(); - }; - - var initVideoPopup = function () { - - function scale(width, height, padding, border) { - var scrWidth = $(window).width() - 30, - scrHeight = $(window).height() - 30, - ifrPadding = 2 * padding, - ifrBorder = 2 * border, - ifrWidth = width + ifrPadding + ifrBorder, - ifrHeight = height + ifrPadding + ifrBorder, - h, w; - - if (ifrWidth < scrWidth && ifrHeight < scrHeight) { - w = ifrWidth; - h = ifrHeight; - } else if ((ifrWidth / scrWidth) > (ifrHeight / scrHeight)) { - w = scrWidth; - h = (scrWidth / ifrWidth) * ifrHeight; - } else { - h = scrHeight; - w = (scrHeight / ifrHeight) * ifrWidth; - } - - return { - 'width': w - (ifrPadding + ifrBorder), - 'height': h - (ifrPadding + ifrBorder) - }; - } - - $("#popupVideo").find("a").click(function () { - $("#popupVideo").popup("close"); - $("#popupVideo").popup("close"); //Sometimes twice?? - }); - - $("#popupVideo iframe") - .attr("width", 0) - .attr("height", 0); - - $("#popupVideo").on({ - popupbeforeposition: function () { - var size = scale(popupVideoWidth, popupVideoHeight, 15, 1), - w = size.width, - h = size.height; - - $("#popupVideo iframe") - .attr("width", w) - .attr("height", h); - }, - popupafterclose: function () { - $("#popupVideo iframe") - .attr("width", 0) - .attr("height", 0) - .attr("src", ""); - } - }); - }; - - this.showYoutube = function (artist, title) { - request({ - url: "http://gdata.youtube.com/feeds/api/videos/-/Music?max-results=1&alt=json&format=5&q=" + artist + " " + title, - dataType: "json", - }, "external") - .done(function (result) { - if (result && result.feed && result.feed.entry && result.feed.entry.length > 0) { - var vidId = result.feed.entry[0].id.$t.replace("http://gdata.youtube.com/feeds/api/videos/", ""); - popupVideoHeight = 390; - popupVideoWidth = 640; - - $("#popupVideo iframe").attr("src", "http://www.youtube.com/embed/" + vidId + "?&autoplay=1&rel=0&showinfo=0&disablekb=1&autohide=1"); - $("#popupVideo").popup("open"); - } - }); - }; - - this.showSpotify = function (artist, title) { - request({ - url: "http://ws.spotify.com/search/1/track.json?q=" + title + "+artist:" + artist, - dataType: "json", - }, "external") - .done(function (result) { - if (result && result.tracks && result.tracks.length > 0) { - var spotId = result.tracks[0].href; - popupVideoHeight = 80; - popupVideoWidth = 300; - - $("#popupVideo iframe").attr("src", "https://embed.spotify.com/?uri=" + spotId); - $("#popupVideo").popup("open"); - } - }); - }; - - this.showWikipedia = function (artist) { - popupVideoHeight = 800; - popupVideoWidth = 600; - - $("#popupVideo iframe").attr("src", "http://m.wikipedia.org/wiki/Special:Search/" + artist); - $("#popupVideo").popup("open"); - }; - - init(); - } - function Translator() { this.translationLoaded = $.Deferred(); var translationLoaded = this.translationLoaded; @@ -1101,18 +990,7 @@ }; $.mobile.changePage("#selectPlaylist", { transition: "slidefade" }); }); - - $('#displaySongLinkYoutube').unbind('click').click(function () { - externalServices.showYoutube(result.Artist, result.Title); - }); - - $('#displaySongLinkSpotify').unbind('click').click(function () { - externalServices.showSpotify(result.Artist, result.Title); - }); - - $('#displaySongLinkWikipedia').unbind('click').click(function () { - externalServices.showWikipedia(result.Artist); - }); + } else { $('#displaySongLinks').hide(); }