{"id":253,"date":"2024-08-22T12:42:39","date_gmt":"2024-08-22T12:42:39","guid":{"rendered":"https:\/\/www.buddyupgo.com\/?page_id=253"},"modified":"2024-08-22T12:42:39","modified_gmt":"2024-08-22T12:42:39","slug":"messages","status":"publish","type":"page","link":"https:\/\/buddyupapi-staging.us35.cdn-alpha.com\/messages\/","title":{"rendered":"Messages"},"content":{"rendered":"<div class=\"buddyUpPjaxContainer\" data-buddyup-pjax-container=\"1\"><style>\/* Current user info, may remove... *\/\nbody {\n    background: var(--buddyup-background);\n}\n\n#chatSectionWrapper {\n    min-height: calc(var(--buddyup-mobile-usable-vh, 100dvh) - 230px);\n    display: grid;\n    grid-template-columns: minmax(250px, 320px) 1fr;\n    gap: .9rem;\n    align-items: stretch;\n}\n\n\/* Sidebar *\/\n#chatListSidebar {\n    width: 100%;\n    max-width: 100%;\n}\n\n#chatListSidebar > div {\n    padding: .9rem;\n    background: white;\n    border-radius: var(--border-radius);\n    box-shadow: 0 2px 10px -2px rgba(0,0,0,.05), 0 2px 15px -2px rgba(0,0,0,.05);\n    display: flex;\n    flex-direction: column;\n    min-height: 100%;\n}\n\n#chatListSidebar ul {\n    padding-top: 0;\n    max-height: calc(var(--buddyup-mobile-usable-vh, 100dvh) - 320px);\n    overflow-y: auto;\n}\n\n#chatListSidebar .messagesListSeparater {\n    display: block;\n    margin: .5rem 0;\n    padding: 0 .8rem;\n    font-size: .95rem;\n}\n\n\/* User cards in list *\/\n.userListCard {\n    align-items: center;\n    margin-bottom: .45rem;\n    gap: .7rem;\n    line-height: 1.2rem;\n    padding: .75rem .85rem;\n    border-radius: 12px;\n    border: 1px solid transparent;\n}\n\n.userListCard:not(#currentUserInfo):not(.placeholderUser) {\n    transition: background .2s;\n    cursor: pointer;\n}\n\n.userListCard:not(#currentUserInfo):not(.placeholderUser):hover {\n    background: rgba(0,0,0,.035);\n}\n\n.userListCard.active {\n    background: rgba(217, 63, 12, .08);\n    border-color: rgba(217, 63, 12, .22);\n}\n\n.userListCard > * {\n    overflow: hidden;\n}\n\n.userListCardImageWrapperWrapper {\n    --image-size: 50px;\n    width: var(--image-size);\n    max-width: var(--image-size);\n    min-width: var(--image-size);\n    height: var(--image-size);\n}\n\n.userListCardImageWrapper {\n    width: var(--image-size);\n    min-width: var(--image-size);\n    max-width: var(--image-size);\n    height: var(--image-size);\n}\n\n.userListCardName {\n    font-weight: bold;\n}\n\n.userListCardBlurb {\n    white-space: nowrap;\n    text-overflow: ellipsis;\n    overflow: hidden;\n    font-size: .9rem;\n    color: #888;\n    font-style: italic;\n}\n\n\/* Placeholder User *\/\n.placeholderUserImage {\n    border-radius: 500px;\n}\n\n.placeholderUser .userListCardName,\n.placeholderUser .userListCardBlurb {\n    border-radius: 3px;\n}\n\n.placeholderUser .userListCardName {\n    margin-bottom: .2rem;\n}\n\n\n\/* Chat Wrapper *\/\n.chatMessagesWrapper {\n    border-radius: 12px;\n    padding: .9rem;\n    background: #fff;\n    border: 1px solid rgba(0,0,0,.06);\n    display: flex;\n    flex-direction: column;\n    box-shadow: 0 2px 10px -2px rgba(0,0,0,.05), 0 2px 15px -2px rgba(0,0,0,.05);\n    min-height: 540px;\n    height: calc(var(--buddyup-mobile-usable-vh, 100dvh) - 260px);\n}\n\n#currentChat {\n    flex: 1;\n    overflow-y: auto;\n    min-height: 0;\n    margin: 0;\n    padding: .15rem .1rem .6rem;\n}\n\n\n\/* Chat Messages *\/\nli.placeholderMessage {\n    padding: 6px 0;\n    margin-bottom: 1rem !important;\n}\n\n.currentChat li:before {\n    content: '';\n    display: none;\n}\n\n.currentChat li {\n    margin: 0;\n}\n\n.currentChat .userMessageWrapper {\n    display: flex;\n    gap: 10px;\n    padding: 0;\n    margin-bottom: .5rem;\n}\n\n.currentChat .userMessageWrapper:not(:first-of-type).nextUser {\n    margin-top: 1.8rem;\n}\n\n.currentChat .userMessageWrapper .userMessage {\n    width: calc(100% - 40px);\n}\n\n.currentChat .userMessageWrapper .userMessage.currentUser {\n    text-align: right;\n}\n\n.currentChat .userMessageWrapper .userMessage span {\n    --message-border-radius: 12px;\n    display: inline-block;\n    border-radius: 0 var(--message-border-radius) var(--message-border-radius) var(--message-border-radius);\n    background: #f2f3f5;\n    color: #222;\n    padding: 8px 14px;\n    text-align: left;\n    white-space: pre-wrap;\n    overflow-wrap: anywhere;\n    word-break: break-word;\n    max-width: 100%;\n}\n\n.currentChat .userMessageWrapper .userMessage.currentUser span {\n    border-radius: var(--message-border-radius) 0 var(--message-border-radius) var(--message-border-radius);\n    background: var(--primary-color);\n    color: #fff;\n}\n\n.currentChat .userMessageWrapper .userMessageImage {\n    width: 36px;\n    height: 36px;\n}\n\n\/* New Message Input *\/\n#chatNewMessageWrapper {\n    height: auto;\n    margin-top: auto;\n    border-top: 1px solid rgba(0,0,0,.08);\n    padding-top: .7rem;\n}\n\n#chatNewMessageForm {\n    gap: 0;\n    margin: 0;\n    background: #f3f3f3;\n    border: 1px solid rgba(0,0,0,.08);\n    border-radius: 12px;\n    align-items: flex-end;\n    padding-right: 6px;\n}\n\n#chatNewMessageForm > * {\n    margin: 0;\n}\n\n#chatNewMessageInput {\n    width: 100%;\n    background-color: transparent;\n    border: none;\n    min-height: 42px;\n    padding: .65rem .7rem;\n}\n\n#chatNewMessageSubmit {\n    border-radius: 999px;\n    border: none !important;\n    background: var(--primary-color) !important;\n    color: #fff !important;\n    transition: opacity .2s;\n    margin: 0;\n    height: 34px;\n    width: 34px;\n    min-width: 34px;\n    display: inline-flex;\n    align-items: center;\n    justify-content: center;\n    padding: 0;\n}\n\n#chatNewMessageSubmit:disabled {\n    background: #d5d5d5 !important;\n    color: #777 !important;\n}\n\n@media (min-width: 551px){\n    #chatNewMessageWrapper .buddyUpSubscriptionCTAWrapper {\n        display: flex;\n        justify-content: space-between;\n        align-items: center;\n        padding: .5rem .6rem .5rem 1rem;\n    }\n\n    #chatNewMessageWrapper .buddyUpSubscriptionCTAWrapper p {\n        padding: 0;\n    }\n}\n\n@media (max-width: 766px){\n    #chatSectionWrapper {\n        display: flex;\n        flex-direction: column;\n        min-height: auto;\n    }\n\n    #chatListSidebar {\n        width: 100%;\n        max-width: 100%;\n    }\n\n    #chatListSidebar #userChatList {\n        display: flex;\n        white-space: nowrap;\n        overflow-x: auto;\n        overflow-y: hidden;\n        max-height: none;\n        gap: .5rem;\n    }\n\n    #chatListSidebar #userChatList .userListCard {\n        display: inline-flex;\n        flex-direction: column;\n        justify-content: center;\n        overflow: hidden;\n        width: 145px;\n        min-width: 145px;\n        margin-bottom: 0;\n    }\n\n    #chatListSidebar #userChatList .userListCard .userListCardName {\n        overflow: hidden;\n        text-overflow: ellipsis;\n        text-align: center;\n    }\n\n    #chatListSidebar #userChatList .userListCard .userListCardBlurb {\n        display: none;\n    }\n\n    #chatListSidebar #userChatList .userListCard .userListCardImageWrapperWrapper {\n        margin: 0 auto .5rem;\n    }\n\n    .chatMessagesWrapper {\n        min-height: 480px;\n        height: calc(var(--buddyup-mobile-usable-vh, 100dvh) - 300px);\n        padding: .75rem;\n    }\n\n    #chatNewMessageWrapper {\n        flex-grow: 0;\n    }\n}\n<\/style>\n<section id=\"chatSectionWrapper\" class=\"flexWrapper buddyUpContainer\">\n    <aside id=\"chatListSidebar\" class=\"hidden\">\n        <div>\n            <strong class=\"messagesListSeparater\">All Chats<\/strong>\n            <ul id=\"userChatList\"> <div class=\"flexWrapper userListCard placeholderUser\">\n        <div class=\"userListCardImageWrapperWrapper placeholderUserImage buddyUpPlaceholderLoading\"><div class=\"userListCardImageWrapper\"><\/div><\/div>\n        <div>\n            <div class=\"userListCardName buddyUpPlaceholderLoading\">&nbsp;<\/div>\n            <div class=\"userListCardBlurb buddyUpPlaceholderLoading\">&nbsp;<\/div>\n        <\/div>\n    <\/div> <\/ul>\n            <div class=\"buddyUpBackButtonWrapper\"><a href=\"https:\/\/buddyupapi-staging.us35.cdn-alpha.com\/account\/\"><i class=\"fa fa-solid fa-arrow-left\"><\/i> Back to Profile<\/a><\/div>        <\/div>\n    <\/aside>\n    <div id=\"currentChatWrapper\" class=\"chatMessagesWrapper hidden\">\n        <ul id=\"currentChat\" class=\"currentChat hidden\"><\/ul>\n        <div id=\"chatNewMessageWrapper\" class=\"hidden\">\n            <form id=\"chatNewMessageForm\" class=\"flexWrapper\">\n                <input type=\"text\" id=\"chatNewMessageInput\" disabled=\"disabled\" \/>\n                <button type=\"submit\" id=\"chatNewMessageSubmit\" class=\"buddyUpButton1\" aria-label=\"Send Message\" title=\"Send Message\" disabled=\"disabled\"><i class=\"fa-solid fa-paper-plane\"><\/i><\/button>\n            <\/form>\n        <\/div>\n    <\/div>\n<\/section><script>\/***\n * Initial Messaging Setup\n *\/\nconst currentUser = BUDDYUP.getCurrentUser();\nlet currentUserSubscription = 0;\nlet currentUserCanMessage = true;\nlet activeChatId = null;\nlet activeChatRequestId = 0;\nlet chatListRequestId = 0;\n\nif (currentUser && currentUser.id){\n    document.getElementById('chatListSidebar').classList.remove('hidden');\n    document.querySelector('.chatMessagesWrapper').classList.remove('hidden');\n    \n    \/\/ Initial get users with chats\n    async function getInitialUserInfo(){\n        const localRequestId = ++chatListRequestId;\n        try {\n            const messagesUsersResponse = await BUDDYUP.apiRequest('messages-get-chatlist');\n            if (localRequestId !== chatListRequestId) return;\n            document.getElementById('userChatList').innerHTML = '';\n            if (messagesUsersResponse.status === 'success' && messagesUsersResponse.list.length > 0){\n                currentUserSubscription = messagesUsersResponse.subscription;\n                updateChatList(messagesUsersResponse.list);\n            } else { \/\/ No users found...\n                document.getElementById('userChatList').insertAdjacentHTML('beforeend', `<div style=\"padding: .5rem .8rem .8rem\">No messages found. Find a buddy and message them!<\/div>`);\n            }\n        } catch (e) {\n            if (localRequestId !== chatListRequestId) return;\n            document.getElementById('userChatList').innerHTML = `<div style=\"padding: .5rem .8rem .8rem\">Unable to load chats. Please try again.<\/div>`;\n        }\n    }\n    getInitialUserInfo();\n} else { \/\/ User isn't logged in\n    let errMessageContent = `<p>Please log in to your account to view your messages and reply to your buddies or register to start chatting!<\/p>\n        <a href=\"${buddyUpVariables.login_link}\" class=\"buddyUpButton1\">Log in<\/a>\n        <a href=\"${buddyUpVariables.register_link}\" class=\"buddyUpButton1\" style=\"margin-left: .5rem;\">Sign Up<\/a>`;\n    let errMessage = BUDDYUP.errorPage('Please log in', errMessageContent);\n    document.getElementById('chatSectionWrapper').innerHTML = errMessage;\n}\n\n\n\/***\n * Update chat List\n *\/\nfunction updateChatList(usersList){\n    if (typeof usersList === 'object' || typeof usersList === 'array'){\n        var el = '';\n\n        for (x in usersList){\n            let user = usersList[x];\n            if (typeof user === 'object'){\n                el += `<div class=\"flexWrapper userListCard\" data-id=\"${user.chat_id}\" data-chat-id=\"${user.chat_id}\" tabindex=\"0\" aria-label=\"View chat with ${user.full_name}\">\n    <div class=\"userListCardImageWrapperWrapper\"><div class=\"userListCardImageWrapper buddyUpImageCircle\"><img decoding=\"async\" src=\"${BUDDYUP.profileImageSrc(user.profile_image)}\" alt=\"Image of ${user.full_name}\" onerror=\"BUDDYUP.onErrProfileImage(this)\"><\/div><\/div>\n    <div><div class=\"userListCardName\">${user.full_name}<\/div><div class=\"userListCardBlurb\">${user.last_message_blurb}<\/div><\/div>\n<\/div>`;\n            }\n        }\n\n        document.getElementById('userChatList').insertAdjacentHTML('beforeend', el);\n\n        \/\/ Auto-select top\/most recent chat to reduce extra clicks TODO: add sorting option for user to set chat sorting behaviors\n        if (!activeChatId) {\n            const firstChat = document.querySelector('#userChatList [data-id]');\n            if (firstChat) {\n                activeChatId = firstChat.getAttribute('data-id');\n                firstChat.classList.add('active');\n                document.getElementById('chatNewMessageInput').removeAttribute('disabled');\n                updateChat(activeChatId, true);\n            }\n        }\n    }\n}\n\n\n\/***\n * Get messages and add to chat\n*\/\nasync function updateChat(chatID, initialClearChat){\n    const localRequestId = ++activeChatRequestId;\n    const messagesResponse = await BUDDYUP.getChatMessages(chatID, 'id'); \/\/ Get messages by user ID\n    if (localRequestId !== activeChatRequestId || chatID !== activeChatId) return;\n    currentUserSubscription = await BUDDYUP.getSubscriptionTier();\n    currentUserCanMessage = true;\n    try {\n        const limitsResp = await BUDDYUP.getUserLimits();\n        const limit = Number(limitsResp?.limits?.messaging?.daily_limit ?? 0);\n        const current = Number(limitsResp?.current?.messaging?.current_today ?? 0);\n        if (limit > 0 && current >= limit) currentUserCanMessage = false;\n    } catch (e) {}\n\n    if (messagesResponse.status === 'success'){\n        const chatWrapper = document.getElementById('currentChat');\n        if (initialClearChat === true){ chatWrapper.innerHTML = ''; } \/\/ If clear chat is set, clear the chat (used when clicking on a new user chat)\n        \n        if (!currentUserCanMessage){\n            document.getElementById('chatNewMessageWrapper').innerHTML = BUDDYUP.subscriptionCTA('You\u2019ve reached your daily message limit. Upgrade to send more.', 'small');\n        }\n        \n        document.getElementById('chatNewMessageWrapper').classList.remove('hidden');\n\n        document.getElementById('currentChat').classList.remove('hidden');\n        BUDDYUP.updateChat('#currentChat', messagesResponse.messages, messagesResponse.users);\n    } else {\n        let modalContent = messagesResponse.message && !messagesResponse.message.includes('critical error on this website') ? messagesResponse.message : 'An error occured getting your chat. Please try again.';\n        \n        BUDDYUP.openModal(modalContent, `An error occurred`, 'buddyUpErrModal');\n    }\n}\n\n\n\n\/***\n * Send Message\n *\/\nconst submitButton = document.getElementById('chatNewMessageSubmit');\nconst newMessageInput = document.getElementById('chatNewMessageInput');\nBUDDYUP.setGlobalHandler('messages.formSubmit', document.getElementById('chatNewMessageForm'), 'submit', e => {\n    e.preventDefault();\n    \n    const activeChat = document.querySelector('#userChatList [data-id].active'); \/\/ Check to see if a user chat is currently active\n    if (activeChat){\n        const currentUser = BUDDYUP.getCurrentUser(); \/\/ Get current user\n        var newMessage = {\n            id: 'new-message',\n            message: newMessageInput.value,\n            subscription: currentUserSubscription,\n            user_id: currentUser.id,\n            chat_id: activeChat.getAttribute('data-id'),\n            chat_type: 'chat',\n        };\n\n        BUDDYUP.updateChat('#currentChat', [newMessage], null);\n\n        if (currentUserCanMessage){\n            newMessageInput.value = '';\n        }\n        submitButton.setAttribute('disabled', 'disabled');\n    }\n});\n\nnewMessageInput.addEventListener('keyup', e => {\n    if (newMessageInput.value !== ''){\n        submitButton.removeAttribute('disabled');\n    } else {\n        submitButton.setAttribute('disabled', 'disabled');\n    }\n});\n\n\n\n\/***\n * Document Event Listeners\n *\/\nfunction selectUser(e){\n    \/***\n     * Select user\n     *\/\n    const userSelect = e.target.closest('#userChatList [data-id]:not(.active)'); \/\/ Event card class (not placeholders)\n    if (userSelect){\n        document.getElementById('chatNewMessageInput').removeAttribute('disabled'); \/\/ Make text input active\n        \/* Update user sidebar list *\/\n        const chatID = userSelect.getAttribute('data-id'); \/\/ Get user ID\n        activeChatId = chatID;\n        const activeUsers = document.querySelectorAll('#userChatList [data-id].active'); \/\/ Get list of previously active users\n        activeUsers.forEach(e => { e.classList.remove('active'); }); \/\/ Remove active class from previously active user\n        userSelect.classList.add('active'); \/\/ Set newly clicked user as active\n\n        \/* Add placeholder messages and only display if loading takes longer than half a second *\/\n        const placeholderEl = '<li class=\"placeholderMessage buddyUpPlaceholderLoading hidden\">&nbsp;<\/li>';\n        document.getElementById('currentChat').innerHTML = placeholderEl + placeholderEl; \/\/ Add placeholder messages\n        setTimeout(() => {\n            const placeholderEls = document.querySelectorAll('.placeholderMessage');\n            if (placeholderEls.length > 0){\n                placeholderEls.forEach(el => { el.classList.remove('hidden'); })\n            }\n        }, 500);\n\n        \/* Get chat and update the message list *\/\n        updateChat(chatID, true);\n    }\n}\n\nBUDDYUP.setGlobalHandler('messages.selectUser.click', document, 'click', e => {\n    selectUser(e);\n});\n\nBUDDYUP.setGlobalHandler('messages.selectUser.keyup', document, 'keyup', e => {\n    if (e.key === 'Enter'){\n        selectUser(e);\n    }\n});<\/script><\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"templates\/full-width-no-header.php","meta":{"footnotes":""},"class_list":["post-253","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/buddyupapi-staging.us35.cdn-alpha.com\/api\/wp\/v2\/pages\/253","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/buddyupapi-staging.us35.cdn-alpha.com\/api\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/buddyupapi-staging.us35.cdn-alpha.com\/api\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/buddyupapi-staging.us35.cdn-alpha.com\/api\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/buddyupapi-staging.us35.cdn-alpha.com\/api\/wp\/v2\/comments?post=253"}],"version-history":[{"count":0,"href":"https:\/\/buddyupapi-staging.us35.cdn-alpha.com\/api\/wp\/v2\/pages\/253\/revisions"}],"wp:attachment":[{"href":"https:\/\/buddyupapi-staging.us35.cdn-alpha.com\/api\/wp\/v2\/media?parent=253"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}