// ==UserScript==
// @name CAI Swipe Navigator
// @namespace Massgen swipenav
// @version 0.2
// @description Displays swipes separately and navigates to them on the main form with one click
// @author GPT ft. anon
// @match https://beta.character.ai/chat*
// @grant none
// @license MIT
// @downloadURL none
// ==/UserScript==
//Change if you want the old style
const oldStyle = false;
//Change if you want the swipe number shown on the actual swipes
const showCircle = false;
// Create display box for showing the message text
var displayBox = document.createElement('div');
displayBox.setAttribute('id', 'message-display-swipenav');
displayBox.setAttribute('class', 'messages-list-swipenav');
displayBox.setAttribute('style', 'display: none;');
document.body.appendChild(displayBox);
var count = 0;
var prevClass = '';
function clearDisplayAndCount() {
count = 0;
document.getElementById('message-display-swipenav').innerHTML = '';
}
// Function to retrieve and display the associated message
function getMessage(event) {
var number = parseInt(event.target.getAttribute('data-slide-number'));
var messageDiv = document.querySelectorAll('div[class="msg char-msg"]')[number - 1].cloneNode(true); // clone the message element
var annotationContainer = messageDiv.querySelector('.annotation-buttons-container'); // find the annotation buttons container
if(annotationContainer !== null) {
annotationContainer.remove(); // remove the annotation buttons container
}
var message = messageDiv.innerHTML;
// Check if message is already in the message display box before adding it
var messageExists = false;
var messageDivs = document.querySelectorAll('.hywmsg.non-deleted');
for (var i = 0; i < messageDivs.length; i++) {
if (messageDivs[i].innerHTML.includes(message)) {
messageExists = true;
break;
}
}
if (!messageExists) {
var newMessage = document.createElement('div');
newMessage.innerHTML = '
Swipe ' + (number) + ':
' + message;
newMessage.setAttribute('class', 'hywmsg non-deleted');
document.getElementById('message-display').appendChild(newMessage);
}
}
// Function to check for new messages and add them to the display box
function checkNewMessages() {
var messages = document.querySelectorAll('.swiper-slide div[class="msg char-msg"]');
for (var i = 0; i < messages.length; i++) {
if (!messages[i].hasAttribute('data-isnew')) {
var messageContent = messages[i].innerHTML;
// Exclude messages with typing-dot typing-dot-light-bg class
if (!messageContent.includes("typing-dot typing-dot-light-bg")) {
messages[i].setAttribute('data-isnew', 'true');
var message = messageContent.trim();
var messageNumber = i + 1;
var currentClass = messages[i].parentNode.parentNode.parentNode.parentNode.getAttribute('class');
if (prevClass !== '' && prevClass !== currentClass) {
count = 0;
document.getElementById('message-display-swipenav').innerHTML = '';
}
prevClass = currentClass;
count++;
var existingMessage = document.querySelector('.hywmsg.non-deleted-swipenav[data-slide-number="' + messageNumber + '"]');
if (existingMessage) {
existingMessage.remove();
}
var newMessage = document.createElement('div');
newMessage.setAttribute('data-slide-number', messageNumber);
if (oldStyle) {
newMessage.innerHTML = 'Swipe ' + messageNumber + ':
' + message;
} else {
newMessage.innerHTML = ' ' + messageNumber + '
' + message;
}
newMessage.setAttribute('class', 'hywmsg non-deleted-swipenav');
// Remove empty divs
newMessage.innerHTML = newMessage.innerHTML.replace(/<\/div>/g, '');
document.getElementById('message-display-swipenav').appendChild(newMessage);
newMessage.addEventListener('click', getMessage);
}
}
}
// Remove the annotation buttons from newly added messages
var newMessages = document.querySelectorAll('.hywmsg.non-deleted-swipenav');
for (var i = 0; i < newMessages.length; i++) {
var annotationButtons = newMessages[i].querySelectorAll('.annotation-buttons-container.col.mb-3');
for (var j = 0; j < annotationButtons.length; j++) {
annotationButtons[j].remove();
}
}
// Function to navigate to the corresponding slide when slide-number-msg element is clicked
function navigateToSlide(event) {
var slideNumber = parseInt(event.target.getAttribute('data-slide-number'));
var activeSlideNumber = parseInt(document.querySelector('.swiper-slide.swiper-slide-active').getAttribute('data-slide-number'));
var slideDifference = slideNumber - activeSlideNumber;
if (slideDifference < 0) {
for (var i = 0; i < Math.abs(slideDifference); i++) {
document.querySelector('.swiper-button-prev').click();
}
} else if (slideDifference > 0) {
for (var i = 0; i < slideDifference; i++) {
document.querySelector('.swiper-button-next').click();
}
}
}
// Add slide navigation function to slide-number-msg elements
var slideNumberMsgs = document.querySelectorAll('.slide-number-msg-swipenav');
for (var i = 0; i < slideNumberMsgs.length; i++) {
slideNumberMsgs[i].setAttribute('data-slide-number', i + 1);
slideNumberMsgs[i].addEventListener('click', navigateToSlide);
}
// Add numbered navigation to swiper-slide elements
var swiperSlides = document.getElementsByClassName('swiper-slide');
for (var i = 0; i < swiperSlides.length; i++) {
swiperSlides[i].setAttribute('data-slide-number', i + 1);
// Check if slide already has a slide-number element before adding one
if (!swiperSlides[i].querySelector('.slide-number-swipenav')) {
var messageNumber = document.createElement('div');
messageNumber.innerHTML = i + 1;
messageNumber.setAttribute('class', 'slide-number-swipenav');
messageNumber.setAttribute('data-slide-number', i + 1);
messageNumber.onclick = function() {
var slideNumber = this.getAttribute('data-slide-number');
var activeSlideNumber = document.querySelector('.swiper-slide.swiper-slide-active').getAttribute('data-slide-number');
var slideDifference = slideNumber - activeSlideNumber;
if (slideDifference < 0) {
for (var i = 0; i < Math.abs(slideDifference); i++) {
document.querySelector('.swiper-button-prev').click();
}
} else if (slideDifference > 0) {
for (var i = 0; i < slideDifference; i++) {
document.querySelector('.swiper-button-next').click();
}
}
};
swiperSlides[i].appendChild(messageNumber);
}
}
// Add class to currently active swiper-slide element
var activeSlide = document.querySelector('.swiper-slide.swiper-slide-active');
activeSlide.classList.add('active-slide-swipenav');
}
// Create a MutationObserver to detect changes in the DOM
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (mutation.type === 'childList' && mutation.addedNodes.length > 0) {
if (mutation.target.classList.contains('infinite-scroll-component')) {
clearDisplayAndCount();
}
}
});
});
// Observe changes in the body element and its child nodes
observer.observe(document.body, {
childList: true,
subtree: true
});
// Call the checkNewMessages function every second
setInterval(checkNewMessages, 1000);
// Style HTML
let styleHTML = document.createElement('style');
if (oldStyle) {
styleHTML.innerHTML = `
html {
height: 100%;
overflow: hidden;
width: 100%;
}
body {
height: 100%;
overflow-x: hidden;
overflow-y: auto;
width: 100%;
}
.messages-list-swipenav {
padding: 4px 4px 3px 4px;
margin: 40px 4px 0 0;
border: 3px solid gray;
position: absolute;
top: 0;
right: 0;
width: 20%;
height: 80%;
overflow-y: scroll;
border-radius: 0 0 8px 8px;
z-index: 100;
resize: both;
direction: rtl;
min-width: 100px;
min-height: 100px;
}
.display-btn-swipenav {
cursor: pointer;
user-select: none;
border: 3px solid gray;
padding: 4px;
margin: 4px;
width: 20%;
position: absolute;
top: 0;
right: 0;
background-color: lightsteelblue;
color: black;
font-weight: bold;
text-align: center;
z-index: 100;
}
.messages-list-swipenav div {
margin-top: 5px;
padding: 8px;
background-color: lightpink;
direction: ltr;
}
.hywmsg-swipenav {
border-radius: 8px;
}
.hywmsg.non-deleted-swipenav {
background-color: aquamarine;
}
.hywmsg.hidden-swipenav {
display: none;
}
.screen-btn-swipenav {
cursor: pointer;
user-select: none;
border: 3px solid gray;
padding: 4px;
margin: 4px;
width: 20%;
position: absolute;
top: 0;
right: 0;
background-color: lightsteelblue;
color: black;
font-weight: bold;
text-align: center;
z-index: 100;
}
.swiper-slide {
position: relative;
}
.slide-number-swipenav {
position: absolute;
bottom: 0;
left: 0;
background-color: white;
border-radius: 50%;
height: 20px;
width: 20px;
text-align: center;
line-height: 20px;
font-weight: bold;
${!showCircle ? "display: none;" : ""}
}
.active-slide-swipenav .slide-number-swipenav {
background-color: lightsteelblue;
color: black;
}
.slide-number-msg-swipenav {
display: inline-block;
margin-right: 5px;
font-weight: bold;
cursor: pointer;
}
`;
} else {
styleHTML.innerHTML = `
html {
height: 100%;
overflow: hidden;
width: 100%;
}
body {
height: 100%;
overflow-x: hidden;
overflow-y: auto;
width: 100%;
font-family: Arial, Helvetica, sans-serif;
}
.messages-list-swipenav {
padding: 4px;
margin: 40px 4px 0 0;
border: 1px solid #D9D9D9;
position: absolute;
top: 0;
right: 0;
width: 20%;
height: 80%;
overflow-y: scroll;
border-radius: 8px;
z-index: 100;
resize: both;
direction: rtl;
min-width: 100px;
min-height: 100px;
background-color: #FFFFFF;
}
.display-btn-swipenav {
cursor: pointer;
user-select: none;
border: 1px solid #D9D9D9;
padding: 4px;
margin: 4px;
width: 20%;
position: absolute;
top: 0;
right: 0;
background-color: #FFFFFF;
color: #5A5A5A;
font-weight: bold;
text-align: center;
z-index: 100;
border-radius: 4px;
}
.messages-list-swipenav div {
margin-top: 5px;
padding: 8px;
background-color: #F2F2F2;
direction: ltr;
border-radius: 4px;
}
.hywmsg-swipenav {
border-radius: 4px;
}
.hywmsg.non-deleted-swipenav {
background-color: silver;
}
.hywmsg.hidden-swipenav {
display: none;
}
.screen-btn-swipenav {
cursor: pointer;
user-select: none;
border: 1px solid #D9D9D9;
padding: 4px;
margin: 4px;
width: 20%;
position: absolute;
top: 0;
right: 0;
background-color: #FFFFFF;
color: #5A5A5A;
font-weight: bold;
text-align: center;
z-index: 100;
border-radius: 4px;
}
.swiper-slide {
position: relative;
}
.slide-number-swipenav {
position: absolute;
bottom: 0;
left: 0;
background-color: white;
border-radius: 50%;
height: 20px;
width: 20px;
text-align: center;
line-height: 20px;
font-weight: bold;
border: 1px solid #D9D9D9;
${!showCircle ? "display: none;" : ""}
}
.active-slide-swipenav .slide-number-swipenav {
background-color: #5A5A5A;
color: #FFFFFF;
}
.slide-number-msg-swipenav {
background-color: silver !important;
display: inline;
margin-right: 5px;
font-weight: bold;
cursor: pointer;
color: black;
}
`;
}
document.body.appendChild(styleHTML);
// Button HTML
let buttonHTML = document.createElement('div');
buttonHTML.innerHTML = "Swipenav";
buttonHTML.onclick = function () {
let msgList = document.getElementsByClassName('messages-list-swipenav')[0]
if (msgList.style.display === "none") {
msgList.style.display = "block";
} else {
msgList.style.display = "none";
}
};
buttonHTML.classList.add("display-btn-swipenav");
document.body.appendChild(buttonHTML);
window.addEventListener('load', function() {
if (!isFirefox()) {
init();
}
});
function isFirefox() {
return navigator.userAgent.includes('Firefox');
}
if (isFirefox()) {
init();
}
function init() {
const displayBtn = {
default: document.querySelector('.display-btn'),
massgen: document.querySelector('.display-btn-swipenav'),
};
const messagesList = {
default: document.querySelector('.messages-list'),
massgen: document.querySelector('.messages-list-swipenav'),
};
const hideBtn = document.createElement('div');
let isHidden = false;
let currentMode = 'default';
function setMode(mode) {
if (mode === currentMode) {
return;
}
if (mode === 'default') {
if (displayBtn.default) displayBtn.default.style.display = 'block';
if (messagesList.default) messagesList.default.style.display = 'block';
if (displayBtn.massgen) displayBtn.massgen.style.display = 'none';
if (messagesList.massgen) messagesList.massgen.style.display = 'none';
hideBtn.innerHTML = 'Swipenav';
} else if (mode === 'massgen') {
if (displayBtn.default) displayBtn.default.style.display = 'none';
if (messagesList.default) messagesList.default.style.display = 'none';
if (displayBtn.massgen) displayBtn.massgen.style.display = 'block';
if (messagesList.massgen) messagesList.massgen.style.display = 'block';
hideBtn.innerHTML = 'HYW';
}
currentMode = mode;
}
hideBtn.innerHTML = 'Swipenav';
hideBtn.style.position = 'absolute';
hideBtn.style.top = '0px';
hideBtn.style.right = '386px';
hideBtn.style.cursor = 'pointer';
hideBtn.style.userSelect = 'none';
hideBtn.style.border = '3px solid grey';
hideBtn.style.padding = '4px';
hideBtn.style.margin = '4px';
hideBtn.style.backgroundColor = 'lightsteelblue';
hideBtn.style.color = 'white';
hideBtn.style.fontWeight = 'bold';
hideBtn.style.textAlign = 'center';
hideBtn.style.zIndex = '100';
hideBtn.id = 'hideBtn';
hideBtn.classList.add("hide-btn-swipenav");
hideBtn.onclick = function () {
if (isHidden) {
setMode('default');
hideBtn.style.backgroundColor = 'lightsteelblue';
hideBtn.style.border = '3px solid grey';
hideBtn.style.color = 'white';
isHidden = false;
} else {
setMode('massgen');
if(oldStyle) {
hideBtn.style.backgroundColor = 'lightsteelblue';
hideBtn.style.border = '3px solid grey';
hideBtn.style.color = 'white';
} else {
hideBtn.style.backgroundColor = '#FFFFFF';
hideBtn.style.border = '1px solid #D9D9D9';
hideBtn.style.color = '#5A5A5A';
}
isHidden = true;
}
};
if (displayBtn.massgen) displayBtn.massgen.style.display = 'none';
if (messagesList.massgen) messagesList.massgen.style.display = 'none';
hideBtn.style.display = 'block';
document.body.appendChild(hideBtn);
};;