diff --git a/HowToBuildWin.md b/HowToBuildWin.md new file mode 100644 index 00000000..95285b79 --- /dev/null +++ b/HowToBuildWin.md @@ -0,0 +1,58 @@ +# Build Vocaluxe - HowTo (Windows) + +* Navigate to the right repository: usually [Vocaluxe Main](https://github.com/Vocaluxe/Vocaluxe) +* Navigate to the right branch: usually [develop](https://github.com/Vocaluxe/Vocaluxe/tree/develop) (The main branch of Vocaluxe) + + ![branch](https://cloud.githubusercontent.com/assets/5115160/4995706/bc5aa536-69c2-11e4-8534-b64573624a33.PNG) + +* Copy the `URL` of the corresponding git file + + ![url](https://cloud.githubusercontent.com/assets/5115160/4995708/bc5af234-69c2-11e4-91d1-112972f35f01.PNG) + +* Make sure [Visual Studio 2012/2013(?)](http://www.visualstudio.com/downloads/download-visual-studio-vs#d-express-windows-desktop) is installed + +* Clone the repository and open it + + **Method A: Use Visual Studio (2013+)'s git client:** + * Start Visual Studio + * `VIEW`->`Team Explorer` + * Click on the `Connect to a Team Project` button inside the `Team Explorer` + * Click on `Clone` under `Local Git Repositories` + * Enter `[theCopiedGitUrl]` in the first field + * Enter a target folder in the second field + * Click clone + ![vsclone](https://cloud.githubusercontent.com/assets/5115160/4998350/de81ca76-69d7-11e4-983d-d2886aa9faa0.png) + + **Method B: Use commandline git client:** + * Make sure git is installed [git-scm](http://git-scm.com/) + * Open a `git bash` (there should be a link in the start menu) + or a normal commandline if you have added git to the `PATH` variable + * Navigate to the folder where git should create the Vocaluxe project folder + + ``` + cd [PathToYourFolder] + ``` + * Clone the repository (could take some time...) + ``` + git clone [theCopiedGitUrl] + ``` + ![clone](https://cloud.githubusercontent.com/assets/5115160/4995707/bc5aa6da-69c2-11e4-95cb-71ac7b0c3fc8.png) + + * Now you should find a Folder `Vocaluxe` in the given directory -> navigate into it + + * Open the file `Vocaluxe.sln` with Visual Studio + +* Configure the build target to `ReleaseWin` and `x86` or `x64` (if unsure -> select `x86`) +* Build the projects by clicking `"Build"->"Build solution"` or just press `Control`+`Shift`+`B` + + ![build](https://cloud.githubusercontent.com/assets/5115160/4995709/bc5b3474-69c2-11e4-9d9b-b49f8a3b315d.png) + +* Check if your build was successful + ![buildsuccess](https://cloud.githubusercontent.com/assets/5115160/4995710/bc5b4fe0-69c2-11e4-8b0f-4acaeffbc568.png) + +* YOUR build should have appeared here: + ``` + [PathToYourFolder]\Vocaluxe\Output + ``` +* Run `Vocaluxe.exe` or copy the whole folder to a location of your choice +* Have fun! diff --git a/ServerLib/CServer.cs b/ServerLib/CServer.cs index e4c46301..b085e2c1 100644 --- a/ServerLib/CServer.cs +++ b/ServerLib/CServer.cs @@ -33,6 +33,7 @@ namespace ServerLib private bool _Encrypted; public static SendKeyEventDelegate SendKeyEvent { internal get; set; } + public static SendKeyStringEventDelegate SendKeyStringEvent { internal get; set; } #region profile public static GetProfileDataDelegate GetProfileData { internal get; set; } diff --git a/ServerLib/CWebservice.cs b/ServerLib/CWebservice.cs index 0844c7fa..7f5edac1 100644 --- a/ServerLib/CWebservice.cs +++ b/ServerLib/CWebservice.cs @@ -58,6 +58,23 @@ namespace ServerLib CServer.SendKeyEvent(key); } + public void SendKeyStringEvent(string keyString, bool isShiftPressed = false, bool isAltPressed = false, bool isCtrlPressed = false) + { + if (!_CheckRight(EUserRights.UseKeyboard)) + return; + + if (CServer.SendKeyStringEvent == null) + { + if (WebOperationContext.Current != null) + { + WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.NotFound; + WebOperationContext.Current.OutgoingResponse.StatusDescription = "Not found"; + } + } + else + CServer.SendKeyStringEvent(keyString, isShiftPressed, isAltPressed, isCtrlPressed); + } + #region profile public int GetOwnProfileId() { diff --git a/ServerLib/DataStructs.cs b/ServerLib/DataStructs.cs index 24b01219..cc88104e 100644 --- a/ServerLib/DataStructs.cs +++ b/ServerLib/DataStructs.cs @@ -26,6 +26,7 @@ using System.Text.RegularExpressions; namespace ServerLib { public delegate bool SendKeyEventDelegate(string key); + public delegate bool SendKeyStringEventDelegate(string keyString, bool isShiftPressed , bool isAltPressed , bool isCtrlPressed); #region profile public delegate SProfileData GetProfileDataDelegate(int profileId, bool isReadonly); diff --git a/ServerLib/ICWebservice.cs b/ServerLib/ICWebservice.cs index 86fbb091..1324c2d9 100644 --- a/ServerLib/ICWebservice.cs +++ b/ServerLib/ICWebservice.cs @@ -30,6 +30,11 @@ namespace ServerLib UriTemplate = "/sendKeyEvent?key={key}")] void SendKeyEvent(string key); + [OperationContract, WebInvoke(Method = "GET", + ResponseFormat = WebMessageFormat.Json, + UriTemplate = "/sendKeyStringEvent?keyString={keyString}&shift={isShiftPressed}&alt={isAltPressed}&ctrl={isCtrlPressed}")] + void SendKeyStringEvent(string keyString, bool isShiftPressed = false, bool isAltPressed = false, bool isCtrlPressed = false); + #region profile [OperationContract, WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json, diff --git a/Vocaluxe/Base/CSettings.cs b/Vocaluxe/Base/CSettings.cs index 528b56e1..de9378cb 100644 --- a/Vocaluxe/Base/CSettings.cs +++ b/Vocaluxe/Base/CSettings.cs @@ -19,6 +19,7 @@ using System; using System.Collections.Generic; using System.IO; using System.Reflection; +using System.Windows.Forms; using VocaluxeLib; namespace Vocaluxe.Base @@ -185,8 +186,11 @@ namespace Vocaluxe.Base // ReSharper disable ConditionIsAlwaysTrueOrFalse if (VersionRevision != ERevision.Release) + { // ReSharper restore ConditionIsAlwaysTrueOrFalse - version += " " + _GetVersionStatus() + String.Format(" ({0:0000)}", _Assembly.Version.Revision); + var gitversion = Application.ProductVersion; + version += " " + _GetVersionStatus() + String.Format(" ({0})", gitversion); + } return version; } diff --git a/Vocaluxe/Base/Server/CVocaluxeServer.cs b/Vocaluxe/Base/Server/CVocaluxeServer.cs index da781d27..b324116a 100644 --- a/Vocaluxe/Base/Server/CVocaluxeServer.cs +++ b/Vocaluxe/Base/Server/CVocaluxeServer.cs @@ -64,6 +64,7 @@ namespace Vocaluxe.Base.Server _Server = new CServer(CConfig.Config.Server.ServerPort, CConfig.Config.Server.ServerEncryption == EOffOn.TR_CONFIG_ON); CServer.SendKeyEvent = _SendKeyEvent; + CServer.SendKeyStringEvent = _sendKeyStringEvent; CServer.GetProfileData = _GetProfileData; CServer.SendProfileData = _SendProfileData; CServer.GetProfileList = _GetProfileList; @@ -125,9 +126,11 @@ namespace Vocaluxe.Base.Server private static bool _SendKeyEvent(string key) { bool result = false; - if (!string.IsNullOrEmpty(key)) + var lowerKey = key.ToLower(); + + if (!string.IsNullOrEmpty(lowerKey)) { - switch (key.ToLower()) + switch (lowerKey) { case "up": Controller.AddKeyEvent(new SKeyEvent(ESender.Keyboard, false, false, false, false, Char.MinValue, Keys.Up)); @@ -157,25 +160,22 @@ namespace Vocaluxe.Base.Server Controller.AddKeyEvent(new SKeyEvent(ESender.Keyboard, false, false, false, false, Char.MinValue, Keys.Tab)); result = true; break; + case "backspace": + Controller.AddKeyEvent(new SKeyEvent(ESender.Keyboard, false, false, false, false, Char.MinValue, Keys.Back)); + result = true; + break; default: - foreach (char c in key) + if (lowerKey.StartsWith("f")) { - bool shift = true; - char keyChar; - if (char.ToUpper(c) != c) - { - keyChar = char.ToUpper(c); - shift = false; - } - else - keyChar = c; + var numberString = lowerKey.Substring(1); + int number; + Keys fKey; - if ((keyChar >= '0' && keyChar <= '9') || (keyChar >= 'A' && keyChar <= 'Z')) + if (Int32.TryParse(numberString, out number) && number >= 1 + && number <= 12 + && Enum.TryParse("F" + number, true, out fKey)) { - Keys keys = (Keys)keyChar; - if (shift) - keys |= Keys.Shift; - Controller.AddKeyEvent(new SKeyEvent(ESender.Keyboard, false, false, false, false, Char.MinValue, keys)); + Controller.AddKeyEvent(new SKeyEvent(ESender.Keyboard, false, false, false, false, Char.MinValue, fKey)); result = true; } } @@ -186,6 +186,43 @@ namespace Vocaluxe.Base.Server return result; } + private static bool _sendKeyStringEvent(string keyString, bool isShiftPressed , bool isAltPressed , bool isCtrlPressed ) + { + bool result = false; + + foreach (var key in keyString.ToCharArray()) + { + Controller.AddKeyEvent(new SKeyEvent(ESender.Keyboard, isAltPressed, + Char.IsUpper(key) || isShiftPressed, + isCtrlPressed, true, + isShiftPressed?Char.ToUpper(key) :key, + _ParseKeys(key))); + result = true; + } + + return result; + } + + private static Keys _ParseKeys(char keyText) + { + Keys key; + + if (!Enum.TryParse(keyText.ToString(), true, out key)) + { + switch (keyText) + { + case ' ': + key = Keys.Space; + break; + default: + key = Keys.None; + break; + } + } + + return key; + } + #region profile private static SProfileData _GetProfileData(int profileId, bool isReadonly) { diff --git a/Vocaluxe/Properties/AssemblyInfo.cs b/Vocaluxe/Properties/AssemblyInfo.cs index 861326f6..495dca5c 100644 --- a/Vocaluxe/Properties/AssemblyInfo.cs +++ b/Vocaluxe/Properties/AssemblyInfo.cs @@ -50,4 +50,5 @@ using System.Runtime.InteropServices; // [assembly: AssemblyVersion("0.3.0.83")] -[assembly: AssemblyFileVersion("0.3.0.83")] \ No newline at end of file +[assembly: AssemblyFileVersion("0.3.0.83")] +[assembly: AssemblyInformationalVersion("GITVERSION")] \ No newline at end of file diff --git a/Vocaluxe/Vocaluxe.csproj b/Vocaluxe/Vocaluxe.csproj index d38b6d10..02af3467 100644 --- a/Vocaluxe/Vocaluxe.csproj +++ b/Vocaluxe/Vocaluxe.csproj @@ -521,7 +521,11 @@ - xcopy /E /D /Y "$(ProjectDir)\Website" "$(SolutionDir)\PhoneGap" + xcopy /E /D /Y "$(ProjectDir)\Website" "$(SolutionDir)\PhoneGap" +powershell -command "(Get-Content -Encoding UTF8 '$(ProjectDir)Properties\AssemblyInfo.cs') | Foreach-Object {$_ -replace '(?<=AssemblyInformationalVersion\()(.*)(?=\))', '\"GITVERSION\"'} | Set-Content -Encoding UTF8 '$(ProjectDir)Properties\AssemblyInfo.cs'" + + + powershell -command "$version = git describe --long; (Get-Content -Encoding UTF8 '$(ProjectDir)Properties\AssemblyInfo.cs') | Foreach-Object {$_ -replace 'GITVERSION', $version} | Set-Content -Encoding UTF8 '$(ProjectDir)Properties\AssemblyInfo.cs'" -
+

Volcaluxe

@@ -297,14 +297,36 @@
+
+ +
+
+
+ + + + + + +
+
- P +
- + +
diff --git a/Vocaluxe/Website/js/main.js b/Vocaluxe/Website/js/main.js index 53b892be..814d253b 100644 --- a/Vocaluxe/Website/js/main.js +++ b/Vocaluxe/Website/js/main.js @@ -1,628 +1,1278 @@ -var ownProfileId = -1; -var profileIdRequest = -1; -var songIdRequest = -1; -var allSongsCache = null; -var playlistIdRequest = -1; -var playlistRequestName = ""; -var customSelectPlaylistSongCallback = null; -var sessionId = ""; -var serverBaseAddress = ""; -var translationLoaded; +/// +/// +(function () { + var imageLoader; + var externalServices; + var translator; + var pageHandler; + var sessionHandler; -if (document.location.protocol == "file:") { - if (typeof (window.deviceAndJqmLoaded) == "undefined") { - window.deviceAndJqmLoaded = $.Deferred(); - } - window.deviceAndJqmLoaded.done(function () { - preStart(); - }); -} else { - $(document).ready(function () { - preStart(); - }); -} - -function preStart() { - translationLoaded = $.Deferred(); - initTranslation(); - - translationLoaded.done(function () { - translate(); - start(); - }); -} - -function start() { - replaceTransitionHandler(); - initPageLoadHandler(); - initKeyboardPageHandler(); - initMainPageHandler(); - initDiscoverPageHandler(); - initLoginPageHandler(); - initHeartbeat(); - initVideoPopup(); -} - -function replaceTransitionHandler() { - //Thx to http://stackoverflow.com/a/14096311 - var oldDefaultTransitionHandler = $.mobile.defaultTransitionHandler; - - $.mobile.defaultTransitionHandler = function (name, reverse, $to, $from) { - var promise = $to.data('promise'); - if (promise) { - $to.removeData('promise'); - /*$('div[data-role="content"]').wrap('
'); - $.mobile.loading('show', { - text: 'Loading data...', - textVisible: true - });*/ - return promise.then(function () { - /*$.mobile.loading('hide'); - $('div[data-role="content"]').unwrap();*/ - return oldDefaultTransitionHandler(name, reverse, $to, $from); + var initMain = function () { + if (document.location.protocol == "file:") { + if (typeof (window.deviceAndJqmLoaded) == "undefined") { + window.deviceAndJqmLoaded = $.Deferred(); + } + window.deviceAndJqmLoaded.done(function () { + preStart(); + }); + } else { + $(document).ready(function () { + translator = new Translator(); + preStart(); }); } - return oldDefaultTransitionHandler(name, reverse, $to, $from); }; -} -function initPageLoadHandler() { - //pageLoadHandler for discover - $(document).on('pagebeforeshow', '#discover', pagebeforeshowDiscover); + function preStart() { + translator.translationLoaded.done(function () { + translator.translate(); - //pageLoadHandler for displayProfile - $(document).on('pagebeforeshow', '#displayProfile', function () { - if (profileIdRequest >= 0) { - var promise = request({ - url: "getProfile?profileId=" + profileIdRequest - }).done(function (result) { - handleDisplayProfileData(result); + sessionHandler = new SessionHandler(); + imageLoader = new ImageLoader(); + externalServices = new ExternalServices(); + pageHandler = new PageHandler(); - $('#playerSaveButton').click(function () { - var dataToUpload = {}; - - dataToUpload["ProfileId"] = profileIdRequest; - dataToUpload["PlayerName"] = $('#playerName').prop("value"); - dataToUpload["Type"] = $('#playerType').prop("value"); - dataToUpload["Difficulty"] = $('#playerDifficulty').prop("value"); - dataToUpload["Avatar"] = $('#playerAvatar').data("changed") ? { "base64Data": $('#playerAvatar').prop("src") } : null; - - var pass = $('#playerPassword').prop("value"); - if (pass != "***__oldPassword__***") { - if (pass == "") { - dataToUpload["Password"] = "***__CLEAR_PASSWORD__***"; - } else { - dataToUpload["Password"] = pass; - } - } else { - dataToUpload["Password"] = null; - } - - request({ - url: "sendProfile", - contentType: "application/json;charset=utf-8", - type: "POST", - data: JSON.stringify(dataToUpload), - }, "Uploading profile...").done(function () { - history.back(); - }); - - }); - }); - - // Save promise on page so the transition handler can find it. - $(this).data('promise', promise); - } - else { - //new profile - handleDisplayProfileData({ - "Avatar": { "base64Data": null }, - "Difficulty": 0, - "IsEditable": true, - "PlayerName": i18n.t("YourName") || "YourName", - "ProfileId": -1, - "Type": 1 - }); - $('#playerType').prop("value", 0); - $('#playerDifficulty').prop("value", 0); - - $('#playerSaveButton').click(function () { - var dataToUpload = {}; - - dataToUpload["ProfileId"] = -1; - dataToUpload["PlayerName"] = $('#playerName').prop("value"); - dataToUpload["Type"] = $('#playerType').prop("value"); - dataToUpload["Difficulty"] = $('#playerDifficulty').prop("value"); - dataToUpload["Avatar"] = $('#playerAvatar').data("changed") ? { "base64Data": $('#playerAvatar').prop("src") } : null; - - var pass = $('#playerPassword').prop("value"); - if (pass != "***__oldPassword__***") { - if (pass == "") { - dataToUpload["Password"] = "***__CLEAR_PASSWORD__***"; - } else { - dataToUpload["Password"] = pass; - } - } else { - dataToUpload["Password"] = null; - } - - request({ - url: "sendProfile", - contentType: "application/json;charset=utf-8", - type: "POST", - data: JSON.stringify(dataToUpload) - }, 'Creating profile...').done(function () { - $.mobile.changePage("#login", { transition: "slidefade" }); - }); - - }); - } - }); - - function handleDisplayProfileData(data) { - $('#playerName').prop("value", data.PlayerName); - - addImage($('#playerAvatar')[0], data.Avatar, "img/profile.png"); - - $('#playerAvatar').data("changed", false); - $('#playerType').prop("selectedIndex", data.Type).selectmenu("refresh"); - $('#playerDifficulty').prop("selectedIndex", data.Difficulty).selectmenu("refresh"); - if (data.IsEditable) { - $('#playerName').prop('disabled', false); - $('#playerType').prop('disabled', false); - $('#playerDifficulty').prop('disabled', false); - $('#playerSaveButton').show().unbind("click"); - $('#playerAvatar').unbind("click"); - $('#playerPassword').prop('disabled', false).prop("value", "***__oldPassword__***").parent().show(); - $('#playerPasswordLabel').show(); - - $('#playerAvatar').click(function () { - if ($('#captureContainer').length > 0) { - $('#captureContainer').remove(); - } - - if (document.location.protocol == "file:" - && typeof (navigator) != 'undefined' - && typeof (navigator.camera) != 'undefined' - && typeof (navigator.camera.getPicture) != 'undefined') { - navigator.camera.getPicture(function (imageData) { - $('#playerAvatar').prop("src", "data:image/jpeg;base64," + imageData); - $('#playerAvatar').data("changed", true); - }, function () { - //Fail - do nothing - }, { - destinationType: navigator.camera.DestinationType.DATA_URL, - allowEdit: true, - correctOrientation: true, - saveToPhotoAlbum: true, - quality: 50 - }); - - } else { - $(document.body).append('
'); - - $('#capture').change(function (eventData) { - if (eventData && eventData.target && eventData.target.files && eventData.target.files.length == 1) { - var file = eventData.target.files[0]; - var reader = new FileReader(); - reader.onloadend = function (e) { - $('#playerAvatar').prop("src", e.target.result); - $('#playerAvatar').data("changed", true); - $('#captureContainer').remove(); - }; - reader.readAsDataURL(file); - } - }); - - $('#capture').click(); - } - }); - } - else { - $('#playerName').prop('disabled', true); - $('#playerType').prop('disabled', true); - $('#playerDifficulty').prop('disabled', true); - $('#playerSaveButton').hide().unbind("click"); - $('#playerAvatar').unbind("click"); - $('#playerPassword').prop('disabled', true).parent().hide(); - $('#playerPasswordLabel').hide(); - } + pageHandler.init(); + }); + translator.initTranslation(); } - //pageLoadHandler for selectProfile - $(document).on('pagebeforeshow', '#selectProfile', function () { - var promise = request({ - url: "getProfileList" - }).done(function (data) { - $('#selectProfileList').children().remove(); + function request(data, message) { + if ((typeof message) == "undefined" || message == null) { + message = "Loading..."; + } - function handleProfileSelectLineClick(e) { - profileIdRequest = parseInt(e.currentTarget.id.replace("ProfileSelectLine_", "")); - $.mobile.changePage("#displayProfile", { transition: "slidefade" }); + if ((typeof data.timeout) == "undefined") { + data.timeout = 10000; //10 sec. timeout + } + + if (message != "noOverlay") { + var message2 = message; + if (i18n.t) { + message2 = i18n.t(message2); } + $('div[data-role="content"]').wrap('
'); + $.mobile.loading('show', { + text: message2, + textVisible: true + }); + } - for (var profile in data) { - var img = $('
  • ' + data[profile].PlayerName + '

    Click here to show the profile of ' + data[profile].PlayerName + '

  • ') - .appendTo('#selectProfileList') - .click(handleProfileSelectLineClick) - .find("img")[0]; + if (!data["headers"]) { + data["headers"] = {}; + } - addImage(img, data[profile].Avatar, "img/profile.png"); + if (message == "external") { + message = "Loading (external)..."; + if (i18n.t) { + message = i18n.t(message) || message; } + } else { + data["headers"]["session"] = sessionHandler.sessionId; + data.url = sessionHandler.serverBaseAddress + data.url; + } - $('#selectProfileList').listview('refresh'); + return $.ajax(data).always(function (result) { + if (message != "noOverlay") { + $.mobile.loading('hide'); + $('div[data-role="content"]').unwrap(); + } + }).fail(function (result) { + if (result.statusText.indexOf("No session") != -1) { + sessionHandler.logout(); + return; + } + if (message != "noOverlay") { + var msg = result.statusText.length <= 20 ? result.statusText : "Error..."; + if (msg == "error" && result.readyState == 0) { + msg = "No connection"; + } + showError(msg); + } }); + } - // Save promise on page so the transition handler can find it. - $(this).data('promise', promise); - }); + function showError(message) { + if (!message) { + message = "Error..."; + } - //pageLoadHandler for displaySong - $(document).on('pagebeforeshow', '#displaySong', function () { - var promise = request({ - url: "getSong?songId=" + songIdRequest - }).done(function (result) { - $('#displaySongAddPlaylist').hide(); + if (i18n.t) { + message = i18n.t(message) || message; + } - if (result.Title != null) { - $('#displaySongTitle').text(result.Title); - } - else { - $('#displaySongTitle').text("No current song"); - } + $('div[data-role="content"]').wrap('
    '); + $.mobile.loading('show', { + text: message, + textVisible: true + }); + $('.ui-loader').find('span').removeClass('ui-icon-loading').addClass('ui-custom-errorIcon'); - addImage($('#displaySongCover')[0], result.Cover, "img/noCover.png"); + setTimeout(function () { + $.mobile.loading('hide'); + $('div[data-role="content"]').unwrap(); + $('.ui-loader').find('span').removeClass('ui-custom-errorIcon').addClass('ui-icon-loading'); + }, 1000); + } - if (result.Artist != null) { - $('#displaySongArtist').text(result.Artist); - } - else { - $('#displaySongArtist').text("-"); - } + function ImageLoader() { + var cachedImages = {}; - if (result.Genre != null) { - $('#displaySongGenre').text(result.Genre); - } - else { - $('#displaySongGenre').text("-"); - } + this.delayedImageLoad = function (elem, id, fail) { + if (elem && id) { + if (cachedImages[id]) { + elem.src = cachedImages[id].base64Data; + return; + } - if (result.Year != null && result.Year != "") { - $('#displaySongYear').text(result.Year); - } - else { - $('#displaySongYear').text("-"); - } - - if (result.Language != null) { - $('#displaySongLanguage').text(result.Language); - } - else { - $('#displaySongLanguage').text("-"); - } - - $('#displaySongIsDuet').text(result.IsDuet ? "Yes" : "No"); - - if (result.Title != null || result.Artist != null) { - $('#displaySongLinks').show(); - - $('#displaySongAddPlaylist').unbind('click').click(function () { - customSelectPlaylistSongCallback = function (playlistId) { - request({ url: "addSongToPlaylist?songId=" + result.SongId + "&playlistId=" + playlistId + "&duplicates=false" }, "Add to playlist..."); - history.back(); - }; - $.mobile.changePage("#selectPlaylist", { transition: "slidefade" }); + elem.src = ""; + $(elem).addClass("imageLoaderImg"); + request({ + url: "delayedImage?id=" + id + }).done(function (result) { + $(elem).removeClass("imageLoaderImg"); + elem.src = result.base64Data; + cachedImages[id] = result; + }).fail(function () { + $(elem).removeClass("imageLoaderImg"); + if (fail) { + elem.src = fail; + } }); - - $('#displaySongLinkYoutube').unbind('click').click(function () { - showYoutube(result.Artist, result.Title); - }); - - $('#displaySongLinkSpotify').unbind('click').click(function () { - showSpotify(result.Artist, result.Title); - }); - - $('#displaySongLinkWikipedia').unbind('click').click(function () { - showWikipedia(result.Artist); - }); - } else { - $('#displaySongLinks').hide(); } + }; - request({ - url: "hasUserRight?right=" + 32 - }).done(function (result2) { - if (result2) { - $('#displaySongAddPlaylist').show(); + this.addImage = function (img, base64Image, defaultImg) { + if (base64Image && (base64Image.base64Data || base64Image.imageId)) { + if (base64Image.base64Data) { + $(img).prop("src", base64Image.base64Data); } else { - $('#displaySongAddPlaylist').hide(); + imageLoader.delayedImageLoad(img, base64Image.imageId, defaultImg); + } + } else { + $(img).prop("src", defaultImg); + } + }; + } + + 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", ""); } }); - }); + }; - // Save promise on page so the transition handler can find it. - $(this).data('promise', promise); - }); + 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; - //pageLoadHandler for selectSong - $(document).on('pagebeforeshow', '#selectSong', function () { - function handleGetAllSongs() { - $('#selectSongList').children().remove(); + $("#popupVideo iframe").attr("src", "http://www.youtube.com/embed/" + vidId + "?&autoplay=1&rel=0&showinfo=0&disablekb=1&autohide=1"); + $("#popupVideo").popup("open"); + } + }); + }; - function handleSelectSongLineClick(e) { - songIdRequest = parseInt(e.currentTarget.id.replace("selectSongLine_", "")); - $.mobile.changePage("#displaySong", { transition: "slidefade" }); - } + 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; - for (var id in allSongsCache) { - $('
  • '/*+' '*/ + '

    ' + allSongsCache[id].Artist + '

    ' + allSongsCache[id].Title + '

  • ') - .appendTo('#selectSongList') - .click(handleSelectSongLineClick); - } + $("#popupVideo iframe").attr("src", "https://embed.spotify.com/?uri=" + spotId); + $("#popupVideo").popup("open"); + } + }); + }; - $('#selectSongList').listview('refresh'); - } + this.showWikipedia = function (artist) { + popupVideoHeight = 800; + popupVideoWidth = 600; - if (allSongsCache == null) { - var promise = request({ - url: "getAllSongs" - }).done(function (data) { - allSongsCache = data; - handleGetAllSongs(); + $("#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; + + this.initTranslation = function () { + $.i18n.init({ + resGetPath: 'locales/__lng__.json', + supportedLngs: ['en', 'de', 'fr', 'sv', 'cs'], + fallbackLng: 'en', + keyseparator: '::', + nsseparator: ':::' + }).done(function () { + translationLoaded.resolve(); }); + }; - // Save promise on page so the transition handler can find it. - $(this).data('promise', promise); - } - else { - handleGetAllSongs(); - } - }); + this.translate = function () { + //repair broken buttons on the first page (get broken while translating) + var repairButtons = function () { + $($('#discoverConnect')[0].childNodes).wrap(' '); + $($('#discoverReadQr')[0].childNodes).wrap(' '); + }; + $('body').i18n(); + repairButtons(); + }; + } - //pageLoadHandler for selectUserAdmin - $(document).on('pagebeforeshow', '#selectUserAdmin', function () { - var promise = request({ - url: "getProfileList" - }).done(function (data) { - $('#selectUserAdminList').children().remove(); + function PageHandler() { + var loginPageHandler; + var discoverPageHandler; + var mainPageHandler; + var keyboardPageHandler; + var userPageHandler; + var songPageHandler; + var playlistPageHandler; - function handleSelectUserAdminLineClick(e) { - profileIdRequest = parseInt(e.currentTarget.id.replace("SelectUserAdminLine_", "")); - $.mobile.changePage("#displayUserAdmin", { transition: "slidefade" }); - } + var t = this; - for (var profile in data) { - $('
  • ' + data[profile].PlayerName + '

    Click here to edit roles for ' + data[profile].PlayerName + '

  • ') - .appendTo('#selectUserAdminList') - .click(handleSelectUserAdminLineClick); - } + this.customSelectPlaylistSongCallback = null; + this.profileIdRequest = -1; + this.songIdRequest = -1; - $('#selectUserAdminList').listview('refresh'); - }); + this.init = function () { + replaceTransitionHandler(); + loginPageHandler = new LoginPageHandler(); + discoverPageHandler = new DiscoverPageHandler(); + mainPageHandler = new MainPageHandler(); + keyboardPageHandler = new KeyboardPageHandler(); + userPageHandler = new UserPageHandler(); + songPageHandler = new SongPageHandler(); + playlistPageHandler = new PlaylistPageHandler(); + }; - // Save promise on page so the transition handler can find it. - $(this).data('promise', promise); - }); + this.reset = function () { + t.customSelectPlaylistSongCallback = null; + t.profileIdRequest = -1; + t.songIdRequest = -1; + }; - //pageLoadHandler for displayUserAdmin - $(document).on('pagebeforeshow', '#displayUserAdmin', function () { - var promise = request({ - url: "getUserRole?profileId=" + profileIdRequest - }).done(function (result) { - var userRoles = { - TR_USERROLE_ADMIN: 2, - TR_USERROLE_KEYBOARDUSER: 4, - TR_USERROLE_ADDSONGSUSER: 8, - TR_USERROLE_PLAYLISTEDITOR: 16, - TR_USERROLE_PROFILEEDITOR: 32 + var replaceTransitionHandler = function () { + //Thx to http://stackoverflow.com/a/14096311 + var oldDefaultTransitionHandler = $.mobile.defaultTransitionHandler; + + $.mobile.defaultTransitionHandler = function (name, reverse, $to, $from) { + var promise = $to.data('promise'); + if (promise) { + $to.removeData('promise'); + /*$('div[data-role="content"]').wrap('
    '); + $.mobile.loading('show', { + text: 'Loading data...', + textVisible: true + });*/ + return promise.then(function () { + /*$.mobile.loading('hide'); + $('div[data-role="content"]').unwrap();*/ + return oldDefaultTransitionHandler(name, reverse, $to, $from); + }); + } + return oldDefaultTransitionHandler(name, reverse, $to, $from); + }; + }; + + var DiscoverPageHandler = function () { + var init = function () { + //pageLoadHandler for discover + $(document).on('pagebeforeshow', '#discover', pagebeforeshowDiscover); + + initDiscoverPageHandler(); }; - for (var roleName in userRoles) { - $('#' + roleName).prop("checked", ((result & userRoles[roleName]) != 0)).checkboxradio("refresh"); - } - - - $('#btnRoleSave').unbind('click').click(function () { - var role = 0; - - for (var roleName2 in userRoles) { - if ($('#' + roleName2).prop("checked")) { - role = (role | userRoles[roleName2]); + var initDiscoverPageHandler = function () { + var keyPressed = function (e) { + if (e.which == 13) { + $('#discoverConnect').click(); } + }; + + $('#discoverServerAddress').keypress(keyPressed); + + function handleAddress(address) { + if (address != null && address != "") { + if (address.indexOf("http") != 0) { + address = "http://" + address; + } + if (address.slice(-1) != '/') { + address = address + '/'; + } + sessionHandler.serverBaseAddress = ""; + request({ + url: address + "isServerOnline", + timeout: 10000 + }, "Checking...") + .done(function () { + sessionHandler.serverBaseAddress = address; + window.localStorage.setItem("VocaluxeServerAddress", address); + $.mobile.changePage("#login", { transition: "slidefade" }); + }) + .fail(function () { + $('#discoverServerAddress').prop("value", ""); + if (document.location.protocol == "file:" + && typeof window.BarcodeScanner != "undefined") { + $('#discoverReadQr').show(); + } + }); + } + } + + $('#discoverConnect').click(function () { + handleAddress($('#discoverServerAddress').prop("value")); + }); + + try { + window.BarcodeScanner = cordova.require("cordova/plugin/BarcodeScanner"); + } catch (e) { + } + + $('#discoverReadQr').hide().click(function () { + window.BarcodeScanner.scan( + function (result) { + handleAddress(result.text); + }, + function () { + showError("Scan faild"); + } + ); + }); + + //Fire pageLoadHandler for discover (first page shown after start) + setTimeout(function () { + pagebeforeshowDiscover(); + $(this).removeData('promise'); + }, 1); + }; + + var pagebeforeshowDiscover = function () { + if (document.location.protocol == "file:") { + if (window.localStorage) { + var address = window.localStorage.getItem("VocaluxeServerAddress"); + if (address != null) { + sessionHandler.serverBaseAddress = ""; + var prom = request({ + url: address + "isServerOnline", + timeout: 10000 + }, "Checking...").done(function () { + sessionHandler.serverBaseAddress = address; + window.localStorage.setItem("VocaluxeServerAddress", address); + $.mobile.changePage("#login", { transition: "none" }); + }).fail(function () { + if (typeof window.BarcodeScanner != "undefined") { + $('#discoverReadQr').show(); + } + }); + $(this).data('promise', prom); + return; + } + if (typeof window.BarcodeScanner != "undefined") { + $('#discoverReadQr').show(); + } + } + } else { + $('#discoverReadQr').hide(); + $.mobile.changePage("#login", { transition: "none" }); + } + }; + + init(); + }; + + var LoginPageHandler = function () { + var init = function () { + //pageLoadHandler for login + $(document).on('pagebeforeshow', '#login', pagebeforeshowLogin); + + initLoginPageHandler(); + }; + + var pagebeforeshowLogin = function () { + if (window.localStorage) { + var value = window.localStorage.getItem("VocaluxeSessionKey"); + if (value != null && value != "") { + sessionHandler.sessionId = value; + } + } + + if (sessionHandler.sessionId != "") { + if (sessionHandler.ownProfileId != -1) { + $.mobile.changePage("#main", { transition: "slidefade" }); + } else { + request({ + url: "getOwnProfileId", + headers: { "session": sessionHandler.sessionId } + }, 'Login...').done(function (result) { + sessionHandler.ownProfileId = result; + $.mobile.changePage("#main", { transition: "slidefade" }); + }); + } + } + }; + + var initLoginPageHandler = function () { + var keyPressed = function (e) { + if (e.which == 13) { + $('#loginButton').click(); + } + }; + + $('#loginName').keypress(keyPressed); + $('#loginPassword').keypress(keyPressed); + + $('#loginButton').click(function () { + var username = $('#loginName').prop("value"); + var password = $('#loginPassword').prop("value"); + + request({ + url: "login?username=" + username + "&password=" + password + }).done(function (result) { + sessionHandler.sessionId = result; + if (window.localStorage) { + window.localStorage.setItem("VocaluxeSessionKey", sessionHandler.sessionId); + } + request({ + url: "getOwnProfileId", + headers: { "session": sessionHandler.sessionId } + }, 'Login...').done(function (result2) { + sessionHandler.ownProfileId = result2; + $.mobile.changePage("#main", { transition: "slidefade" }); + }); + }); + }); + + $('#registerButton').click(function () { + sessionHandler.ownProfileId = -1; + pageHandler.profileIdRequest = -1; + $.mobile.changePage("#displayProfile", { transition: "slidefade" }); + }); + }; + + init(); + }; + + var MainPageHandler = function () { + var init = function () { + //pageLoadHandler for main + $(document).on('pagebeforeshow', '#main', pagebeforeshowMain); + + initMainPageHandler(); + }; + + var pagebeforeshowMain = function () { + request({ + url: "hasUserRight?right=" + 2 + }).done(function (result) { + if (result) { + $('#mainPageTakePhotoLink').parent().parent().parent().show(); + } else { + $('#mainPageTakePhotoLink').parent().parent().parent().hide(); + } + }); + + request({ + url: "hasUserRight?right=" + 8 + }).done(function (result) { + if (result) { + $('#mainPageKeyboard').parent().parent().parent().show(); + } else { + $('#mainPageKeyboard').parent().parent().parent().hide(); + } + }); + + request({ + url: "hasUserRight?right=" + 4 + }).done(function (result) { + if (result) { + $('#mainPageSelectProfile').parent().parent().parent().show(); + } else { + $('#mainPageSelectProfile').parent().parent().parent().hide(); + } + }); + }; + + var initMainPageHandler = function () { + $('#yourProfileLink').click(function () { + pageHandler.profileIdRequest = sessionHandler.ownProfileId; + $.mobile.changePage("#displayProfile", { transition: "slidefade" }); + }); + + $('#currentSongLink').click(function () { + request({ + url: "getCurrentSongId", + headers: { "session": sessionHandler.sessionId } + }, 'Getting current song...').done(function (result) { + pageHandler.songIdRequest = parseInt(result); + $.mobile.changePage("#displaySong", { transition: "slidefade" }); + }); + }); + + function uploadImg(imgData) { + request({ + url: "sendPhoto", + contentType: "application/json;charset=utf-8", + type: "POST", + data: JSON.stringify({ Photo: { base64Data: imgData } }) + }, 'Uploading photo...'); + } + + $('#mainPageTakePhotoLink').click(function () { + if ($('#captureContainer').length > 0) { + $('#captureContainer').remove(); + } + + if (document.location.protocol == "file:" + && typeof (navigator) != 'undefined' + && typeof (navigator.camera) != 'undefined' + && typeof (navigator.camera.getPicture) != 'undefined') { + navigator.camera.getPicture(function (imageData) { + uploadImg("data:image/jpeg;base64," + imageData); + }, function () { + //Fail - do nothing + }, { + destinationType: navigator.camera.DestinationType.DATA_URL, + allowEdit: true, + correctOrientation: true, + saveToPhotoAlbum: true, + quality: 100 + }); + + } else { + $(document.body).append('
    '); + + $('#capture').change(function (eventData) { + if (eventData && eventData.target && eventData.target.files && eventData.target.files.length == 1) { + var file = eventData.target.files[0]; + var reader = new FileReader(); + + reader.onloadend = function (e) { + uploadImg(e.target.result); + $('#capture').remove(); + }; + + reader.readAsDataURL(file); + } + }); + + $('#capture').click(); + } + }); + + $('#mainPageLogoutLink').click(function () { + sessionHandler.logout(); + }); + }; + + init(); + }; + + var KeyboardPageHandler = function () { + var init = function () { + initKeyboardPageHandler(); + }; + + var initKeyboardPageHandler = function () { + $('#keyboardButtonUp').click(function () { + request({ + url: "sendKeyEvent?key=up" + }); + }); + + $('#keyboardButtonDown').click(function () { + request({ + url: "sendKeyEvent?key=down" + }); + }); + + $('#keyboardButtonLeft').click(function () { + request({ + url: "sendKeyEvent?key=left" + }); + }); + + $('#keyboardButtonRight').click(function () { + request({ + url: "sendKeyEvent?key=right" + }); + }); + + $('#keyboardButtonEscape').click(function () { + request({ + url: "sendKeyEvent?key=escape" + }); + }); + + $('#keyboardButtonTab').click(function () { + request({ + url: "sendKeyEvent?key=tab" + }); + }); + + $('#keyboardButtonReturn').click(function () { + request({ + url: "sendKeyEvent?key=return" + }); + }); + + $('#keyboardButtonBackspace').click(function () { + request({ + url: "sendKeyEvent?key=backspace" + }); + }); + + $("#keyboardAutoSend").change(function () { + if ($('#keyboardAutoSend').is(':checked')) { + $('#keyboardButtonSend').hide(); + } else { + $('#keyboardButtonSend').show(); + } + }); + + $('#keyboardButtonSend').click(function () { + sendKeyboardText(); + }); + + $('#keyboardButtonKeys').keyup(function (e) { + if (!$('#keyboardAutoSend').is(':checked') && e.keyCode != 13) { + return; + } + sendKeyboardText(); + }); + + function sendKeyboardText() { + var text = $('#keyboardButtonKeys')[0].value; + + if (text.length <= 0) { + return; + } + + $('#keyboardButtonKeys')[0].value = ""; + $('#keyboardButtonKeys').first().focus(); + + /* if ($('#keyboardButtonFunct').is(':checked')) { + $('#keyboardButtonKeys')[0].value = text.splice(1) + $('#keyboardButtonKeys')[0].value; + var numericElements = /^[0-9][0-9]?/.exec(text.charAt(0)); + if (parseInt(numericElements)) { + request({ + url: "sendKeyEvent?key=F" + numericElements + }); + } + $("#keyboardButtonFunct").attr("checked", false).checkboxradio("refresh"); + }*/ + + request({ + contentType: "application/json;charset=utf-8", + type: "GET", + url: "sendKeyStringEvent?keyString=" + text + + "&shift=" + $('#keyboardButtonShift').is(':checked') + + "&alt=" + $('#keyboardButtonAlt').is(':checked') + + "&ctrl=" + $('#keyboardButtonCtrl').is(':checked') + + }).fail(function () { + $('#keyboardButtonKeys')[0].value = text + $('#keyboardButtonKeys')[0].value; + }); + } + }; + + init(); + }; + + var UserPageHandler = function () { + var init = function () { + //pageLoadHandler for displayProfile + $(document).on('pagebeforeshow', '#displayProfile', pagebeforeshowDisplayProfile); + + //pageLoadHandler for selectProfile + $(document).on('pagebeforeshow', '#selectProfile', pagebeforeshowSelectProfile); + + //pageLoadHandler for selectUserAdmin + $(document).on('pagebeforeshow', '#selectUserAdmin', pagebeforeshowSelectUserAdmin); + + //pageLoadHandler for displayUserAdmin + $(document).on('pagebeforeshow', '#displayUserAdmin', pagebeforeshowDisplayUserAdmin); + }; + + var pagebeforeshowDisplayProfile = function () { + if (pageHandler.profileIdRequest >= 0) { + var promise = request({ + url: "getProfile?profileId=" + pageHandler.profileIdRequest + }).done(function (result) { + handleDisplayProfileData(result); + + $('#playerSaveButton').click(function () { + var dataToUpload = {}; + + dataToUpload["ProfileId"] = pageHandler.profileIdRequest; + dataToUpload["PlayerName"] = $('#playerName').prop("value"); + dataToUpload["Type"] = $('#playerType').prop("value"); + dataToUpload["Difficulty"] = $('#playerDifficulty').prop("value"); + dataToUpload["Avatar"] = $('#playerAvatar').data("changed") ? { "base64Data": $('#playerAvatar').prop("src") } : null; + + var pass = $('#playerPassword').prop("value"); + if (pass != "***__oldPassword__***") { + if (pass == "") { + dataToUpload["Password"] = "***__CLEAR_PASSWORD__***"; + } else { + dataToUpload["Password"] = pass; + } + } else { + dataToUpload["Password"] = null; + } + + request({ + url: "sendProfile", + contentType: "application/json;charset=utf-8", + type: "POST", + data: JSON.stringify(dataToUpload), + }, "Uploading profile...").done(function () { + history.back(); + }); + + }); + }); + + // Save promise on page so the transition handler can find it. + $(this).data('promise', promise); + } else { + //new profile + handleDisplayProfileData({ + "Avatar": { "base64Data": null }, + "Difficulty": 0, + "IsEditable": true, + "PlayerName": i18n.t("YourName") || "YourName", + "ProfileId": -1, + "Type": 1 + }); + $('#playerType').prop("value", 0); + $('#playerDifficulty').prop("value", 0); + + $('#playerSaveButton').click(function () { + var dataToUpload = {}; + + dataToUpload["ProfileId"] = -1; + dataToUpload["PlayerName"] = $('#playerName').prop("value"); + dataToUpload["Type"] = $('#playerType').prop("value"); + dataToUpload["Difficulty"] = $('#playerDifficulty').prop("value"); + dataToUpload["Avatar"] = $('#playerAvatar').data("changed") ? { "base64Data": $('#playerAvatar').prop("src") } : null; + + var pass = $('#playerPassword').prop("value"); + if (pass != "***__oldPassword__***") { + if (pass == "") { + dataToUpload["Password"] = "***__CLEAR_PASSWORD__***"; + } else { + dataToUpload["Password"] = pass; + } + } else { + dataToUpload["Password"] = null; + } + + request({ + url: "sendProfile", + contentType: "application/json;charset=utf-8", + type: "POST", + data: JSON.stringify(dataToUpload) + }, 'Creating profile...').done(function () { + $.mobile.changePage("#login", { transition: "slidefade" }); + }); + + }); + } + }; + + var handleDisplayProfileData = function (data) { + $('#playerName').prop("value", data.PlayerName); + + imageLoader.addImage($('#playerAvatar')[0], data.Avatar, "img/profile.png"); + + $('#playerAvatar').data("changed", false); + $('#playerType').prop("selectedIndex", data.Type).selectmenu("refresh"); + $('#playerDifficulty').prop("selectedIndex", data.Difficulty).selectmenu("refresh"); + if (data.IsEditable) { + $('#playerName').prop('disabled', false); + $('#playerType').prop('disabled', false); + $('#playerDifficulty').prop('disabled', false); + $('#playerSaveButton').show().unbind("click"); + $('#playerAvatar').unbind("click"); + $('#playerPassword').prop('disabled', false).prop("value", "***__oldPassword__***").parent().show(); + $('#playerPasswordLabel').show(); + + $('#playerAvatar').click(function () { + if ($('#captureContainer').length > 0) { + $('#captureContainer').remove(); + } + + if (document.location.protocol == "file:" + && typeof (navigator) != 'undefined' + && typeof (navigator.camera) != 'undefined' + && typeof (navigator.camera.getPicture) != 'undefined') { + navigator.camera.getPicture(function (imageData) { + $('#playerAvatar').prop("src", "data:image/jpeg;base64," + imageData); + $('#playerAvatar').data("changed", true); + }, function () { + //Fail - do nothing + }, { + destinationType: navigator.camera.DestinationType.DATA_URL, + allowEdit: true, + correctOrientation: true, + saveToPhotoAlbum: true, + quality: 50 + }); + + } else { + $(document.body).append('
    '); + + $('#capture').change(function (eventData) { + if (eventData && eventData.target && eventData.target.files && eventData.target.files.length == 1) { + var file = eventData.target.files[0]; + var reader = new FileReader(); + reader.onloadend = function (e) { + $('#playerAvatar').prop("src", e.target.result); + $('#playerAvatar').data("changed", true); + $('#captureContainer').remove(); + }; + reader.readAsDataURL(file); + } + }); + + $('#capture').click(); + } + }); + } else { + $('#playerName').prop('disabled', true); + $('#playerType').prop('disabled', true); + $('#playerDifficulty').prop('disabled', true); + $('#playerSaveButton').hide().unbind("click"); + $('#playerAvatar').unbind("click"); + $('#playerPassword').prop('disabled', true).parent().hide(); + $('#playerPasswordLabel').hide(); + } + }; + + var pagebeforeshowSelectProfile = function () { + var promise = request({ + url: "getProfileList" + }).done(function (data) { + $('#selectProfileList').children().remove(); + + function handleProfileSelectLineClick(e) { + pageHandler.profileIdRequest = parseInt(e.currentTarget.id.replace("ProfileSelectLine_", "")); + $.mobile.changePage("#displayProfile", { transition: "slidefade" }); + } + + for (var profile in data) { + var img = $('
  • ' + data[profile].PlayerName + '

    Click here to show the profile of ' + data[profile].PlayerName + '

  • ') + .appendTo('#selectProfileList') + .click(handleProfileSelectLineClick) + .find("img")[0]; + + imageLoader.addImage(img, data[profile].Avatar, "img/profile.png"); + } + + $('#selectProfileList').listview('refresh'); + }); + + // Save promise on page so the transition handler can find it. + $(this).data('promise', promise); + }; + + var pagebeforeshowSelectUserAdmin = function () { + var promise = request({ + url: "getProfileList" + }).done(function (data) { + $('#selectUserAdminList').children().remove(); + + function handleSelectUserAdminLineClick(e) { + pageHandler.profileIdRequest = parseInt(e.currentTarget.id.replace("SelectUserAdminLine_", "")); + $.mobile.changePage("#displayUserAdmin", { transition: "slidefade" }); + } + + for (var profile in data) { + $('
  • ' + data[profile].PlayerName + '

    Click here to edit roles for ' + data[profile].PlayerName + '

  • ') + .appendTo('#selectUserAdminList') + .click(handleSelectUserAdminLineClick); + } + + $('#selectUserAdminList').listview('refresh'); + }); + + // Save promise on page so the transition handler can find it. + $(this).data('promise', promise); + }; + + var pagebeforeshowDisplayUserAdmin = function () { + var promise = request({ + url: "getUserRole?profileId=" + pageHandler.profileIdRequest + }).done(function (result) { + var userRoles = { + TR_USERROLE_ADMIN: 2, + TR_USERROLE_KEYBOARDUSER: 4, + TR_USERROLE_ADDSONGSUSER: 8, + TR_USERROLE_PLAYLISTEDITOR: 16, + TR_USERROLE_PROFILEEDITOR: 32 + }; + + for (var roleName in userRoles) { + $('#' + roleName).prop("checked", ((result & userRoles[roleName]) != 0)).checkboxradio("refresh"); + } + + + $('#btnRoleSave').unbind('click').click(function () { + var role = 0; + + for (var roleName2 in userRoles) { + if ($('#' + roleName2).prop("checked")) { + role = (role | userRoles[roleName2]); + } + } + + request({ + url: "setUserRole?profileId=" + pageHandler.profileIdRequest + "&userRole=" + role, + headers: { "session": sessionHandler.sessionId } + }, "Saving...").done(function (result) { + history.back(); + }); + }); + }); + + // Save promise on page so the transition handler can find it. + $(this).data('promise', promise); + }; + + init(); + }; + } + + function SongPageHandler() { + var allSongsCache = null; + + var init = function () { + //pageLoadHandler for displaySong + $(document).on('pagebeforeshow', '#displaySong', pagebeforeshowDisplaySong); + + //pageLoadHandler for selectSong + $(document).on('pagebeforeshow', '#selectSong', pagebeforeshowSelectSong); + }; + + var pagebeforeshowDisplaySong = function () { + var promise = request({ + url: "getSong?songId=" + pageHandler.songIdRequest + }).done(function (result) { + $('#displaySongAddPlaylist').hide(); + + if (result.Title != null) { + $('#displaySongTitle').text(result.Title); + } else { + $('#displaySongTitle').text("No current song"); + } + + imageLoader.addImage($('#displaySongCover')[0], result.Cover, "img/noCover.png"); + + if (result.Artist != null) { + $('#displaySongArtist').text(result.Artist); + } else { + $('#displaySongArtist').text("-"); + } + + if (result.Genre != null) { + $('#displaySongGenre').text(result.Genre); + } else { + $('#displaySongGenre').text("-"); + } + + if (result.Year != null && result.Year != "") { + $('#displaySongYear').text(result.Year); + } else { + $('#displaySongYear').text("-"); + } + + if (result.Language != null) { + $('#displaySongLanguage').text(result.Language); + } else { + $('#displaySongLanguage').text("-"); + } + + $('#displaySongIsDuet').text(result.IsDuet ? "Yes" : "No"); + + if (result.Title != null || result.Artist != null) { + $('#displaySongLinks').show(); + + $('#displaySongAddPlaylist').unbind('click').click(function () { + pageHandler.customSelectPlaylistSongCallback = function (playlistId) { + request({ url: "addSongToPlaylist?songId=" + result.SongId + "&playlistId=" + playlistId + "&duplicates=false" }, "Add to playlist..."); + history.back(); + }; + $.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(); } request({ - url: "setUserRole?profileId=" + profileIdRequest + "&userRole=" + role, - headers: { "session": sessionId } - }, "Saving...").done(function (result) { - history.back(); + url: "hasUserRight?right=" + 32 + }).done(function (result2) { + if (result2) { + $('#displaySongAddPlaylist').show(); + } else { + $('#displaySongAddPlaylist').hide(); + } }); }); - }); - // Save promise on page so the transition handler can find it. - $(this).data('promise', promise); - }); + // Save promise on page so the transition handler can find it. + $(this).data('promise', promise); + }; - //pageLoadHandler for login - $(document).on('pagebeforeshow', '#login', pagebeforeshowLogin); + var pagebeforeshowSelectSong = function () { - //pageLoadHandler for main - $(document).on('pagebeforeshow', '#main', function () { - request({ - url: "hasUserRight?right=" + 2 - }).done(function (result) { - if (result) { - $('#mainPageTakePhotoLink').parent().parent().parent().show(); - } else { - $('#mainPageTakePhotoLink').parent().parent().parent().hide(); - } - }); + function handleGetAllSongs() { + $('#selectSongList').children().remove(); - request({ - url: "hasUserRight?right=" + 8 - }).done(function (result) { - if (result) { - $('#mainPageKeyboard').parent().parent().parent().show(); - } else { - $('#mainPageKeyboard').parent().parent().parent().hide(); - } - }); - - request({ - url: "hasUserRight?right=" + 4 - }).done(function (result) { - if (result) { - $('#mainPageSelectProfile').parent().parent().parent().show(); - } else { - $('#mainPageSelectProfile').parent().parent().parent().hide(); - } - }); - }); - - //pageLoadHandler for selectPlaylist - $(document).on('pagebeforeshow', '#selectPlaylist', function () { - function handleGetAllPlaylists(data) { - $('#selectPlaylistContentList').children().remove(); - $('#selectPlaylistAddPlaylistButton').hide(); - - function handleSelectSongLineClick(e) { - playlistIdRequest = parseInt(e.currentTarget.parentElement.parentElement.parentElement.id.replace("selectPlaylistLine_", "")); - playlistRequestName = $(e.currentTarget.parentElement.parentElement.parentElement).find('h2').text(); - if (customSelectPlaylistSongCallback != null) { - customSelectPlaylistSongCallback(playlistIdRequest, playlistRequestName); - customSelectPlaylistSongCallback = null; - } else { - - $.mobile.changePage("#displayPlaylist", { transition: "slidefade" }); + function handleSelectSongLineClick(e) { + pageHandler.songIdRequest = parseInt(e.currentTarget.id.replace("selectSongLine_", "")); + $.mobile.changePage("#displaySong", { transition: "slidefade" }); } + + for (var id in allSongsCache) { + $('
  • '/*+' '*/ + '

    ' + allSongsCache[id].Artist + '

    ' + allSongsCache[id].Title + '

  • ') + .appendTo('#selectSongList') + .click(handleSelectSongLineClick); + } + + $('#selectSongList').listview('refresh'); } - function handleSelectSongLineDeleteClick(e) { - var playlistToDeleteId = parseInt(e.currentTarget.parentElement.id.replace("selectPlaylistLine_", "")); - var playlistToDeleteName = $(e.currentTarget.parentElement).find('h2').text(); - if (window.confirm("Do you really want to delete this playlist:\n" + playlistToDeleteName)) { - request({ url: "removePlaylist?playlistId=" + playlistToDeleteId }, "Loading...").done(function () { - request({ - url: "getPlaylists" - }).done(function (data2) { - handleGetAllPlaylists(data2); + if (allSongsCache == null) { + var promise = request({ + url: "getAllSongs" + }).done(function (data) { + allSongsCache = data; + handleGetAllSongs(); + }); + + // Save promise on page so the transition handler can find it. + $(this).data('promise', promise); + } else { + handleGetAllSongs(); + } + }; + + init(); + } + + function PlaylistPageHandler() { + var playlistIdRequest = -1; + var playlistRequestName = ""; + + var init = function () { + //pageLoadHandler for selectPlaylist + $(document).on('pagebeforeshow', '#selectPlaylist', pagebeforeshowSelectPlaylist); + + //pageLoadHandler for displayPlaylist + $(document).on('pagebeforeshow', '#displayPlaylist', pagebeforeshowDisplayPlaylist); + }; + + var pagebeforeshowSelectPlaylist = function () { + + function handleGetAllPlaylists(data) { + $('#selectPlaylistContentList').children().remove(); + $('#selectPlaylistAddPlaylistButton').hide(); + + function handleSelectSongLineClick(e) { + playlistIdRequest = parseInt(e.currentTarget.parentElement.parentElement.parentElement.id.replace("selectPlaylistLine_", "")); + playlistRequestName = $(e.currentTarget.parentElement.parentElement.parentElement).find('h2').text(); + if (pageHandler.customSelectPlaylistSongCallback != null) { + pageHandler.customSelectPlaylistSongCallback(playlistIdRequest, playlistRequestName); + pageHandler.customSelectPlaylistSongCallback = null; + } else { + + $.mobile.changePage("#displayPlaylist", { transition: "slidefade" }); + } + } + + function handleSelectSongLineDeleteClick(e) { + var playlistToDeleteId = parseInt(e.currentTarget.parentElement.id.replace("selectPlaylistLine_", "")); + var playlistToDeleteName = $(e.currentTarget.parentElement).find('h2').text(); + if (window.confirm("Do you really want to delete this playlist:\n" + playlistToDeleteName)) { + request({ url: "removePlaylist?playlistId=" + playlistToDeleteId }, "Loading...").done(function () { + request({ + url: "getPlaylists" + }).done(function (data2) { + handleGetAllPlaylists(data2); + }); }); - }); + } } - } - for (var id in data) { - var line = $('
  • '/*+' '*/ - + '

    ' + data[id].PlaylistName + '

    ' - + data[id].SongCount - + ' ' + i18n.t('songs') + '

    Delete
  • ') - .appendTo('#selectPlaylistContentList'); - line.find('a:not(.delete)').click(handleSelectSongLineClick); - line.find('a.delete').click(handleSelectSongLineDeleteClick); - } - - $('#selectPlaylistContentList').listview('refresh'); - - request({ - url: "hasUserRight?right=" + 128 - }).done(function (result) { - if (result) { - $('#selectPlaylistContentList').find('.delete').show(); - $('#selectPlaylistContentList').listview('refresh'); - } else { - $('#selectPlaylistContentList').find('.delete').hide(); - $('#selectPlaylistContentList').listview('refresh'); + for (var id in data) { + var line = $('
  • '/*+' '*/ + + '

    ' + data[id].PlaylistName + '

    ' + + data[id].SongCount + + ' ' + i18n.t('songs') + '

    Delete
  • ') + .appendTo('#selectPlaylistContentList'); + line.find('a:not(.delete)').click(handleSelectSongLineClick); + line.find('a.delete').click(handleSelectSongLineDeleteClick); } - }); - $('#selectPlaylistAddPlaylistButton').unbind('click').hide().click(function () { - var name = prompt("Name of the new playlist:", "NewPlaylistName"); - if (name != null - && name.replace(" ", "") != "" - && $('h2').filter(function () { return this.textContent == name; }).length == 0) { - request({ url: "addPlaylist?playlistName=" + name }, "Creating...").done(function () { - request({ - url: "getPlaylists" - }).done(function (data2) { - handleGetAllPlaylists(data2); - }); - }); - } else { - alert(i18n.t("This is not a valid name.")); - } - }); + $('#selectPlaylistContentList').listview('refresh'); - request({ - url: "hasUserRight?right=" + 64 - }).done(function (result) { - if (result) { - $('#selectPlaylistAddPlaylistButton').show(); - } else { - $('#selectPlaylistAddPlaylistButton').hide(); - } - }); - } - - var promise = request({ - url: "getPlaylists" - }).done(function (data) { - handleGetAllPlaylists(data); - }); - - // Save promise on page so the transition handler can find it. - $(this).data('promise', promise); - - }); - - //pageLoadHandler for displayPlaylist - $(document).on('pagebeforeshow', '#displayPlaylist', function () { - function handleGetAllPlaylistSongs(data) { - $('#displayPlaylistHeader').find('h1').text(playlistRequestName); - - $('#displayPlaylistSaveButton').hide().unbind('click').click(function () { - var promises = []; - $('#displayPlaylistContentList').find('li').each(function (indx, elem) { - var newPos = $(elem).index(); - var oldPos = $(elem).data("oldPos"); - if (newPos != oldPos) { - var movedId = elem.id.replace("selectSongLine_", ""); - - promises.push(request({ - url: "moveSongInPlaylist?&newPosition=" + newPos + "&playlistId=" + playlistIdRequest + "&songId=" + movedId - }, "Resorting...")); + request({ + url: "hasUserRight?right=" + 128 + }).done(function (result) { + if (result) { + $('#selectPlaylistContentList').find('.delete').show(); + $('#selectPlaylistContentList').listview('refresh'); + } else { + $('#selectPlaylistContentList').find('.delete').hide(); + $('#selectPlaylistContentList').listview('refresh'); } }); - $.when.apply(promises).done(function () { - //reload data - request({ - url: "getPlaylistSongs?playlistId=" + playlistIdRequest - }).done(function (data2) { - handleGetAllPlaylistSongs(data2); - }); + $('#selectPlaylistAddPlaylistButton').unbind('click').hide().click(function () { + var name = prompt("Name of the new playlist:", "NewPlaylistName"); + if (name != null + && name.replace(" ", "") != "" + && $('h2').filter(function () { return this.textContent == name; }).length == 0) { + request({ url: "addPlaylist?playlistName=" + name }, "Creating...").done(function () { + request({ + url: "getPlaylists" + }).done(function (data2) { + handleGetAllPlaylists(data2); + }); + }); + } else { + alert(i18n.t("This is not a valid name.")); + } }); - }); - $('#displayPlaylistContentList').children().remove(); - - function handleSelectPlaylistSongLineClick(e) { - songIdRequest = parseInt(e.currentTarget.parentElement.parentElement.parentElement.id.replace("selectSongLine_", "")); - $.mobile.changePage("#displaySong", { transition: "slidefade" }); + request({ + url: "hasUserRight?right=" + 64 + }).done(function (result) { + if (result) { + $('#selectPlaylistAddPlaylistButton').show(); + } else { + $('#selectPlaylistAddPlaylistButton').hide(); + } + }); } - function handleSelectPlaylistSongLineDeleteClick(e) { - var songToDeleteId = parseInt(e.currentTarget.parentElement.id.replace("selectSongLine_", "")); - var songToDeleteName = $(e.currentTarget.parentElement).find('h2').text(); + var promise = request({ + url: "getPlaylists" + }).done(function (data) { + handleGetAllPlaylists(data); + }); - if (window.confirm("Do you really want to delete this song from playlist:\n" + songToDeleteName)) { - request({ - url: "/removeSongFromPlaylist?position=" + $('#selectSongLine_' + songToDeleteId).index() - + "&playlistId=" + playlistIdRequest - + "&songId=" + songToDeleteId - }, "Loading...").done(function () { + // Save promise on page so the transition handler can find it. + $(this).data('promise', promise); + + }; + + var pagebeforeshowDisplayPlaylist = function () { + + function handleGetAllPlaylistSongs(data) { + $('#displayPlaylistHeader').find('h1').text(playlistRequestName); + + $('#displayPlaylistSaveButton').hide().unbind('click').click(function () { + var promises = []; + $('#displayPlaylistContentList').find('li').each(function (indx, elem) { + var newPos = $(elem).index(); + var oldPos = $(elem).data("oldPos"); + if (newPos != oldPos) { + var movedId = elem.id.replace("selectSongLine_", ""); + + promises.push(request({ + url: "moveSongInPlaylist?&newPosition=" + newPos + "&playlistId=" + playlistIdRequest + "&songId=" + movedId + }, "Resorting...")); + } + }); + + $.when.apply(promises).done(function () { //reload data request({ url: "getPlaylistSongs?playlistId=" + playlistIdRequest @@ -630,659 +1280,167 @@ function initPageLoadHandler() { handleGetAllPlaylistSongs(data2); }); }); + }); + + $('#displayPlaylistContentList').children().remove(); + + function handleSelectPlaylistSongLineClick(e) { + pageHandler.songIdRequest = parseInt(e.currentTarget.parentElement.parentElement.parentElement.id.replace("selectSongLine_", "")); + $.mobile.changePage("#displaySong", { transition: "slidefade" }); } + function handleSelectPlaylistSongLineDeleteClick(e) { + var songToDeleteId = parseInt(e.currentTarget.parentElement.id.replace("selectSongLine_", "")); + var songToDeleteName = $(e.currentTarget.parentElement).find('h2').text(); - } - - var sortedData = []; - - for (var id1 in data) { - sortedData[data[id1].PlaylistPosition] = data[id1].Song; - } - var i = 0; - for (var id in sortedData) { - var line = $('
  • ' - + sortedData[id].Artist - + '

    ' - + sortedData[id].Title - + '

    Delete
  • ') - .appendTo('#displayPlaylistContentList').data("oldPos", i++); - - line.find('a:not(.delete)').click(handleSelectPlaylistSongLineClick); - line.find('a.delete').click(handleSelectPlaylistSongLineDeleteClick); - - var img = line.find("img")[0]; - - addImage(img, sortedData[id].Cover, "img/noCover.png"); - } - - $('#displayPlaylistContentList').listview('refresh'); - - request({ - url: "hasUserRight?right=" + 256 - }).done(function (result) { - if (result) { - $('#displayPlaylistContentList').find('.delete').show(); - $('#displayPlaylistContentList').listview('refresh'); - } else { - $('#displayPlaylistContentList').find('.delete').hide(); - $('#displayPlaylistContentList').listview('refresh'); - } - }); - - request({ - url: "hasUserRight?right=" + 16 - }).done(function (result) { - if (result) { - $('#displayPlaylistContentList').sortable({ - axis: 'y', - sort: function () { - $('#displayPlaylistSaveButton').show(); - - var $lis = $(this).children('li'); - $lis.each(function () { - var $li = $(this); - var hindex = $lis.filter('.ui-sortable-helper').index(); - if (!$li.is('.ui-sortable-helper')) { - var index = $li.index(); - index = index < hindex ? index + 1 : index; - - $li.val(index); - - if ($li.is('.ui-sortable-placeholder')) { - $lis.filter('.ui-sortable-helper').val(index); - } - } + if (window.confirm("Do you really want to delete this song from playlist:\n" + songToDeleteName)) { + request({ + url: "/removeSongFromPlaylist?position=" + $('#selectSongLine_' + songToDeleteId).index() + + "&playlistId=" + playlistIdRequest + + "&songId=" + songToDeleteId + }, "Loading...").done(function () { + //reload data + request({ + url: "getPlaylistSongs?playlistId=" + playlistIdRequest + }).done(function (data2) { + handleGetAllPlaylistSongs(data2); }); - } - }); + }); + } + + } - }); - } - var promise = request({ - url: "getPlaylistSongs?playlistId=" + playlistIdRequest - }).done(function (data) { - handleGetAllPlaylistSongs(data); - }); + var sortedData = []; - // Save promise on page so the transition handler can find it. - $(this).data('promise', promise); + for (var id1 in data) { + sortedData[data[id1].PlaylistPosition] = data[id1].Song; + } + var i = 0; + for (var id in sortedData) { + var line = $('
  • ' + + sortedData[id].Artist + + '

    ' + + sortedData[id].Title + + '

    Delete
  • ') + .appendTo('#displayPlaylistContentList').data("oldPos", i++); - }); -} + line.find('a:not(.delete)').click(handleSelectPlaylistSongLineClick); + line.find('a.delete').click(handleSelectPlaylistSongLineDeleteClick); -function pagebeforeshowLogin() { - if (window.localStorage) { - var value = window.localStorage.getItem("VocaluxeSessionKey"); - if (value != null && value != "") { - sessionId = value; - } - } + var img = line.find("img")[0]; - if (sessionId != "") { - if (ownProfileId != -1) { - $.mobile.changePage("#main", { transition: "slidefade" }); - } - else { - request({ - url: "getOwnProfileId", - headers: { "session": sessionId } - }, 'Login...').done(function (result) { - ownProfileId = result; - $.mobile.changePage("#main", { transition: "slidefade" }); - }); - } - } -} + imageLoader.addImage(img, sortedData[id].Cover, "img/noCover.png"); + } -function pagebeforeshowDiscover() { - if (document.location.protocol == "file:") { - if (window.localStorage) { - var address = window.localStorage.getItem("VocaluxeServerAddress"); - if (address != null) { - serverBaseAddress = ""; - var prom = request({ - url: address + "isServerOnline", - timeout: 10000 - }, "Checking...").done(function () { - serverBaseAddress = address; - window.localStorage.setItem("VocaluxeServerAddress", address); - $.mobile.changePage("#login", { transition: "none" }); - }).fail(function () { - if (typeof window.BarcodeScanner != "undefined") { - $('#discoverReadQr').show(); + $('#displayPlaylistContentList').listview('refresh'); + + request({ + url: "hasUserRight?right=" + 256 + }).done(function (result) { + if (result) { + $('#displayPlaylistContentList').find('.delete').show(); + $('#displayPlaylistContentList').listview('refresh'); + } else { + $('#displayPlaylistContentList').find('.delete').hide(); + $('#displayPlaylistContentList').listview('refresh'); } }); - $(this).data('promise', prom); + + request({ + url: "hasUserRight?right=" + 16 + }).done(function (result) { + if (result) { + $('#displayPlaylistContentList').sortable({ + axis: 'y', + sort: function () { + $('#displayPlaylistSaveButton').show(); + + var $lis = $(this).children('li'); + $lis.each(function () { + var $li = $(this); + var hindex = $lis.filter('.ui-sortable-helper').index(); + if (!$li.is('.ui-sortable-helper')) { + var index = $li.index(); + index = index < hindex ? index + 1 : index; + + $li.val(index); + + if ($li.is('.ui-sortable-placeholder')) { + $lis.filter('.ui-sortable-helper').val(index); + } + } + }); + } + }); + } + }); + } + + var promise = request({ + url: "getPlaylistSongs?playlistId=" + playlistIdRequest + }).done(function (data) { + handleGetAllPlaylistSongs(data); + }); + + // Save promise on page so the transition handler can find it. + $(this).data('promise', promise); + + }; + + init(); + } + + function SessionHandler() { + this.ownProfileId = -1; + this.sessionId = ""; + this.serverBaseAddress = ""; + + var t = this; + + var init = function () { + initHeartbeat(); + }; + + this.logout = function () { + t.ownProfileId = -1; + + t.sessionId = ""; + + pageHandler.reset(); + + if (window.localStorage) { + window.localStorage.setItem("VocaluxeSessionKey", ""); + } + $.mobile.changePage("#login", { transition: "slidefade" }); + }; + + + var checkSession = function () { + if (t.ownProfileId == -1 + && pageHandler.profileIdRequest == -1 + && ($.mobile.activePage.attr("id") == "displayProfile" || $.mobile.activePage.attr("id") == "login" || $.mobile.activePage.attr("id") == "discover")) { return; } - if (typeof window.BarcodeScanner != "undefined") { - $('#discoverReadQr').show(); - } - } - } else { - $('#discoverReadQr').hide(); - $.mobile.changePage("#login", { transition: "none" }); - } -} - -function initLoginPageHandler() { - var keyPressed = function (e) { - if (e.which == 13) { - $('#loginButton').click(); - } - }; - - $('#loginName').keypress(keyPressed); - $('#loginPassword').keypress(keyPressed); - - $('#loginButton').click(function () { - var username = $('#loginName').prop("value"); - var password = $('#loginPassword').prop("value"); - - request({ - url: "login?username=" + username + "&password=" + password - }).done(function (result) { - sessionId = result; - if (window.localStorage) { - window.localStorage.setItem("VocaluxeSessionKey", sessionId); - } request({ - url: "getOwnProfileId", - headers: { "session": sessionId } - }, 'Login...').done(function (result2) { - ownProfileId = result2; - $.mobile.changePage("#main", { transition: "slidefade" }); - }); - }); - }); - - $('#registerButton').click(function () { - ownProfileId = -1; - profileIdRequest = -1; - $.mobile.changePage("#displayProfile", { transition: "slidefade" }); - }); - - //Fire pageLoadHandler for login - //pagebeforeshowLogin(); -} - -function initMainPageHandler() { - $('#yourProfileLink').click(function () { - profileIdRequest = ownProfileId; - $.mobile.changePage("#displayProfile", { transition: "slidefade" }); - }); - - $('#currentSongLink').click(function () { - request({ - url: "getCurrentSongId", - headers: { "session": sessionId } - }, 'Getting current song...').done(function (result) { - songIdRequest = parseInt(result); - $.mobile.changePage("#displaySong", { transition: "slidefade" }); - }); - }); - - function uploadImg(imgData) { - request({ - url: "sendPhoto", - contentType: "application/json;charset=utf-8", - type: "POST", - data: JSON.stringify({ Photo: { base64Data: imgData } }) - }, 'Uploading photo...'); - } - - $('#mainPageTakePhotoLink').click(function () { - if ($('#captureContainer').length > 0) { - $('#captureContainer').remove(); - } - - if (document.location.protocol == "file:" - && typeof (navigator) != 'undefined' - && typeof (navigator.camera) != 'undefined' - && typeof (navigator.camera.getPicture) != 'undefined') { - navigator.camera.getPicture(function (imageData) { - uploadImg("data:image/jpeg;base64," + imageData); - }, function () { - //Fail - do nothing - }, { - destinationType: navigator.camera.DestinationType.DATA_URL, - allowEdit: true, - correctOrientation: true, - saveToPhotoAlbum: true, - quality: 100 - }); - - } else { - $(document.body).append('
    '); - - $('#capture').change(function (eventData) { - if (eventData && eventData.target && eventData.target.files && eventData.target.files.length == 1) { - var file = eventData.target.files[0]; - var reader = new FileReader(); - - reader.onloadend = function (e) { - uploadImg(e.target.result); - $('#capture').remove(); - }; - - reader.readAsDataURL(file); + url: "getOwnProfileId" + }, "noOverlay").done(function (result) { + if (result == -1) { + t.logout(); } + }).fail(function (result) { + t.logout(); }); - - $('#capture').click(); - } - }); - - $('#mainPageLogoutLink').click(function () { - logout(); - }); -} - -function initKeyboardPageHandler() { - $('#keyboardButtonUp').click(function () { - request({ - url: "sendKeyEvent?key=up" - }); - }); - - $('#keyboardButtonDown').click(function () { - request({ - url: "sendKeyEvent?key=down" - }); - }); - - $('#keyboardButtonLeft').click(function () { - request({ - url: "sendKeyEvent?key=left" - }); - }); - - $('#keyboardButtonRight').click(function () { - request({ - url: "sendKeyEvent?key=right" - }); - }); - - $('#keyboardButtonEscape').click(function () { - request({ - url: "sendKeyEvent?key=escape" - }); - }); - - $('#keyboardButtonTab').click(function () { - request({ - url: "sendKeyEvent?key=tab" - }); - }); - - $('#keyboardButtonReturn').click(function () { - request({ - url: "sendKeyEvent?key=return" - }); - }); - - $('#keyboardButtonP').click(function () { - request({ - url: "sendKeyEvent?key=p" - }); - }); - - $('#keyboardButtonKeys').keyup(function (e) { - var c = String.fromCharCode(e.keyCode); - if (c.match(/\w/)) { - c = e.keyCode >= 65 ? c.toLowerCase() : c; - request({ - url: "sendKeyEvent?key=" + c - }); - } - var oldText = $('#keyboardButtonKeys')[0].value; - if (oldText.length > 0) { - $('#keyboardButtonKeys')[0].value = oldText.slice(1); - } - }); -} - -function initDiscoverPageHandler() { - var keyPressed = function (e) { - if (e.which == 13) { - $('#discoverConnect').click(); - } - }; - - $('#discoverServerAddress').keypress(keyPressed); - - function handleAddress(address) { - if (address != null && address != "") { - if (address.indexOf("http") != 0) { - address = "http://" + address; - } - if (address.slice(-1) != '/') { - address = address + '/'; - } - serverBaseAddress = ""; - request({ - url: address + "isServerOnline", - timeout: 10000 - }, "Checking...") - .done(function () { - serverBaseAddress = address; - window.localStorage.setItem("VocaluxeServerAddress", address); - $.mobile.changePage("#login", { transition: "slidefade" }); - }) - .fail(function () { - $('#discoverServerAddress').prop("value", ""); - if (document.location.protocol == "file:" - && typeof window.BarcodeScanner != "undefined") { - $('#discoverReadQr').show(); - } - }); - } - } - - $('#discoverConnect').click(function () { - handleAddress($('#discoverServerAddress').prop("value")); - }); - - try { - window.BarcodeScanner = cordova.require("cordova/plugin/BarcodeScanner"); - } catch (e) { } - - $('#discoverReadQr').hide().click(function () { - window.BarcodeScanner.scan( - function (result) { - handleAddress(result.text); - }, - function () { - showError("Scan faild"); - } - ); - }); - - //Fire pageLoadHandler for discover (first page shown after start) - setTimeout(function () { - pagebeforeshowDiscover(); - $(this).removeData('promise'); - }, 1); -} - -var cachedImages = {}; - -function delayedImageLoad(elem, id, fail) { - if (elem && id) { - if (cachedImages[id]) { - elem.src = cachedImages[id].base64Data; - return; - } - - elem.src = ""; - $(elem).addClass("imageLoaderImg"); - request({ - url: "delayedImage?id=" + id - }).done(function (result) { - $(elem).removeClass("imageLoaderImg"); - elem.src = result.base64Data; - cachedImages[id] = result; - }).fail(function () { - $(elem).removeClass("imageLoaderImg"); - if (fail) { - elem.src = fail; - } - }); - } -} - -function addImage(img, base64Image, defaultImg) { - if (base64Image && (base64Image.base64Data || base64Image.imageId)) { - if (base64Image.base64Data) { - $(img).prop("src", base64Image.base64Data); - } - else { - delayedImageLoad(img, base64Image.imageId, defaultImg); - } - } - else { - $(img).prop("src", defaultImg); - } -} - -function logout() { - ownProfileId = -1; - profileIdRequest = -1; - songIdRequest = -1; - sessionId = ""; - if (window.localStorage) { - window.localStorage.setItem("VocaluxeSessionKey", ""); - } - $.mobile.changePage("#login", { transition: "slidefade" }); -} - -function checkSession() { - if (ownProfileId == -1 - && profileIdRequest == -1 - && ($.mobile.activePage.attr("id") == "displayProfile" || $.mobile.activePage.attr("id") == "login" || $.mobile.activePage.attr("id") == "discover")) { - return; - } - request({ - url: "getOwnProfileId" - }, "noOverlay").done(function (result) { - if (result == -1) { - logout(); - } - }).fail(function (result) { - logout(); - }); -} - -function initHeartbeat() { - setInterval(checkSession, 20000); -} - -function request(data, message) { - if ((typeof message) == "undefined" || message == null) { - message = "Loading..."; - } - - if ((typeof data.timeout) == "undefined") { - data.timeout = 10000; //10 sec. timeout - } - - if (message != "noOverlay") { - var message2 = message; - if (i18n.t) { - message2 = i18n.t(message2); - } - $('div[data-role="content"]').wrap('
    '); - $.mobile.loading('show', { - text: message2, - textVisible: true - }); - } - - if (!data["headers"]) { - data["headers"] = {}; - } - - if (message == "external") { - message = "Loading (external)..."; - if (i18n.t) { - message = i18n.t(message) || message; - } - } else { - data["headers"]["session"] = sessionId; - data.url = serverBaseAddress + data.url; - } - - return $.ajax(data).always(function (result) { - if (message != "noOverlay") { - $.mobile.loading('hide'); - $('div[data-role="content"]').unwrap(); - } - }).fail(function (result) { - if (result.statusText.indexOf("No session") != -1) { - logout(); - return; - } - if (message != "noOverlay") { - var msg = result.statusText.length <= 20 ? result.statusText : "Error..."; - if (msg == "error" && result.readyState == 0) { - msg = "No connection"; - } - showError(msg); - } - }); -} - -function showError(message) { - if (!message) { - message = "Error..."; - } - - if (i18n.t) { - message = i18n.t(message) || message; - } - - $('div[data-role="content"]').wrap('
    '); - $.mobile.loading('show', { - text: message, - textVisible: true - }); - $('.ui-loader').find('span').removeClass('ui-icon-loading').addClass('ui-custom-errorIcon'); - - setTimeout(function () { - $.mobile.loading('hide'); - $('div[data-role="content"]').unwrap(); - $('.ui-loader').find('span').removeClass('ui-custom-errorIcon').addClass('ui-icon-loading'); - }, 1000); -} - -var popupVideoHeight = 390; -var popupVideoWidth = 640; -function initVideoPopup() { - 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); + var initHeartbeat = function () { + setInterval(checkSession, 20000); + }; - $("#popupVideo").on({ - popupbeforeposition: function () { - var size = scale(popupVideoWidth, popupVideoHeight, 15, 1), - w = size.width, - h = size.height; + init(); + } - $("#popupVideo iframe") - .attr("width", w) - .attr("height", h); - }, - popupafterclose: function () { - $("#popupVideo iframe") - .attr("width", 0) - .attr("height", 0) - .attr("src", ""); - } - }); -}; - -function showYoutube(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"); - } - }); -} - -function showSpotify(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"); - } - }); -} - -function showWikipedia(artist) { - popupVideoHeight = 800; - popupVideoWidth = 600; - - $("#popupVideo iframe").attr("src", "http://m.wikipedia.org/wiki/Special:Search/" + artist); - $("#popupVideo").popup("open"); -} - -function initTranslation() { - - //repair broken buttons on the first page (get broken while translating) - var repairButtons = function () { - $($('#discoverConnect')[0].childNodes).wrap(' '); - $($('#discoverReadQr')[0].childNodes).wrap(' '); - }; - - $.i18n.init({ - resGetPath: 'locales/__lng__.json', - supportedLngs: ['en', 'de', 'fr', 'sv', 'cs'], - fallbackLng: 'en', - keyseparator: '::', - nsseparator: ':::' - }).done(function () { - translationLoaded.resolve(); - }); -} - -function translate() { - //repair broken buttons on the first page (get broken while translating) - var repairButtons = function () { - $($('#discoverConnect')[0].childNodes).wrap(' '); - $($('#discoverReadQr')[0].childNodes).wrap(' '); - }; - $('body').i18n(); - repairButtons(); -} + initMain(); +})(); \ No newline at end of file diff --git a/Vocaluxe/Website/locales/de.json b/Vocaluxe/Website/locales/de.json index ddf85d71..d9f2420a 100644 --- a/Vocaluxe/Website/locales/de.json +++ b/Vocaluxe/Website/locales/de.json @@ -76,5 +76,11 @@ "discoverConnectServerAddress": "Serveradresse:", "discoverConnectButton": "Verbinden", "Checking...": "Prüfen...", - "timeout": "Zeitüberschreitung" + "timeout": "Zeitüberschreitung", + "keyboardButtonShift": "Umschalt", + "keyboardButtonAlt": "Alt", + "keyboardButtonCtrl": "Steuerung", + "keyboardButtonBackspace": "Rücktaste", + "keyboardAutoSend": "Tasten autom. senden", + "keyboardButtonSend": "Senden" } \ No newline at end of file diff --git a/Vocaluxe/Website/locales/en.json b/Vocaluxe/Website/locales/en.json index c6b28fd0..308d01c1 100644 --- a/Vocaluxe/Website/locales/en.json +++ b/Vocaluxe/Website/locales/en.json @@ -76,5 +76,11 @@ "discoverConnectServerAddress": "Serveraddress:", "discoverConnectButton": "Connect", "Checking...": "Checking...", - "timeout": "Timeout" + "timeout": "Timeout", + "keyboardButtonShift": "Shift", + "keyboardButtonAlt": "Alt", + "keyboardButtonCtrl": "Control", + "keyboardButtonBackspace": "Backspace", + "keyboardAutoSend": "Auto send keys", + "keyboardButtonSend": "Send" } \ No newline at end of file