From 35cdd55c4925b8518e73264097801073d746c17f Mon Sep 17 00:00:00 2001 From: lukeIam Date: Tue, 18 Feb 2014 16:37:41 +0100 Subject: [PATCH 01/22] Use auto-properties in CServer --- ClientServerLib/ClientServerLib/CServer.cs | 184 ++++----------------- 1 file changed, 28 insertions(+), 156 deletions(-) diff --git a/ClientServerLib/ClientServerLib/CServer.cs b/ClientServerLib/ClientServerLib/CServer.cs index ac50a6d5..76c762de 100644 --- a/ClientServerLib/ClientServerLib/CServer.cs +++ b/ClientServerLib/ClientServerLib/CServer.cs @@ -1,8 +1,8 @@ using System; -using System.ServiceModel; -using System.ServiceModel.Web; using System.Diagnostics; using System.Net; +using System.ServiceModel; +using System.ServiceModel.Web; namespace ServerLib { @@ -12,192 +12,64 @@ namespace ServerLib private Uri _BaseAddress; private bool _Encrypted = false; - private static SendKeyEventDelegate _SendKeyEvent; - public static SendKeyEventDelegate SendKeyEvent - { - internal get { return CServer._SendKeyEvent; } - set { CServer._SendKeyEvent = value; } - } + public static SendKeyEventDelegate SendKeyEvent { internal get; set; } #region profile + public static GetProfileDataDelegate GetProfileData { internal get; set; } - private static GetProfileDataDelegate _GetProfileData; - public static GetProfileDataDelegate GetProfileData - { - internal get { return CServer._GetProfileData; } - set { CServer._GetProfileData = value; } - } - - private static SendProfileDataDelegate _SendProfileData; - public static SendProfileDataDelegate SendProfileData - { - internal get { return CServer._SendProfileData; } - set { CServer._SendProfileData = value; } - } - - private static GetProfileListDelegate _GetProfileList; - public static GetProfileListDelegate GetProfileList - { - internal get { return CServer._GetProfileList; } - set { CServer._GetProfileList = value; } - } + public static SendProfileDataDelegate SendProfileData { internal get; set; } + public static GetProfileListDelegate GetProfileList { internal get; set; } #endregion #region photo - private static SendPhotoDelegate _SendPhoto; - public static SendPhotoDelegate SendPhoto - { - get { return CServer._SendPhoto; } - set { CServer._SendPhoto = value; } - } - + public static SendPhotoDelegate SendPhoto { internal get; set; } #endregion #region website + public static GetSiteFileDelegate GetSiteFile { internal get; set; } - private static GetSiteFileDelegate _GetSiteFile; - public static GetSiteFileDelegate GetSiteFile - { - internal get { return CServer._GetSiteFile; } - set { CServer._GetSiteFile = value; } - } - - private static GetDelayedImageDelegate _GetDelayedImage; - public static GetDelayedImageDelegate GetDelayedImage - { - internal get { return CServer._GetDelayedImage; } - set { CServer._GetDelayedImage = value; } - } - + public static GetDelayedImageDelegate GetDelayedImage { internal get; set; } #endregion #region songs + public static GetSongDelegate GetSong { internal get; set; } - private static GetSongDelegate _GetSong; - public static GetSongDelegate GetSong - { - internal get { return CServer._GetSong; } - set { CServer._GetSong = value; } - } - - private static GetAllSongsDelegate _GetAllSongs; - public static GetAllSongsDelegate GetAllSongs - { - internal get { return CServer._GetAllSongs; } - set { CServer._GetAllSongs = value; } - } - - private static GetCurrentSongIdDelegate _GetCurrentSongId; - public static GetCurrentSongIdDelegate GetCurrentSongId - { - internal get { return CServer._GetCurrentSongId; } - set { CServer._GetCurrentSongId = value; } - } - + public static GetAllSongsDelegate GetAllSongs { internal get; set; } + public static GetCurrentSongIdDelegate GetCurrentSongId { internal get; set; } #endregion #region playlist + public static GetPlaylistsDelegate GetPlaylists { internal get; set; } - private static GetPlaylistsDelegate _GetPlaylists; - public static GetPlaylistsDelegate GetPlaylists - { - internal get { return _GetPlaylists; } - set { _GetPlaylists = value; } - } + public static GetPlaylistDelegate GetPlaylist { internal get; set; } + public static AddSongToPlaylistDelegate AddSongToPlaylist { internal get; set; } - private static GetPlaylistDelegate _GetPlaylist; - public static GetPlaylistDelegate GetPlaylist - { - internal get { return _GetPlaylist; } - set { _GetPlaylist = value; } - } + public static RemoveSongFromPlaylistDelegate RemoveSongFromPlaylist { internal get; set; } - private static AddSongToPlaylistDelegate _AddSongToPlaylist; - public static AddSongToPlaylistDelegate AddSongToPlaylist - { - internal get { return _AddSongToPlaylist; } - set { _AddSongToPlaylist = value; } - } + public static MoveSongInPlaylistDelegate MoveSongInPlaylist { internal get; set; } - private static RemoveSongFromPlaylistDelegate _RemoveSongFromPlaylist; - public static RemoveSongFromPlaylistDelegate RemoveSongFromPlaylist - { - internal get { return _RemoveSongFromPlaylist; } - set { _RemoveSongFromPlaylist = value; } - } + public static PlaylistContainsSongDelegate PlaylistContainsSong { internal get; set; } - private static MoveSongInPlaylistDelegate _MoveSongInPlaylist; - public static MoveSongInPlaylistDelegate MoveSongInPlaylist - { - internal get { return _MoveSongInPlaylist; } - set { _MoveSongInPlaylist = value; } - } + public static GetPlaylistSongsDelegate GetPlaylistSongs { internal get; set; } - private static PlaylistContainsSongDelegate _PlaylistContainsSong; - public static PlaylistContainsSongDelegate PlaylistContainsSong - { - internal get { return _PlaylistContainsSong; } - set { _PlaylistContainsSong = value; } - } - - private static GetPlaylistSongsDelegate _GetPlaylistSongs; - public static GetPlaylistSongsDelegate GetPlaylistSongs - { - internal get { return _GetPlaylistSongs; } - set { _GetPlaylistSongs = value; } - } - - private static RemovePlaylistDelegate _RemovePlaylist; - public static RemovePlaylistDelegate RemovePlaylist - { - internal get { return _RemovePlaylist; } - set { _RemovePlaylist = value; } - } - - private static AddPlaylistDelegate _AddPlaylist; - public static AddPlaylistDelegate AddPlaylist - { - internal get { return _AddPlaylist; } - set { _AddPlaylist = value; } - } + public static RemovePlaylistDelegate RemovePlaylist { internal get; set; } + public static AddPlaylistDelegate AddPlaylist { internal get; set; } #endregion #region user management + public static ValidatePasswordDelegate ValidatePassword { internal get; set; } - private static ValidatePasswordDelegate _ValidatePassword; - public static ValidatePasswordDelegate ValidatePassword - { - internal get { return CServer._ValidatePassword; } - set { CServer._ValidatePassword = value; } - } + public static GetUserRoleDelegate GetUserRole { internal get; set; } - private static GetUserRoleDelegate _GetUserRole; - public static GetUserRoleDelegate GetUserRole - { - internal get { return CServer._GetUserRole; } - set { CServer._GetUserRole = value; } - } + public static SetUserRoleDelegate SetUserRole { internal get; set; } - private static SetUserRoleDelegate _SetUserRole; - public static SetUserRoleDelegate SetUserRole - { - internal get { return CServer._SetUserRole; } - set { CServer._SetUserRole = value; } - } - - private static GetUserIdFromUsernameDelegate _GetUserIdFromUsername; - public static GetUserIdFromUsernameDelegate GetUserIdFromUsername - { - internal get { return CServer._GetUserIdFromUsername; } - set { CServer._GetUserIdFromUsername = value; } - } - + public static GetUserIdFromUsernameDelegate GetUserIdFromUsername { internal get; set; } #endregion - + public CServer(int port, bool encrypted) { _Init(port, encrypted); @@ -206,7 +78,7 @@ namespace ServerLib public string GetBaseAddress() { return _BaseAddress.AbsoluteUri; - + /*IPAddress[] ips = Dns.GetHostAddresses(Dns.GetHostName()); foreach (IPAddress ip in ips) { @@ -305,7 +177,7 @@ namespace ServerLib ProcessStartInfo info = new ProcessStartInfo { FileName = "VocaluxeServerConfig.exe", - Arguments = port.ToString() + " " + (_Encrypted?"true":"false"), + Arguments = port.ToString() + " " + (_Encrypted ? "true" : "false"), UseShellExecute = true, CreateNoWindow = true, WindowStyle = ProcessWindowStyle.Hidden, From 3144ea24b9c230636ed2fcdbf7d09a5fd3649b8d Mon Sep 17 00:00:00 2001 From: lukeIam Date: Sat, 1 Mar 2014 15:43:02 +0100 Subject: [PATCH 02/22] Implemented a per player comunicationsystem for the app. --- ClientServerLib/ClientServerLib/CServer.cs | 4 +- .../ClientServerLib/CWebservice.cs | 36 ++- .../ClientServerLib/DataStructs.cs | 40 ++-- .../ClientServerLib/ICWebservice.cs | 7 + .../PlayerComunication/CUserCommunication.cs | 209 ++++++++++++++++++ .../DataTypes/CPlayerComunicationData.cs | 10 + .../CPlayerComunicationDataString.cs | 13 ++ .../CPlayerComunicationDataSubscription.cs | 15 ++ .../DataTypes/EPlayerComunicationType.cs | 12 + .../ClientServerLib/ServerLib.csproj | 6 + Vocaluxe.sln | 3 + Vocaluxe/Website/js/main.js | 144 ++++++++++-- 12 files changed, 455 insertions(+), 44 deletions(-) create mode 100644 ClientServerLib/ClientServerLib/PlayerComunication/CUserCommunication.cs create mode 100644 ClientServerLib/ClientServerLib/PlayerComunication/DataTypes/CPlayerComunicationData.cs create mode 100644 ClientServerLib/ClientServerLib/PlayerComunication/DataTypes/CPlayerComunicationDataString.cs create mode 100644 ClientServerLib/ClientServerLib/PlayerComunication/DataTypes/CPlayerComunicationDataSubscription.cs create mode 100644 ClientServerLib/ClientServerLib/PlayerComunication/DataTypes/EPlayerComunicationType.cs diff --git a/ClientServerLib/ClientServerLib/CServer.cs b/ClientServerLib/ClientServerLib/CServer.cs index 76c762de..a9306a8b 100644 --- a/ClientServerLib/ClientServerLib/CServer.cs +++ b/ClientServerLib/ClientServerLib/CServer.cs @@ -1,4 +1,5 @@ -using System; +using ServerLib.PlayerComunication; +using System; using System.Diagnostics; using System.Net; using System.ServiceModel; @@ -73,6 +74,7 @@ namespace ServerLib public CServer(int port, bool encrypted) { _Init(port, encrypted); + CPlayerCommunication.Init(); } public string GetBaseAddress() diff --git a/ClientServerLib/ClientServerLib/CWebservice.cs b/ClientServerLib/ClientServerLib/CWebservice.cs index 8da01ab2..4b319335 100644 --- a/ClientServerLib/ClientServerLib/CWebservice.cs +++ b/ClientServerLib/ClientServerLib/CWebservice.cs @@ -1,9 +1,10 @@ -using System; +using ServerLib.PlayerComunication; +using System; +using System.IO; using System.Net; using System.ServiceModel; -using System.ServiceModel.Web; -using System.IO; using System.ServiceModel.Channels; +using System.ServiceModel.Web; namespace ServerLib { @@ -82,8 +83,8 @@ namespace ServerLib if (profile.ProfileId != -1) //-1 is the id for a new profile { - if (CSessionControl.GetUserIdFromSession(sessionKey) != profile.ProfileId - && !(_CheckRight(EUserRights.EditAllProfiles) )) + if (CSessionControl.GetUserIdFromSession(sessionKey) != profile.ProfileId + && !(_CheckRight(EUserRights.EditAllProfiles))) { return; } @@ -303,7 +304,7 @@ namespace ServerLib { return true; } - + #endregion #region songs @@ -403,7 +404,7 @@ namespace ServerLib CServer.SetUserRole(profileId, userRole); } } - + public bool HasUserRight(int right) { return _CheckRightWithNoErrorMessage((EUserRights)right); @@ -452,7 +453,26 @@ namespace ServerLib return true; } + public SPlayerComunicationFrame[] PlayerComunication(SPlayerComunicationFrame[] recivedData) + { + Guid sessionKey = _GetSession(); + + if (sessionKey == Guid.Empty) + { + if (WebOperationContext.Current != null) + { + WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.Forbidden; + WebOperationContext.Current.OutgoingResponse.StatusDescription = "No session"; + } + + return null; + } + int userId = CSessionControl.GetUserIdFromSession(sessionKey); + CPlayerCommunication.AddMessagesFromPlayer(recivedData, userId); + + return CPlayerCommunication.GetAllMessagesForPlayer(userId); + } #endregion - + } } diff --git a/ClientServerLib/ClientServerLib/DataStructs.cs b/ClientServerLib/ClientServerLib/DataStructs.cs index cf52fd80..faba1680 100644 --- a/ClientServerLib/ClientServerLib/DataStructs.cs +++ b/ClientServerLib/ClientServerLib/DataStructs.cs @@ -1,9 +1,10 @@ -using System; +using ServerLib.PlayerComunication.DataTypes; +using System; +using System.Drawing; +using System.Drawing.Imaging; +using System.IO; using System.Linq; using System.Runtime.Serialization; -using System.Drawing; -using System.IO; -using System.Drawing.Imaging; using System.Text.RegularExpressions; namespace ServerLib @@ -108,8 +109,8 @@ namespace ServerLib public delegate SSongInfo[] GetAllSongsDelegate(); public delegate int GetCurrentSongIdDelegate(); - - + + [DataContract] public struct SSongInfo { @@ -155,26 +156,26 @@ namespace ServerLib [DataContract] public struct SPlaylistSongInfo { - [DataMember] + [DataMember] public SSongInfo Song; [DataMember] public int PlaylistId; - [DataMember] + [DataMember] public int PlaylistPosition; [DataMember] public int GameMode; } - + [DataContract] public struct SPlaylistInfo { - [DataMember] + [DataMember] public int PlaylistId; - [DataMember] + [DataMember] public string PlaylistName; - [DataMember] + [DataMember] public int SongCount; - [DataMember] + [DataMember] public string LastChanged; } @@ -192,5 +193,18 @@ namespace ServerLib public delegate int GetUserIdFromUsernameDelegate(string username); + [DataContract] + public struct SPlayerComunicationFrame + { + [DataMember] + public int ProfileId; + [DataMember] + public DateTime ValidTill; + [DataMember] + public EPlayerComunicationType Type; + [DataMember] + public String Data; + } + #endregion } diff --git a/ClientServerLib/ClientServerLib/ICWebservice.cs b/ClientServerLib/ClientServerLib/ICWebservice.cs index 3e79d8ce..b7401c6e 100644 --- a/ClientServerLib/ClientServerLib/ICWebservice.cs +++ b/ClientServerLib/ClientServerLib/ICWebservice.cs @@ -209,6 +209,13 @@ namespace ServerLib UriTemplate = "/hasUserRight?right={right}")] bool HasUserRight(int right); + [OperationContract] + [WebInvoke(Method = "POST", + ResponseFormat = WebMessageFormat.Json, + RequestFormat = WebMessageFormat.Json, + UriTemplate = "/playerComunication")] + SPlayerComunicationFrame[] PlayerComunication(SPlayerComunicationFrame[] recivedData); + #endregion } } \ No newline at end of file diff --git a/ClientServerLib/ClientServerLib/PlayerComunication/CUserCommunication.cs b/ClientServerLib/ClientServerLib/PlayerComunication/CUserCommunication.cs new file mode 100644 index 00000000..d1a3fce3 --- /dev/null +++ b/ClientServerLib/ClientServerLib/PlayerComunication/CUserCommunication.cs @@ -0,0 +1,209 @@ +using ServerLib.PlayerComunication.DataTypes; +using System; +using System.Collections.Generic; +using System.Runtime.Serialization; +using System.Threading; +using System.Web.Script.Serialization; + +namespace ServerLib.PlayerComunication +{ + public static class CPlayerCommunication + { + public delegate void IncommingMessageDelegate(CPlayerComunicationData data); + + private static readonly Dictionary> _OutgoingMessagesPerUser + = new Dictionary>(); + + private static readonly Queue _IncommingMessages = new Queue(); + + private static readonly Dictionary> _IncommingMessageHandler + = new Dictionary>(); + + private static readonly Dictionary> _Subscriptions + = new Dictionary>(); + + private static readonly Dictionary _TypeMapping + = new Dictionary(); + + internal static void Init() + { + SetDataType(EPlayerComunicationType.RegisterSubscription, typeof(CPlayerComunicationDataSubscription)); + AddIncommingHandler(EPlayerComunicationType.RegisterSubscription, + data => _AddSubscription(((CPlayerComunicationDataSubscription)data).Type, + ((CPlayerComunicationDataSubscription)data).PlayerId)); + + SetDataType(EPlayerComunicationType.UnregisterSubscription, typeof(CPlayerComunicationDataSubscription)); + AddIncommingHandler(EPlayerComunicationType.UnregisterSubscription, + data => _RemoveSubscription(((CPlayerComunicationDataSubscription)data).Type, + ((CPlayerComunicationDataSubscription)data).PlayerId)); + } + + public static void AddNewPlayerMessage(int targetPlayerId, + EPlayerComunicationType type, ISerializable data, + DateTime validTill) + { + if (!_OutgoingMessagesPerUser.ContainsKey(targetPlayerId)) + { + _OutgoingMessagesPerUser.Add(targetPlayerId, new List(2)); + } + + _OutgoingMessagesPerUser[targetPlayerId].Add(new SPlayerComunicationFrame + { + ProfileId = targetPlayerId, + Type = type, + Data = _SerializeHelper(data), + ValidTill = validTill + }); + } + + public static void AddNewPlayerMessage(int tagertPlayerId, + EPlayerComunicationType type, ISerializable data) + { + AddNewPlayerMessage(tagertPlayerId, type, data, DateTime.Now.AddMinutes(1)); + } + + public static void AddNewPlayerMessage(EPlayerComunicationType type, ISerializable data, + DateTime validTill) + { + if (_Subscriptions.ContainsKey(type)) + { + foreach (int subscribedPlayers in _Subscriptions[type]) + { + AddNewPlayerMessage(subscribedPlayers, type, data, validTill); + } + } + + } + + public static void AddNewPlayerMessage(EPlayerComunicationType type, ISerializable data) + { + AddNewPlayerMessage(type, data, DateTime.Now.AddMinutes(1)); + } + + internal static SPlayerComunicationFrame[] GetAllMessagesForPlayer(int playerId) + { + SPlayerComunicationFrame[] messages = null; + if (_OutgoingMessagesPerUser.ContainsKey(playerId)) + { + messages = _OutgoingMessagesPerUser[playerId].ToArray(); + _OutgoingMessagesPerUser[playerId].Clear(); + } + return new SPlayerComunicationFrame[]{ + new SPlayerComunicationFrame() + { + ProfileId = 0, + Type = EPlayerComunicationType.RegisterSubscription, + ValidTill = DateTime.Now.AddMinutes(1), + Data = _SerializeHelper(new CPlayerComunicationDataString(){Data = "Test"}) + } + }; + //return messages; + } + + public static void RemoveAllMessages(int playerId, EPlayerComunicationType type) + { + if (_OutgoingMessagesPerUser.ContainsKey(playerId)) + { + _OutgoingMessagesPerUser[playerId].RemoveAll(m => m.Type == type); + } + } + + internal static void AddMessagesFromPlayer(IEnumerable messages, int playerId) + { + if (messages == null || playerId < 0) + { + return; + } + + foreach (SPlayerComunicationFrame message in messages) + { + SPlayerComunicationFrame data = message; + data.ProfileId = playerId; + _IncommingMessages.Enqueue(data); + } + + if (_IncommingMessages.Count > 0) + { + ThreadPool.QueueUserWorkItem(_ProcessIncommingQueue); + } + } + + private static void _ProcessIncommingQueue(object dummy) + { + lock (_IncommingMessages) + { + foreach (SPlayerComunicationFrame message in _IncommingMessages) + { + if (_IncommingMessageHandler.ContainsKey(message.Type)) + { + List handlers = _IncommingMessageHandler[message.Type]; + var deserializedData = _DeserializeHelper(message.Data, message.Type); + foreach (IncommingMessageDelegate handler in handlers) + { + handler(deserializedData); + } + } + } + } + } + + public static void SetDataType(EPlayerComunicationType type, Type dataType) + { + if (_TypeMapping.ContainsKey(type)) + { + _TypeMapping.Add(type, dataType); + } + else + { + _TypeMapping[type] = dataType; + } + } + + public static void AddIncommingHandler(EPlayerComunicationType type, IncommingMessageDelegate handler) + { + if (!_IncommingMessageHandler.ContainsKey(type)) + { + _IncommingMessageHandler.Add(type, new List(2)); + } + + _IncommingMessageHandler[type].Add(handler); + } + + private static void _AddSubscription(EPlayerComunicationType type, int playerId) + { + if (!_Subscriptions.ContainsKey(type)) + { + _Subscriptions.Add(type, new List(2)); + } + if (!_Subscriptions[type].Contains(playerId)) + { + _Subscriptions[type].Add(playerId); + } + } + + private static void _RemoveSubscription(EPlayerComunicationType type, int playerId) + { + if (_Subscriptions.ContainsKey(type) && _Subscriptions[type].Contains(playerId)) + { + _Subscriptions[type].Remove(playerId); + } + } + + private static CPlayerComunicationData _DeserializeHelper(String data, EPlayerComunicationType type) + { + if (_TypeMapping.ContainsKey(type)) + { + return (CPlayerComunicationData)(new JavaScriptSerializer()).Deserialize(data, _TypeMapping[type]); + } + else + { + return new CPlayerComunicationDataString { Data = data }; + } + } + + private static string _SerializeHelper(Object data) + { + return (new JavaScriptSerializer()).Serialize(data); + } + } +} diff --git a/ClientServerLib/ClientServerLib/PlayerComunication/DataTypes/CPlayerComunicationData.cs b/ClientServerLib/ClientServerLib/PlayerComunication/DataTypes/CPlayerComunicationData.cs new file mode 100644 index 00000000..93a84041 --- /dev/null +++ b/ClientServerLib/ClientServerLib/PlayerComunication/DataTypes/CPlayerComunicationData.cs @@ -0,0 +1,10 @@ + +using System; + +namespace ServerLib.PlayerComunication.DataTypes +{ + [Serializable] + public abstract class CPlayerComunicationData + { + } +} diff --git a/ClientServerLib/ClientServerLib/PlayerComunication/DataTypes/CPlayerComunicationDataString.cs b/ClientServerLib/ClientServerLib/PlayerComunication/DataTypes/CPlayerComunicationDataString.cs new file mode 100644 index 00000000..dc933e80 --- /dev/null +++ b/ClientServerLib/ClientServerLib/PlayerComunication/DataTypes/CPlayerComunicationDataString.cs @@ -0,0 +1,13 @@ + +using System; +using System.Runtime.Serialization; + +namespace ServerLib.PlayerComunication.DataTypes +{ + [Serializable] + public class CPlayerComunicationDataString : CPlayerComunicationData + { + [DataMember] + public string Data { get; set; } + } +} diff --git a/ClientServerLib/ClientServerLib/PlayerComunication/DataTypes/CPlayerComunicationDataSubscription.cs b/ClientServerLib/ClientServerLib/PlayerComunication/DataTypes/CPlayerComunicationDataSubscription.cs new file mode 100644 index 00000000..e68c9630 --- /dev/null +++ b/ClientServerLib/ClientServerLib/PlayerComunication/DataTypes/CPlayerComunicationDataSubscription.cs @@ -0,0 +1,15 @@ + +using System; +using System.Runtime.Serialization; + +namespace ServerLib.PlayerComunication.DataTypes +{ + [Serializable] + public class CPlayerComunicationDataSubscription : CPlayerComunicationData + { + [DataMember] + public EPlayerComunicationType Type { get; set; } + [DataMember] + public int PlayerId { get; set; } + } +} diff --git a/ClientServerLib/ClientServerLib/PlayerComunication/DataTypes/EPlayerComunicationType.cs b/ClientServerLib/ClientServerLib/PlayerComunication/DataTypes/EPlayerComunicationType.cs new file mode 100644 index 00000000..de16c795 --- /dev/null +++ b/ClientServerLib/ClientServerLib/PlayerComunication/DataTypes/EPlayerComunicationType.cs @@ -0,0 +1,12 @@ + +using System; + +namespace ServerLib.PlayerComunication.DataTypes +{ + [Serializable] + public enum EPlayerComunicationType + { + RegisterSubscription, + UnregisterSubscription + } +} diff --git a/ClientServerLib/ClientServerLib/ServerLib.csproj b/ClientServerLib/ClientServerLib/ServerLib.csproj index 21ee0f0e..27606601 100644 --- a/ClientServerLib/ClientServerLib/ServerLib.csproj +++ b/ClientServerLib/ClientServerLib/ServerLib.csproj @@ -58,6 +58,7 @@ + @@ -67,9 +68,14 @@ + + + + + diff --git a/Vocaluxe.sln b/Vocaluxe.sln index 5d225110..091b83d9 100644 --- a/Vocaluxe.sln +++ b/Vocaluxe.sln @@ -183,4 +183,7 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(Performance) = preSolution + HasPerformanceSessions = true + EndGlobalSection EndGlobal diff --git a/Vocaluxe/Website/js/main.js b/Vocaluxe/Website/js/main.js index 53b892be..75220d70 100644 --- a/Vocaluxe/Website/js/main.js +++ b/Vocaluxe/Website/js/main.js @@ -8,6 +8,7 @@ var customSelectPlaylistSongCallback = null; var sessionId = ""; var serverBaseAddress = ""; var translationLoaded; +var playerComunication = new PlayerComunication(); if (document.location.protocol == "file:") { if (typeof (window.deviceAndJqmLoaded) == "undefined") { @@ -39,7 +40,6 @@ function start() { initMainPageHandler(); initDiscoverPageHandler(); initLoginPageHandler(); - initHeartbeat(); initVideoPopup(); } @@ -1055,33 +1055,15 @@ function logout() { profileIdRequest = -1; songIdRequest = -1; sessionId = ""; + + playerComunication.reset(); + 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..."; @@ -1286,3 +1268,121 @@ function translate() { $('body').i18n(); repairButtons(); } + +function PlayerComunication() { + var playerComunicationToServer = []; + var playerComunicationFromServerHandler = {}; + var defaultHeartbeatIntervall = 5000; + var heartbeatIntervalls = []; + var heartbeatIntervallId; + + var init = function () { + startHeartbeat(); + }; + + var checkPlayerMessages = function () { + if (ownProfileId == -1 + && profileIdRequest == -1 + && ($.mobile.activePage.attr("id") == "displayProfile" + || $.mobile.activePage.attr("id") == "login" + || $.mobile.activePage.attr("id") == "discover")) { + return; + } + + request({ + url: "playerComunication", + type: "POST", + dataType: "json", + contentType: "application/json", + data: JSON.stringify(playerComunicationToServer) + }, "noOverlay").done(function (result) { + if (result.length > 0) { + handlePlayerComunicationFromServer(result); + } + }).fail(function (result) { + if (result.status == 403 || result.status == 0) { + logout(); + } + }); + + if (playerComunicationToServer.length > 0) { + setTimeout(checkPlayerMessages, 50); + } + + playerComunicationToServer = []; + }; + + var handlePlayerComunicationFromServer = function (items) { + for (var i = 0; i < items.length; i++) { + if (items[i].ProfileId == ownProfileId && playerComunicationFromServerHandler[items[i].Type]) { + if (new Date() - new Date(parseInt("\/Date(1234656000000)\/".match(/[0-9]+/)[0])) <= 0) { + var deserializedData = JSON.parse(items[i].Data); + for (var j = 0; j < playerComunicationFromServerHandler[items[i].Type]; j++) { + playerComunicationFromServerHandler[items[i].Type][j](deserializedData); + } + } + } + } + }; + + var startHeartbeat = function () { + var interv = defaultHeartbeatIntervall; + for (var i = 0; i < heartbeatIntervalls.length; i++) { + if (interv > heartbeatIntervalls[i] && heartbeatIntervalls[i] >= 50) { + interv = heartbeatIntervalls[i]; + } + } + + if (interv == defaultHeartbeatIntervall && heartbeatIntervalls.length != 0) { + heartbeatIntervalls = []; + } + + clearInterval(heartbeatIntervallId); + heartbeatIntervallId = setInterval(checkPlayerMessages, interv); + }; + + var sendPlayerComunicationToServer = function (packet) { + playerComunicationToServer.push(packet); + }; + + this.registerPlayerComunicationFromServerHandler = function (type, handler) { + if (!playerComunicationFromServerHandler[type]) { + playerComunicationFromServerHandler[type] = []; + } + playerComunicationFromServerHandler[type].push(handler); + }; + + this.sendDataToServer = function (data, type) { + sendPlayerComunicationToServer({ + "ProfileId": ownProfileId, + "ValidTill": "\/Date(" + (((new Date())).getTime() + 60000) + ")\/", + "Type": type, + "Data": JSON.stringify(data) + }); + }; + + //mim 50ms + this.requestIntervall = function (newIntervall) { + heartbeatIntervalls.push(newIntervall); + }; + + this.removeIntervall = function (oldIntervall) { + var index = heartbeatIntervalls.indexOf(oldIntervall); + if (index > -1) { + heartbeatIntervalls.splice(oldIntervall, 1); + } + }; + + this.reset = function () { + playerComunicationToServer = []; + playerComunicationFromServerHandler = {}; + heartbeatIntervalls = []; + }; + + this.EPlayerComunicationType = { + "RegisterSubscription": 0, + "UnregisterSubscription": 1 + }; + + init(); +} \ No newline at end of file From c93262fc5415881732784c010833282cb3d83f6a Mon Sep 17 00:00:00 2001 From: lukeIam Date: Sun, 2 Mar 2014 12:02:30 +0100 Subject: [PATCH 03/22] Fix: can't show own profile --- ClientServerLib/ClientServerLib/CWebservice.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ClientServerLib/ClientServerLib/CWebservice.cs b/ClientServerLib/ClientServerLib/CWebservice.cs index 4b319335..1fa5251a 100644 --- a/ClientServerLib/ClientServerLib/CWebservice.cs +++ b/ClientServerLib/ClientServerLib/CWebservice.cs @@ -106,7 +106,7 @@ namespace ServerLib public SProfileData GetProfile(int profileId) { Guid sessionKey = _GetSession(); - if (_CheckRight(EUserRights.ViewOtherProfiles) || CSessionControl.GetUserIdFromSession(sessionKey) == profileId) + if (CSessionControl.GetUserIdFromSession(sessionKey) == profileId || _CheckRight(EUserRights.ViewOtherProfiles)) { if (CServer.GetProfileData == null) { @@ -469,7 +469,7 @@ namespace ServerLib } int userId = CSessionControl.GetUserIdFromSession(sessionKey); CPlayerCommunication.AddMessagesFromPlayer(recivedData, userId); - + return CPlayerCommunication.GetAllMessagesForPlayer(userId); } #endregion From 3350eb16deb6af81a1e4aec595addccec3a6f244 Mon Sep 17 00:00:00 2001 From: lukeIam Date: Sun, 2 Mar 2014 12:14:38 +0100 Subject: [PATCH 04/22] Fix: sometimes there is no back button in app --- Vocaluxe/Website/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Vocaluxe/Website/index.html b/Vocaluxe/Website/index.html index 1ce7b1e6..0501220f 100644 --- a/Vocaluxe/Website/index.html +++ b/Vocaluxe/Website/index.html @@ -78,7 +78,7 @@ -
+

Volcaluxe

From 7680aad78c64dda7d0022abcadfbc6693c7c947c Mon Sep 17 00:00:00 2001 From: lukeIam Date: Sun, 2 Mar 2014 12:18:51 +0100 Subject: [PATCH 05/22] Mod: Refactored main.js for better structure and readability (grouped methods, which belongs together) --- Vocaluxe/Website/js/main.js | 2665 ++++++++++++++++++----------------- 1 file changed, 1387 insertions(+), 1278 deletions(-) diff --git a/Vocaluxe/Website/js/main.js b/Vocaluxe/Website/js/main.js index 75220d70..9f960bd1 100644 --- a/Vocaluxe/Website/js/main.js +++ b/Vocaluxe/Website/js/main.js @@ -1,628 +1,1358 @@ -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; -var playerComunication = new PlayerComunication(); +(function () { + var playerComunication; + 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(); - 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(); + + sessionHandler = new SessionHandler(); + imageLoader = new ImageLoader(); + externalServices = new ExternalServices(); + pageHandler = new PageHandler(); + playerComunication = new PlayerComunication(); + - //pageLoadHandler for displayProfile - $(document).on('pagebeforeshow', '#displayProfile', function () { - if (profileIdRequest >= 0) { - var promise = request({ - url: "getProfile?profileId=" + profileIdRequest - }).done(function (result) { - handleDisplayProfileData(result); - - $('#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); - }); + this.addImage = function (img, base64Image, defaultImg) { + if (base64Image && (base64Image.base64Data || base64Image.imageId)) { + if (base64Image.base64Data) { + $(img).prop("src", base64Image.base64Data); + } else { + imageLoader.delayedImageLoad(img, base64Image.imageId, defaultImg); + } } else { - $('#displaySongLinks').hide(); + $(img).prop("src", defaultImg); + } + }; + } + + function PlayerComunication() { + var playerComunicationToServer = []; + var playerComunicationFromServerHandler = {}; + var defaultHeartbeatIntervall = 5000; + var heartbeatIntervalls = []; + var heartbeatIntervallId; + + var init = function () { + startHeartbeat(); + }; + + var checkPlayerMessages = function () { + if (sessionHandler.ownProfileId == -1 + && pageHandler.profileIdRequest == -1 + && ($.mobile.activePage.attr("id") == "displayProfile" + || $.mobile.activePage.attr("id") == "login" + || $.mobile.activePage.attr("id") == "discover")) { + return; } request({ - url: "hasUserRight?right=" + 32 - }).done(function (result2) { - if (result2) { - $('#displaySongAddPlaylist').show(); - } else { - $('#displaySongAddPlaylist').hide(); + url: "playerComunication", + type: "POST", + dataType: "json", + contentType: "application/json", + data: JSON.stringify(playerComunicationToServer) + }, "noOverlay").done(function (result) { + if (result.length > 0) { + handlePlayerComunicationFromServer(result); + } + }).fail(function (result) { + if (result.status == 403 || result.status == 0) { + sessionHandler.logout(); } }); - }); - // Save promise on page so the transition handler can find it. - $(this).data('promise', promise); - }); - - //pageLoadHandler for selectSong - $(document).on('pagebeforeshow', '#selectSong', function () { - function handleGetAllSongs() { - $('#selectSongList').children().remove(); - - function handleSelectSongLineClick(e) { - songIdRequest = parseInt(e.currentTarget.id.replace("selectSongLine_", "")); - $.mobile.changePage("#displaySong", { transition: "slidefade" }); + if (playerComunicationToServer.length > 0) { + setTimeout(checkPlayerMessages, 50); } - for (var id in allSongsCache) { - $('
  • '/*+' '*/ + '

    ' + allSongsCache[id].Artist + '

    ' + allSongsCache[id].Title + '

  • ') - .appendTo('#selectSongList') - .click(handleSelectSongLineClick); + playerComunicationToServer = []; + }; + + var handlePlayerComunicationFromServer = function (items) { + for (var i = 0; i < items.length; i++) { + if (items[i].ProfileId == sessionHandler.ownProfileId && playerComunicationFromServerHandler[items[i].Type]) { + if (new Date() - new Date(parseInt("\/Date(1234656000000)\/".match(/[0-9]+/)[0])) <= 0) { + var deserializedData = JSON.parse(items[i].Data); + for (var j = 0; j < playerComunicationFromServerHandler[items[i].Type]; j++) { + playerComunicationFromServerHandler[items[i].Type][j](deserializedData); + } + } + } + } + }; + + var startHeartbeat = function () { + var interv = defaultHeartbeatIntervall; + for (var i = 0; i < heartbeatIntervalls.length; i++) { + if (interv > heartbeatIntervalls[i] && heartbeatIntervalls[i] >= 50) { + interv = heartbeatIntervalls[i]; + } } - $('#selectSongList').listview('refresh'); - } + if (interv == defaultHeartbeatIntervall && heartbeatIntervalls.length != 0) { + heartbeatIntervalls = []; + } - if (allSongsCache == null) { - var promise = request({ - url: "getAllSongs" - }).done(function (data) { - allSongsCache = data; - handleGetAllSongs(); + clearInterval(heartbeatIntervallId); + heartbeatIntervallId = setInterval(checkPlayerMessages, interv); + }; + + var sendPlayerComunicationToServer = function (packet) { + playerComunicationToServer.push(packet); + }; + + this.registerPlayerComunicationFromServerHandler = function (type, handler) { + if (!playerComunicationFromServerHandler[type]) { + playerComunicationFromServerHandler[type] = []; + } + playerComunicationFromServerHandler[type].push(handler); + }; + + this.sendDataToServer = function (data, type) { + sendPlayerComunicationToServer({ + "ProfileId": sessionHandler.ownProfileId, + "ValidTill": "\/Date(" + (((new Date())).getTime() + 60000) + ")\/", + "Type": type, + "Data": JSON.stringify(data) + }); + }; + + //mim 50ms + this.requestIntervall = function (newIntervall) { + heartbeatIntervalls.push(newIntervall); + }; + + this.removeIntervall = function (oldIntervall) { + var index = heartbeatIntervalls.indexOf(oldIntervall); + if (index > -1) { + heartbeatIntervalls.splice(oldIntervall, 1); + } + }; + + this.reset = function () { + playerComunicationToServer = []; + playerComunicationFromServerHandler = {}; + heartbeatIntervalls = []; + }; + + this.EPlayerComunicationType = { + "RegisterSubscription": 0, + "UnregisterSubscription": 1 + }; + + init(); + } + + 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?? }); - // Save promise on page so the transition handler can find it. - $(this).data('promise', promise); - } - else { - handleGetAllSongs(); - } - }); + $("#popupVideo iframe") + .attr("width", 0) + .attr("height", 0); - //pageLoadHandler for selectUserAdmin - $(document).on('pagebeforeshow', '#selectUserAdmin', function () { - var promise = request({ - url: "getProfileList" - }).done(function (data) { - $('#selectUserAdminList').children().remove(); + $("#popupVideo").on({ + popupbeforeposition: function () { + var size = scale(popupVideoWidth, popupVideoHeight, 15, 1), + w = size.width, + h = size.height; - function handleSelectUserAdminLineClick(e) { - profileIdRequest = parseInt(e.currentTarget.id.replace("SelectUserAdminLine_", "")); - $.mobile.changePage("#displayUserAdmin", { transition: "slidefade" }); - } + $("#popupVideo iframe") + .attr("width", w) + .attr("height", h); + }, + popupafterclose: function () { + $("#popupVideo iframe") + .attr("width", 0) + .attr("height", 0) + .attr("src", ""); + } + }); + }; - for (var profile in data) { - $('
  • ' + data[profile].PlayerName + '

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

  • ') - .appendTo('#selectUserAdminList') - .click(handleSelectUserAdminLineClick); - } + 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; - $('#selectUserAdminList').listview('refresh'); - }); + $("#popupVideo iframe").attr("src", "http://www.youtube.com/embed/" + vidId + "?&autoplay=1&rel=0&showinfo=0&disablekb=1&autohide=1"); + $("#popupVideo").popup("open"); + } + }); + }; - // Save promise on page so the transition handler can find it. - $(this).data('promise', promise); - }); + 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; - //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 + $("#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; + + this.initTranslation = function () { + $.i18n.init({ + resGetPath: 'locales/__lng__.json', + supportedLngs: ['en', 'de', 'fr', 'sv', 'cs'], + fallbackLng: 'en', + keyseparator: '::', + nsseparator: ':::' + }).done(function () { + translationLoaded.resolve(); + }); + }; + + 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(); + }; + } + + function PageHandler() { + var loginPageHandler; + var discoverPageHandler; + var mainPageHandler; + var keyboardPageHandler; + var userPageHandler; + var songPageHandler; + var playlistPageHandler; + + this.customSelectPlaylistSongCallback = null; + this.profileIdRequest = -1; + this.songIdRequest = -1; + + 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(); + }; + + this.reset = function () { + this.customSelectPlaylistSongCallback = null; + this.profileIdRequest = -1; + this.songIdRequest = -1; + }; + + 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" + }); + }); + + $('#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); + } + }); + }; + + 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,759 +1360,138 @@ 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); - 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(); - } - }; + request({ + url: "hasUserRight?right=" + 16 + }).done(function (result) { + if (result) { + $('#displayPlaylistContentList').sortable({ + axis: 'y', + sort: function () { + $('#displayPlaylistSaveButton').show(); - $('#loginName').keypress(keyPressed); - $('#loginPassword').keypress(keyPressed); + 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; - $('#loginButton').click(function () { - var username = $('#loginName').prop("value"); - var password = $('#loginPassword').prop("value"); + $li.val(index); - 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); - } - }); - - $('#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(); + if ($li.is('.ui-sortable-placeholder')) { + $lis.filter('.ui-sortable-helper').val(index); + } + } + }); + } + }); } }); - } - } - - $('#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); - } -} + var promise = request({ + url: "getPlaylistSongs?playlistId=" + playlistIdRequest + }).done(function (data) { + handleGetAllPlaylistSongs(data); + }); -function logout() { - ownProfileId = -1; - profileIdRequest = -1; - songIdRequest = -1; - sessionId = ""; + // Save promise on page so the transition handler can find it. + $(this).data('promise', promise); - playerComunication.reset(); - - if (window.localStorage) { - window.localStorage.setItem("VocaluxeSessionKey", ""); - } - $.mobile.changePage("#login", { transition: "slidefade" }); -} - -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); + init(); + } - $("#popupVideo").on({ - popupbeforeposition: function () { - var size = scale(popupVideoWidth, popupVideoHeight, 15, 1), - w = size.width, - h = size.height; + function SessionHandler() { + this.ownProfileId = -1; + this.sessionId = ""; + this.serverBaseAddress = ""; - $("#popupVideo iframe") - .attr("width", w) - .attr("height", h); - }, - popupafterclose: function () { - $("#popupVideo iframe") - .attr("width", 0) - .attr("height", 0) - .attr("src", ""); - } - }); -}; + this.logout = function () { + this.ownProfileId = -1; + + this.sessionId = ""; + + pageHandler.reset(); + playerComunication.reset(); -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(); -} - -function PlayerComunication() { - var playerComunicationToServer = []; - var playerComunicationFromServerHandler = {}; - var defaultHeartbeatIntervall = 5000; - var heartbeatIntervalls = []; - var heartbeatIntervallId; - - var init = function () { - startHeartbeat(); - }; - - var checkPlayerMessages = function () { - if (ownProfileId == -1 - && profileIdRequest == -1 - && ($.mobile.activePage.attr("id") == "displayProfile" - || $.mobile.activePage.attr("id") == "login" - || $.mobile.activePage.attr("id") == "discover")) { - return; - } - - request({ - url: "playerComunication", - type: "POST", - dataType: "json", - contentType: "application/json", - data: JSON.stringify(playerComunicationToServer) - }, "noOverlay").done(function (result) { - if (result.length > 0) { - handlePlayerComunicationFromServer(result); + if (window.localStorage) { + window.localStorage.setItem("VocaluxeSessionKey", ""); } - }).fail(function (result) { - if (result.status == 403 || result.status == 0) { - logout(); - } - }); + $.mobile.changePage("#login", { transition: "slidefade" }); + }; + } - if (playerComunicationToServer.length > 0) { - setTimeout(checkPlayerMessages, 50); - } - - playerComunicationToServer = []; - }; - - var handlePlayerComunicationFromServer = function (items) { - for (var i = 0; i < items.length; i++) { - if (items[i].ProfileId == ownProfileId && playerComunicationFromServerHandler[items[i].Type]) { - if (new Date() - new Date(parseInt("\/Date(1234656000000)\/".match(/[0-9]+/)[0])) <= 0) { - var deserializedData = JSON.parse(items[i].Data); - for (var j = 0; j < playerComunicationFromServerHandler[items[i].Type]; j++) { - playerComunicationFromServerHandler[items[i].Type][j](deserializedData); - } - } - } - } - }; - - var startHeartbeat = function () { - var interv = defaultHeartbeatIntervall; - for (var i = 0; i < heartbeatIntervalls.length; i++) { - if (interv > heartbeatIntervalls[i] && heartbeatIntervalls[i] >= 50) { - interv = heartbeatIntervalls[i]; - } - } - - if (interv == defaultHeartbeatIntervall && heartbeatIntervalls.length != 0) { - heartbeatIntervalls = []; - } - - clearInterval(heartbeatIntervallId); - heartbeatIntervallId = setInterval(checkPlayerMessages, interv); - }; - - var sendPlayerComunicationToServer = function (packet) { - playerComunicationToServer.push(packet); - }; - - this.registerPlayerComunicationFromServerHandler = function (type, handler) { - if (!playerComunicationFromServerHandler[type]) { - playerComunicationFromServerHandler[type] = []; - } - playerComunicationFromServerHandler[type].push(handler); - }; - - this.sendDataToServer = function (data, type) { - sendPlayerComunicationToServer({ - "ProfileId": ownProfileId, - "ValidTill": "\/Date(" + (((new Date())).getTime() + 60000) + ")\/", - "Type": type, - "Data": JSON.stringify(data) - }); - }; - - //mim 50ms - this.requestIntervall = function (newIntervall) { - heartbeatIntervalls.push(newIntervall); - }; - - this.removeIntervall = function (oldIntervall) { - var index = heartbeatIntervalls.indexOf(oldIntervall); - if (index > -1) { - heartbeatIntervalls.splice(oldIntervall, 1); - } - }; - - this.reset = function () { - playerComunicationToServer = []; - playerComunicationFromServerHandler = {}; - heartbeatIntervalls = []; - }; - - this.EPlayerComunicationType = { - "RegisterSubscription": 0, - "UnregisterSubscription": 1 - }; - - init(); -} \ No newline at end of file + initMain(); +})(); \ No newline at end of file From 6a1b3567f4580b2f8757f6f9a15cbcdc75226675 Mon Sep 17 00:00:00 2001 From: lukeIam Date: Sun, 2 Mar 2014 12:46:23 +0100 Subject: [PATCH 06/22] Fix: removed a ; --- Vocaluxe/Website/js/main.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Vocaluxe/Website/js/main.js b/Vocaluxe/Website/js/main.js index 9f960bd1..127a41cd 100644 --- a/Vocaluxe/Website/js/main.js +++ b/Vocaluxe/Website/js/main.js @@ -309,8 +309,7 @@ 'height': h - (ifrPadding + ifrBorder) }; } - - ; + $("#popupVideo").find("a").click(function () { $("#popupVideo").popup("close"); $("#popupVideo").popup("close"); //Sometimes twice?? From ee7690228fa3d53f9de2fa413d74febd2301ba7c Mon Sep 17 00:00:00 2001 From: lukeIam Date: Sun, 9 Nov 2014 11:47:46 +0100 Subject: [PATCH 07/22] Fixed mixed tabs and spaces --- Vocaluxe/Website/js/main.js | 54 ++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/Vocaluxe/Website/js/main.js b/Vocaluxe/Website/js/main.js index 58c706c5..c6a856bd 100644 --- a/Vocaluxe/Website/js/main.js +++ b/Vocaluxe/Website/js/main.js @@ -1355,10 +1355,10 @@ this.ownProfileId = -1; this.sessionId = ""; this.serverBaseAddress = ""; - - var init = function(){ - initHeartbeat(); - } + + var init = function() { + initHeartbeat(); + }; this.logout = function () { this.ownProfileId = -1; @@ -1372,30 +1372,30 @@ } $.mobile.changePage("#login", { transition: "slidefade" }); }; - - - var checkSession = function() { - 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) { - this.logout(); - } - }).fail(function (result) { - this.logout(); - }); - }; + + + var checkSession = function() { + 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) { + this.logout(); + } + }).fail(function (result) { + this.logout(); + }); + }; - var initHeartbeat = function() { - setInterval(checkSession, 20000); - }; - - init(); + var initHeartbeat = function() { + setInterval(checkSession, 20000); + }; + + init(); } initMain(); From 5e67d9d4db7d36dd6bd5bd4958cf3ca54c2be6cd Mon Sep 17 00:00:00 2001 From: lukeIam Date: Sun, 9 Nov 2014 11:50:59 +0100 Subject: [PATCH 08/22] Fixed mixed tabs and spaces 2 --- Vocaluxe/Website/js/main.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Vocaluxe/Website/js/main.js b/Vocaluxe/Website/js/main.js index c6a856bd..7d02e068 100644 --- a/Vocaluxe/Website/js/main.js +++ b/Vocaluxe/Website/js/main.js @@ -1,4 +1,6 @@ -(function () { +/// +/// +(function () { var imageLoader; var externalServices; var translator; From 9773aa31d869ed36c8f2580b25d616d61581afb4 Mon Sep 17 00:00:00 2001 From: lukeIam Date: Sun, 9 Nov 2014 21:29:15 +0100 Subject: [PATCH 09/22] Reactivated and modified text field for keyboard --- ServerLib/CServer.cs | 1 + ServerLib/CWebservice.cs | 17 ++++++ ServerLib/DataStructs.cs | 1 + ServerLib/ICWebservice.cs | 5 ++ Vocaluxe/Base/Server/CVocaluxeServer.cs | 26 +++++++++ Vocaluxe/Website/index.html | 4 +- Vocaluxe/Website/js/main.js | 74 +++++++++++++------------ 7 files changed, 91 insertions(+), 37 deletions(-) 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 97a8962c..7aaeb4e4 100644 --- a/ServerLib/CWebservice.cs +++ b/ServerLib/CWebservice.cs @@ -58,6 +58,23 @@ namespace ServerLib CServer.SendKeyEvent(key); } + public void SendKeyStringEvent(string keyString) + { + 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); + } + #region profile public int GetOwnProfileId() { diff --git a/ServerLib/DataStructs.cs b/ServerLib/DataStructs.cs index 4d4bbed7..4ca7a0b7 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); #region profile public delegate SProfileData GetProfileDataDelegate(int profileId, bool isReadonly); diff --git a/ServerLib/ICWebservice.cs b/ServerLib/ICWebservice.cs index 0305e418..e4eeb0c3 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}")] + void SendKeyStringEvent(string keyString); + #region profile [OperationContract, WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json, diff --git a/Vocaluxe/Base/Server/CVocaluxeServer.cs b/Vocaluxe/Base/Server/CVocaluxeServer.cs index e0afa162..2b58c726 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.ServerPort, CConfig.ServerEncryption == EOffOn.TR_CONFIG_ON); CServer.SendKeyEvent = _SendKeyEvent; + CServer.SendKeyStringEvent = _sendKeyStringEvent; CServer.GetProfileData = _GetProfileData; CServer.SendProfileData = _SendProfileData; CServer.GetProfileList = _GetProfileList; @@ -186,6 +187,31 @@ namespace Vocaluxe.Base.Server return result; } + private static bool _sendKeyStringEvent(string keyString) + { + bool result = false; + + foreach (var key in keyString.ToCharArray()) + { + Controller.AddKeyEvent(new SKeyEvent(ESender.Keyboard, false, Char.IsUpper(key), false, false, key, _ParseKeys(key))); + result = true; + } + + return result; + } + + private static Keys _ParseKeys(char keyText) + { + Keys key; + + if (!Enum.TryParse(keyText.ToString(), true, out key)) + { + key = Keys.None; + } + + return key; + } + #region profile private static SProfileData _GetProfileData(int profileId, bool isReadonly) { diff --git a/Vocaluxe/Website/index.html b/Vocaluxe/Website/index.html index 0501220f..dbe2b538 100644 --- a/Vocaluxe/Website/index.html +++ b/Vocaluxe/Website/index.html @@ -301,10 +301,10 @@ P
    - +
    diff --git a/Vocaluxe/Website/js/main.js b/Vocaluxe/Website/js/main.js index 7d02e068..96cab4b9 100644 --- a/Vocaluxe/Website/js/main.js +++ b/Vocaluxe/Website/js/main.js @@ -26,11 +26,11 @@ function preStart() { translator.translationLoaded.done(function () { translator.translate(); - + sessionHandler = new SessionHandler(); imageLoader = new ImageLoader(); externalServices = new ExternalServices(); - pageHandler = new PageHandler(); + pageHandler = new PageHandler(); pageHandler.init(); }); @@ -154,7 +154,7 @@ } }; } - + function ExternalServices() { var popupVideoHeight = 390; var popupVideoWidth = 640; @@ -190,7 +190,7 @@ 'height': h - (ifrPadding + ifrBorder) }; } - + $("#popupVideo").find("a").click(function () { $("#popupVideo").popup("close"); $("#popupVideo").popup("close"); //Sometimes twice?? @@ -316,9 +316,9 @@ }; this.reset = function () { - this.customSelectPlaylistSongCallback = null; - this.profileIdRequest = -1; - this.songIdRequest = -1; + this.customSelectPlaylistSongCallback = null; + this.profileIdRequest = -1; + this.songIdRequest = -1; }; var replaceTransitionHandler = function () { @@ -693,17 +693,21 @@ }); $('#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); + var text = $('#keyboardButtonKeys')[0].value; + + $('#keyboardButtonKeys')[0].value = ""; + if (text.length <= 0) { + return; } + + request({ + contentType: "application/json;charset=utf-8", + type: "GET", + url: "sendKeyStringEvent?keyString=" + text + }).fail(function () { + $('#keyboardButtonKeys')[0].value = text + $('#keyboardButtonKeys')[0].value; + }); + }); }; @@ -812,7 +816,7 @@ } }; - var handleDisplayProfileData = function(data) { + var handleDisplayProfileData = function (data) { $('#playerName').prop("value", data.PlayerName); imageLoader.addImage($('#playerAvatar')[0], data.Avatar, "img/profile.png"); @@ -829,19 +833,19 @@ $('#playerPassword').prop('disabled', false).prop("value", "***__oldPassword__***").parent().show(); $('#playerPasswordLabel').show(); - $('#playerAvatar').click(function() { + $('#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) { + && 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() { + }, function () { //Fail - do nothing }, { destinationType: navigator.camera.DestinationType.DATA_URL, @@ -854,11 +858,11 @@ } else { $(document.body).append('
    '); - $('#capture').change(function(eventData) { + $('#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) { + reader.onloadend = function (e) { $('#playerAvatar').prop("src", e.target.result); $('#playerAvatar').data("changed", true); $('#captureContainer').remove(); @@ -1358,25 +1362,25 @@ this.sessionId = ""; this.serverBaseAddress = ""; - var init = function() { + var init = function () { initHeartbeat(); }; this.logout = function () { this.ownProfileId = -1; - + this.sessionId = ""; - - pageHandler.reset(); + + pageHandler.reset(); if (window.localStorage) { window.localStorage.setItem("VocaluxeSessionKey", ""); } $.mobile.changePage("#login", { transition: "slidefade" }); }; - - - var checkSession = function() { + + + var checkSession = function () { if (ownProfileId == -1 && profileIdRequest == -1 && ($.mobile.activePage.attr("id") == "displayProfile" || $.mobile.activePage.attr("id") == "login" || $.mobile.activePage.attr("id") == "discover")) { @@ -1393,10 +1397,10 @@ }); }; - var initHeartbeat = function() { + var initHeartbeat = function () { setInterval(checkSession, 20000); }; - + init(); } From 53153774b7680aa9929932057ef6b0e7b52848a4 Mon Sep 17 00:00:00 2001 From: lukeIam Date: Sun, 9 Nov 2014 21:54:52 +0100 Subject: [PATCH 10/22] Fixed: remote keyboard not working in input fields --- Vocaluxe/Base/Server/CVocaluxeServer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Vocaluxe/Base/Server/CVocaluxeServer.cs b/Vocaluxe/Base/Server/CVocaluxeServer.cs index 2b58c726..f2b22b45 100644 --- a/Vocaluxe/Base/Server/CVocaluxeServer.cs +++ b/Vocaluxe/Base/Server/CVocaluxeServer.cs @@ -193,7 +193,7 @@ namespace Vocaluxe.Base.Server foreach (var key in keyString.ToCharArray()) { - Controller.AddKeyEvent(new SKeyEvent(ESender.Keyboard, false, Char.IsUpper(key), false, false, key, _ParseKeys(key))); + Controller.AddKeyEvent(new SKeyEvent(ESender.Keyboard, false, Char.IsUpper(key), false, true, key, _ParseKeys(key))); result = true; } From c001fd934241e0cc49a0dd9d786ceea6e755dec7 Mon Sep 17 00:00:00 2001 From: lukeIam Date: Tue, 11 Nov 2014 16:43:09 +0100 Subject: [PATCH 11/22] Added BuildWinHowTo --- HowToBuildWin | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 HowToBuildWin diff --git a/HowToBuildWin b/HowToBuildWin new file mode 100644 index 00000000..c49e2c11 --- /dev/null +++ b/HowToBuildWin @@ -0,0 +1,28 @@ +# Build Vocaluxe - HowTo (Windows) + +1. Navigate to the right repository: usually [Vocaluxe Main](https://github.com/Vocaluxe/Vocaluxe) +2. Navigate to the right branch: usually [develop](https://github.com/Vocaluxe/Vocaluxe/tree/develop) (The main branch of Vocaluxe) +3. Copy the `URL` of the correspondending git file +4. Make sure git ist installed [git-scm](http://git-scm.com/) +5. Open a git bash (there should be a link in the start menu) +6. Navigate to the folder where git should greate the Vocaluxe project folder +``` +cd [PathToYourFolder] +``` +7. Clone the repository (could take some time...) +``` +git clone [theCopiedGitUrl] +``` +8. Now you should find a Folder `Vocaluxe` in the given directory -> navigate into it +9. Make sure [Visual Studio 2012/2013(?)](http://www.visualstudio.com/downloads/download-visual-studio-vs#d-express-windows-desktop) ist installed +10. Open the file `Vocaluxe.sln` with Visual Studio +11. Configure the build target to `ReleaseWin` and `x86` or `x64` (if you don not know which one is right -> select `x86`) +12. Build the projects by clicking +`"Build"->"Build solution"` or just press `Control`+`Shit`+`B` +13. Check if your build was successfull +14. YOUR build should have appeared here: +``` +[PathToYourFolder]\Vocaluxe\Output +``` +15. Run `Vocaluxe.exe` or copy the whole folder to a location of your choise +16. Have fun! From 2ba0c8df4f16bd29b273855e4de5611b1ef1ebcd Mon Sep 17 00:00:00 2001 From: lukeIam Date: Tue, 11 Nov 2014 16:46:54 +0100 Subject: [PATCH 12/22] Add extension to HowToBuildWin --- HowToBuildWin => HowToBuildWin.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename HowToBuildWin => HowToBuildWin.md (100%) diff --git a/HowToBuildWin b/HowToBuildWin.md similarity index 100% rename from HowToBuildWin rename to HowToBuildWin.md From 3b15c3e19b9497dc281f3f5fef44a9dcff8f7c79 Mon Sep 17 00:00:00 2001 From: lukeIam Date: Tue, 11 Nov 2014 16:55:54 +0100 Subject: [PATCH 13/22] Add images to HowToBuildWin.md --- HowToBuildWin.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/HowToBuildWin.md b/HowToBuildWin.md index c49e2c11..b325dab3 100644 --- a/HowToBuildWin.md +++ b/HowToBuildWin.md @@ -2,7 +2,11 @@ 1. Navigate to the right repository: usually [Vocaluxe Main](https://github.com/Vocaluxe/Vocaluxe) 2. 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) + 3. Copy the `URL` of the correspondending git file +![url](https://cloud.githubusercontent.com/assets/5115160/4995708/bc5af234-69c2-11e4-91d1-112972f35f01.PNG) + 4. Make sure git ist installed [git-scm](http://git-scm.com/) 5. Open a git bash (there should be a link in the start menu) 6. Navigate to the folder where git should greate the Vocaluxe project folder @@ -13,16 +17,22 @@ cd [PathToYourFolder] ``` git clone [theCopiedGitUrl] ``` +![clone](https://cloud.githubusercontent.com/assets/5115160/4995707/bc5aa6da-69c2-11e4-95cb-71ac7b0c3fc8.png) + 8. Now you should find a Folder `Vocaluxe` in the given directory -> navigate into it 9. Make sure [Visual Studio 2012/2013(?)](http://www.visualstudio.com/downloads/download-visual-studio-vs#d-express-windows-desktop) ist installed 10. Open the file `Vocaluxe.sln` with Visual Studio 11. Configure the build target to `ReleaseWin` and `x86` or `x64` (if you don not know which one is right -> select `x86`) 12. Build the projects by clicking `"Build"->"Build solution"` or just press `Control`+`Shit`+`B` +![build](https://cloud.githubusercontent.com/assets/5115160/4995709/bc5b3474-69c2-11e4-9d9b-b49f8a3b315d.png) + 13. Check if your build was successfull +![buildsuccess](https://cloud.githubusercontent.com/assets/5115160/4995710/bc5b4fe0-69c2-11e4-8b0f-4acaeffbc568.png) + 14. YOUR build should have appeared here: ``` [PathToYourFolder]\Vocaluxe\Output ``` 15. Run `Vocaluxe.exe` or copy the whole folder to a location of your choise -16. Have fun! +16. Have fun! From b59416b57572306afee032e557ebd85a5782bd57 Mon Sep 17 00:00:00 2001 From: lukeIam Date: Tue, 11 Nov 2014 17:03:21 +0100 Subject: [PATCH 14/22] Layout HowToBuildWin.md --- HowToBuildWin.md | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/HowToBuildWin.md b/HowToBuildWin.md index b325dab3..7cefaf94 100644 --- a/HowToBuildWin.md +++ b/HowToBuildWin.md @@ -2,37 +2,40 @@ 1. Navigate to the right repository: usually [Vocaluxe Main](https://github.com/Vocaluxe/Vocaluxe) 2. 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) + + ![branch](https://cloud.githubusercontent.com/assets/5115160/4995706/bc5aa536-69c2-11e4-8534-b64573624a33.PNG) 3. Copy the `URL` of the correspondending git file -![url](https://cloud.githubusercontent.com/assets/5115160/4995708/bc5af234-69c2-11e4-91d1-112972f35f01.PNG) + + ![url](https://cloud.githubusercontent.com/assets/5115160/4995708/bc5af234-69c2-11e4-91d1-112972f35f01.PNG) 4. Make sure git ist installed [git-scm](http://git-scm.com/) 5. Open a git bash (there should be a link in the start menu) 6. Navigate to the folder where git should greate the Vocaluxe project folder -``` -cd [PathToYourFolder] -``` + ``` + cd [PathToYourFolder] + ``` 7. Clone the repository (could take some time...) -``` -git clone [theCopiedGitUrl] -``` -![clone](https://cloud.githubusercontent.com/assets/5115160/4995707/bc5aa6da-69c2-11e4-95cb-71ac7b0c3fc8.png) + ``` + git clone [theCopiedGitUrl] + ``` + ![clone](https://cloud.githubusercontent.com/assets/5115160/4995707/bc5aa6da-69c2-11e4-95cb-71ac7b0c3fc8.png) 8. Now you should find a Folder `Vocaluxe` in the given directory -> navigate into it 9. Make sure [Visual Studio 2012/2013(?)](http://www.visualstudio.com/downloads/download-visual-studio-vs#d-express-windows-desktop) ist installed 10. Open the file `Vocaluxe.sln` with Visual Studio 11. Configure the build target to `ReleaseWin` and `x86` or `x64` (if you don not know which one is right -> select `x86`) -12. Build the projects by clicking -`"Build"->"Build solution"` or just press `Control`+`Shit`+`B` -![build](https://cloud.githubusercontent.com/assets/5115160/4995709/bc5b3474-69c2-11e4-9d9b-b49f8a3b315d.png) +12. Build the projects by clicking `"Build"->"Build solution"` or just press `Control`+`Shit`+`B` + + ![build](https://cloud.githubusercontent.com/assets/5115160/4995709/bc5b3474-69c2-11e4-9d9b-b49f8a3b315d.png) 13. Check if your build was successfull -![buildsuccess](https://cloud.githubusercontent.com/assets/5115160/4995710/bc5b4fe0-69c2-11e4-8b0f-4acaeffbc568.png) + + ![buildsuccess](https://cloud.githubusercontent.com/assets/5115160/4995710/bc5b4fe0-69c2-11e4-8b0f-4acaeffbc568.png) 14. YOUR build should have appeared here: -``` -[PathToYourFolder]\Vocaluxe\Output -``` + ``` + [PathToYourFolder]\Vocaluxe\Output + ``` 15. Run `Vocaluxe.exe` or copy the whole folder to a location of your choise 16. Have fun! From 2a3dceea716e28eb40463af8a3fea9b511ea1ebb Mon Sep 17 00:00:00 2001 From: lukeIam Date: Tue, 11 Nov 2014 17:08:27 +0100 Subject: [PATCH 15/22] Fixed typos in HowToBuildWin.md --- HowToBuildWin.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/HowToBuildWin.md b/HowToBuildWin.md index 7cefaf94..541dbaf2 100644 --- a/HowToBuildWin.md +++ b/HowToBuildWin.md @@ -5,13 +5,13 @@ ![branch](https://cloud.githubusercontent.com/assets/5115160/4995706/bc5aa536-69c2-11e4-8534-b64573624a33.PNG) -3. Copy the `URL` of the correspondending git file +3. Copy the `URL` of the corresponding git file ![url](https://cloud.githubusercontent.com/assets/5115160/4995708/bc5af234-69c2-11e4-91d1-112972f35f01.PNG) 4. Make sure git ist installed [git-scm](http://git-scm.com/) 5. Open a git bash (there should be a link in the start menu) -6. Navigate to the folder where git should greate the Vocaluxe project folder +6. Navigate to the folder where git should create the Vocaluxe project folder ``` cd [PathToYourFolder] ``` @@ -29,7 +29,7 @@ ![build](https://cloud.githubusercontent.com/assets/5115160/4995709/bc5b3474-69c2-11e4-9d9b-b49f8a3b315d.png) -13. Check if your build was successfull +13. Check if your build was successful ![buildsuccess](https://cloud.githubusercontent.com/assets/5115160/4995710/bc5b4fe0-69c2-11e4-8b0f-4acaeffbc568.png) @@ -37,5 +37,5 @@ ``` [PathToYourFolder]\Vocaluxe\Output ``` -15. Run `Vocaluxe.exe` or copy the whole folder to a location of your choise +15. Run `Vocaluxe.exe` or copy the whole folder to a location of your choice 16. Have fun! From f3aebd2619e8e24710f81a4788a68af7701820af Mon Sep 17 00:00:00 2001 From: lukeIam Date: Tue, 11 Nov 2014 18:43:01 +0100 Subject: [PATCH 16/22] Fixed typos in HowToBuildWin.md 2 rest will follow.. --- HowToBuildWin.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/HowToBuildWin.md b/HowToBuildWin.md index 541dbaf2..a400fe7a 100644 --- a/HowToBuildWin.md +++ b/HowToBuildWin.md @@ -9,7 +9,7 @@ ![url](https://cloud.githubusercontent.com/assets/5115160/4995708/bc5af234-69c2-11e4-91d1-112972f35f01.PNG) -4. Make sure git ist installed [git-scm](http://git-scm.com/) +4. Make sure git is installed [git-scm](http://git-scm.com/) 5. Open a git bash (there should be a link in the start menu) 6. Navigate to the folder where git should create the Vocaluxe project folder ``` @@ -22,10 +22,10 @@ ![clone](https://cloud.githubusercontent.com/assets/5115160/4995707/bc5aa6da-69c2-11e4-95cb-71ac7b0c3fc8.png) 8. Now you should find a Folder `Vocaluxe` in the given directory -> navigate into it -9. Make sure [Visual Studio 2012/2013(?)](http://www.visualstudio.com/downloads/download-visual-studio-vs#d-express-windows-desktop) ist installed +9. Make sure [Visual Studio 2012/2013(?)](http://www.visualstudio.com/downloads/download-visual-studio-vs#d-express-windows-desktop) is installed 10. Open the file `Vocaluxe.sln` with Visual Studio -11. Configure the build target to `ReleaseWin` and `x86` or `x64` (if you don not know which one is right -> select `x86`) -12. Build the projects by clicking `"Build"->"Build solution"` or just press `Control`+`Shit`+`B` +11. Configure the build target to `ReleaseWin` and `x86` or `x64` (if unsure -> select `x86`) +12. 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) From a93f2ac4480aeca29712fc3e09c0bc7464684647 Mon Sep 17 00:00:00 2001 From: lukeIam Date: Tue, 11 Nov 2014 19:33:58 +0100 Subject: [PATCH 17/22] Added VS13 git client posiblity --- HowToBuildWin.md | 65 ++++++++++++++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 24 deletions(-) diff --git a/HowToBuildWin.md b/HowToBuildWin.md index a400fe7a..95285b79 100644 --- a/HowToBuildWin.md +++ b/HowToBuildWin.md @@ -1,41 +1,58 @@ # Build Vocaluxe - HowTo (Windows) -1. Navigate to the right repository: usually [Vocaluxe Main](https://github.com/Vocaluxe/Vocaluxe) -2. Navigate to the right branch: usually [develop](https://github.com/Vocaluxe/Vocaluxe/tree/develop) (The main branch of Vocaluxe) +* 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) -3. Copy the `URL` of the corresponding git file +* Copy the `URL` of the corresponding git file ![url](https://cloud.githubusercontent.com/assets/5115160/4995708/bc5af234-69c2-11e4-91d1-112972f35f01.PNG) -4. Make sure git is installed [git-scm](http://git-scm.com/) -5. Open a git bash (there should be a link in the start menu) -6. Navigate to the folder where git should create the Vocaluxe project folder - ``` - cd [PathToYourFolder] - ``` -7. Clone the repository (could take some time...) - ``` - git clone [theCopiedGitUrl] - ``` - ![clone](https://cloud.githubusercontent.com/assets/5115160/4995707/bc5aa6da-69c2-11e4-95cb-71ac7b0c3fc8.png) +* Make sure [Visual Studio 2012/2013(?)](http://www.visualstudio.com/downloads/download-visual-studio-vs#d-express-windows-desktop) is installed -8. Now you should find a Folder `Vocaluxe` in the given directory -> navigate into it -9. Make sure [Visual Studio 2012/2013(?)](http://www.visualstudio.com/downloads/download-visual-studio-vs#d-express-windows-desktop) is installed -10. Open the file `Vocaluxe.sln` with Visual Studio -11. Configure the build target to `ReleaseWin` and `x86` or `x64` (if unsure -> select `x86`) -12. Build the projects by clicking `"Build"->"Build solution"` or just press `Control`+`Shift`+`B` +* 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) -13. Check if your build was successful - +* Check if your build was successful ![buildsuccess](https://cloud.githubusercontent.com/assets/5115160/4995710/bc5b4fe0-69c2-11e4-8b0f-4acaeffbc568.png) -14. YOUR build should have appeared here: +* YOUR build should have appeared here: ``` [PathToYourFolder]\Vocaluxe\Output ``` -15. Run `Vocaluxe.exe` or copy the whole folder to a location of your choice -16. Have fun! +* Run `Vocaluxe.exe` or copy the whole folder to a location of your choice +* Have fun! From e10de6ca0ef877b4ae3e540b150ca8a9d90dd4d0 Mon Sep 17 00:00:00 2001 From: lukeIam Date: Tue, 11 Nov 2014 22:05:43 +0100 Subject: [PATCH 18/22] Added backspace and Alt, Shift, Ctrl to the remote keyboard --- ServerLib/CWebservice.cs | 4 +- ServerLib/DataStructs.cs | 2 +- ServerLib/ICWebservice.cs | 4 +- Vocaluxe/Base/Server/CVocaluxeServer.cs | 53 +++++++++++++++---------- Vocaluxe/Website/index.html | 19 ++++++++- Vocaluxe/Website/js/main.js | 21 +++++++++- Vocaluxe/Website/locales/de.json | 7 +++- Vocaluxe/Website/locales/en.json | 7 +++- 8 files changed, 86 insertions(+), 31 deletions(-) diff --git a/ServerLib/CWebservice.cs b/ServerLib/CWebservice.cs index 7aaeb4e4..dbd27e1f 100644 --- a/ServerLib/CWebservice.cs +++ b/ServerLib/CWebservice.cs @@ -58,7 +58,7 @@ namespace ServerLib CServer.SendKeyEvent(key); } - public void SendKeyStringEvent(string keyString) + public void SendKeyStringEvent(string keyString, bool isShiftPressed = false, bool isAltPressed = false, bool isCtrlPressed = false) { if (!_CheckRight(EUserRights.UseKeyboard)) return; @@ -72,7 +72,7 @@ namespace ServerLib } } else - CServer.SendKeyStringEvent(keyString); + CServer.SendKeyStringEvent(keyString, isShiftPressed, isAltPressed, isCtrlPressed); } #region profile diff --git a/ServerLib/DataStructs.cs b/ServerLib/DataStructs.cs index 4ca7a0b7..5b87398b 100644 --- a/ServerLib/DataStructs.cs +++ b/ServerLib/DataStructs.cs @@ -26,7 +26,7 @@ using System.Text.RegularExpressions; namespace ServerLib { public delegate bool SendKeyEventDelegate(string key); - public delegate bool SendKeyStringEventDelegate(string keyString); + 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 e4eeb0c3..acb24799 100644 --- a/ServerLib/ICWebservice.cs +++ b/ServerLib/ICWebservice.cs @@ -32,8 +32,8 @@ namespace ServerLib [OperationContract, WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json, - UriTemplate = "/sendKeyStringEvent?keyString={keyString}")] - void SendKeyStringEvent(string keyString); + 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", diff --git a/Vocaluxe/Base/Server/CVocaluxeServer.cs b/Vocaluxe/Base/Server/CVocaluxeServer.cs index f2b22b45..d882881e 100644 --- a/Vocaluxe/Base/Server/CVocaluxeServer.cs +++ b/Vocaluxe/Base/Server/CVocaluxeServer.cs @@ -126,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)); @@ -158,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; } } @@ -187,13 +186,17 @@ namespace Vocaluxe.Base.Server return result; } - private static bool _sendKeyStringEvent(string keyString) + 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, false, Char.IsUpper(key), false, true, key, _ParseKeys(key))); + Controller.AddKeyEvent(new SKeyEvent(ESender.Keyboard, isAltPressed, + Char.IsUpper(key) || isShiftPressed, + isCtrlPressed, true, + isShiftPressed?Char.ToUpper(key) :key, + _ParseKeys(key))); result = true; } @@ -206,7 +209,15 @@ namespace Vocaluxe.Base.Server if (!Enum.TryParse(keyText.ToString(), true, out key)) { - key = Keys.None; + switch (keyText) + { + case ' ': + key = Keys.Space; + break; + default: + key = Keys.None; + break; + } } return key; diff --git a/Vocaluxe/Website/index.html b/Vocaluxe/Website/index.html index dbe2b538..fdb14c43 100644 --- a/Vocaluxe/Website/index.html +++ b/Vocaluxe/Website/index.html @@ -297,8 +297,25 @@
    +
    + +
    +
    +
    + + + + + + +
    +
    - P +
    diff --git a/Vocaluxe/Website/js/main.js b/Vocaluxe/Website/js/main.js index 96cab4b9..f7a69d9e 100644 --- a/Vocaluxe/Website/js/main.js +++ b/Vocaluxe/Website/js/main.js @@ -686,12 +686,13 @@ }); }); - $('#keyboardButtonP').click(function () { + $('#keyboardButtonBackspace').click(function () { request({ - url: "sendKeyEvent?key=p" + url: "sendKeyEvent?key=backspace" }); }); + $('#keyboardButtonKeys').keyup(function (e) { var text = $('#keyboardButtonKeys')[0].value; @@ -700,10 +701,26 @@ return; } + + /* 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; }); diff --git a/Vocaluxe/Website/locales/de.json b/Vocaluxe/Website/locales/de.json index ddf85d71..7fc413c3 100644 --- a/Vocaluxe/Website/locales/de.json +++ b/Vocaluxe/Website/locales/de.json @@ -76,5 +76,10 @@ "discoverConnectServerAddress": "Serveradresse:", "discoverConnectButton": "Verbinden", "Checking...": "Prüfen...", - "timeout": "Zeitüberschreitung" + "timeout": "Zeitüberschreitung", + "keyboardButtonShift": "Umschalt", + "keyboardButtonAlt": "Alt", + "keyboardButtonCtrl": "Steuerung", + "keyboardButtonFunct": "Funktion", + "keyboardButtonBackspace": "Rücktaste" } \ No newline at end of file diff --git a/Vocaluxe/Website/locales/en.json b/Vocaluxe/Website/locales/en.json index c6b28fd0..4a7da86a 100644 --- a/Vocaluxe/Website/locales/en.json +++ b/Vocaluxe/Website/locales/en.json @@ -76,5 +76,10 @@ "discoverConnectServerAddress": "Serveraddress:", "discoverConnectButton": "Connect", "Checking...": "Checking...", - "timeout": "Timeout" + "timeout": "Timeout", + "keyboardButtonShift": "Shift", + "keyboardButtonAlt": "Alt", + "keyboardButtonCtrl": "Control", + "keyboardButtonFunct": "Function", + "keyboardButtonBackspace": "Backspace" } \ No newline at end of file From 207f1a02f0355bca7b2a674ff24b0fd29f223b17 Mon Sep 17 00:00:00 2001 From: Stephan Sundermann Date: Wed, 12 Nov 2014 00:11:26 +0100 Subject: [PATCH 19/22] Include git hash in version --- Vocaluxe/Base/CSettings.cs | 6 +++++- Vocaluxe/Properties/AssemblyInfo.cs | 3 ++- Vocaluxe/Vocaluxe.csproj | 6 +++++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/Vocaluxe/Base/CSettings.cs b/Vocaluxe/Base/CSettings.cs index b419e7b1..e55a9208 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 @@ -180,8 +181,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/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 b8276467..62c49204 100644 --- a/Vocaluxe/Vocaluxe.csproj +++ b/Vocaluxe/Vocaluxe.csproj @@ -509,7 +509,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'" diff --git a/Vocaluxe/Website/js/main.js b/Vocaluxe/Website/js/main.js index 1719d00f..814d253b 100644 --- a/Vocaluxe/Website/js/main.js +++ b/Vocaluxe/Website/js/main.js @@ -26,11 +26,11 @@ function preStart() { translator.translationLoaded.done(function () { translator.translate(); - + sessionHandler = new SessionHandler(); imageLoader = new ImageLoader(); externalServices = new ExternalServices(); - pageHandler = new PageHandler(); + pageHandler = new PageHandler(); pageHandler.init(); }); @@ -154,7 +154,7 @@ } }; } - + function ExternalServices() { var popupVideoHeight = 390; var popupVideoWidth = 640; @@ -190,7 +190,7 @@ 'height': h - (ifrPadding + ifrBorder) }; } - + $("#popupVideo").find("a").click(function () { $("#popupVideo").popup("close"); $("#popupVideo").popup("close"); //Sometimes twice?? @@ -641,7 +641,6 @@ var KeyboardPageHandler = function () { var init = function () { - initKeyboardPageHandler(); }; @@ -694,26 +693,45 @@ }); }); + $("#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; - $('#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"); - }*/ + /* 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", @@ -726,8 +744,7 @@ }).fail(function () { $('#keyboardButtonKeys')[0].value = text + $('#keyboardButtonKeys')[0].value; }); - - }); + } }; init(); @@ -835,7 +852,7 @@ } }; - var handleDisplayProfileData = function(data) { + var handleDisplayProfileData = function (data) { $('#playerName').prop("value", data.PlayerName); imageLoader.addImage($('#playerAvatar')[0], data.Avatar, "img/profile.png"); @@ -852,19 +869,19 @@ $('#playerPassword').prop('disabled', false).prop("value", "***__oldPassword__***").parent().show(); $('#playerPasswordLabel').show(); - $('#playerAvatar').click(function() { + $('#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) { + && 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() { + }, function () { //Fail - do nothing }, { destinationType: navigator.camera.DestinationType.DATA_URL, @@ -877,11 +894,11 @@ } else { $(document.body).append('
    '); - $('#capture').change(function(eventData) { + $('#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) { + reader.onloadend = function (e) { $('#playerAvatar').prop("src", e.target.result); $('#playerAvatar').data("changed", true); $('#captureContainer').remove(); @@ -1383,25 +1400,25 @@ var t = this; - var init = function() { + var init = function () { initHeartbeat(); }; this.logout = function () { t.ownProfileId = -1; - + t.sessionId = ""; - - pageHandler.reset(); + + pageHandler.reset(); if (window.localStorage) { window.localStorage.setItem("VocaluxeSessionKey", ""); } $.mobile.changePage("#login", { transition: "slidefade" }); }; - - - var checkSession = function() { + + + 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")) { @@ -1418,10 +1435,10 @@ }); }; - var initHeartbeat = function() { + var initHeartbeat = function () { setInterval(checkSession, 20000); }; - + init(); } diff --git a/Vocaluxe/Website/locales/de.json b/Vocaluxe/Website/locales/de.json index ab74b88b..d9f2420a 100644 --- a/Vocaluxe/Website/locales/de.json +++ b/Vocaluxe/Website/locales/de.json @@ -80,5 +80,7 @@ "keyboardButtonShift": "Umschalt", "keyboardButtonAlt": "Alt", "keyboardButtonCtrl": "Steuerung", - "keyboardButtonBackspace": "Rücktaste" + "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 89c517d6..308d01c1 100644 --- a/Vocaluxe/Website/locales/en.json +++ b/Vocaluxe/Website/locales/en.json @@ -80,5 +80,7 @@ "keyboardButtonShift": "Shift", "keyboardButtonAlt": "Alt", "keyboardButtonCtrl": "Control", - "keyboardButtonBackspace": "Backspace" + "keyboardButtonBackspace": "Backspace", + "keyboardAutoSend": "Auto send keys", + "keyboardButtonSend": "Send" } \ No newline at end of file