Skip to content

Commit

Permalink
Only enable save button when option changed
Browse files Browse the repository at this point in the history
  • Loading branch information
stevencrader committed Nov 6, 2023
1 parent 65c49b6 commit 4fab5db
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 16 deletions.
107 changes: 92 additions & 15 deletions src/pages/options/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { Message, Messages } from "../../types/messages"
import { defaultOptions, Options, Theme } from "../../types/option-types"
import { validateText } from "../../utils"

const saveButton = document.getElementById("save") as HTMLButtonElement
const sortOrderSelect = document.getElementById("sort-order") as HTMLSelectElement
const historyInput = document.getElementById("history") as HTMLInputElement
const themeSelect = document.getElementById("theme") as HTMLSelectElement
Expand All @@ -22,6 +23,19 @@ const importMutedWordsButton = document.getElementById("import-muted-words") as
const muteInChatCheckbox = document.getElementById("mute-in-chat") as HTMLInputElement
const muteInRantStatsCheckbox = document.getElementById("mute-in-rant-stats") as HTMLInputElement

// temporary options before saving
let tempOptions: Options = null

/**
* Set whether the save button should be active or not
* @param enabled enable or disable save button
*/
const setSaveButtonState = (enabled: boolean): void => {
const title = enabled ? "" : "No changes since last save"
saveButton.disabled = !enabled
saveButton.title = title
}

/**
* Toggle showing or hiding the sub-options section based on the check state
* @param checkbox The checkbox to check the state of
Expand Down Expand Up @@ -63,23 +77,17 @@ const setOptions = (options: Options): void => {
muteInChatCheckbox.checked = options.muteInChat
muteInRantStatsCheckbox.checked = options.muteInRantStats

updateUsage()
}
tempOptions = options

/**
* Set the options to the default values
*/
const setDefault = (): void => {
setOptions(defaultOptions)
updateUsage()
}

/**
* Save the option values from the HTML elements to storage
* Get all current option values
* @returns the options
*/
const saveOptions = (): void => {
const customMutedWords = validateText(customMutedWordsTextArea.value).split("\n")

const currentOptions: Options = {
const getCurrentOptions = (): Options => {
return {
sortOrder: sortOrderSelect.value,
historyDays: parseInt(historyInput.value, 10),
theme: themeSelect.value,
Expand All @@ -88,15 +96,66 @@ const saveOptions = (): void => {
showMutedUsers: showMutedUsersCheckbox.checked,
alternateColors: alternateColorsCheckbox.checked,
hideMutedWords: hideMutedWordsCheckbox.checked,
customMutedWords,
customMutedWords: validateText(customMutedWordsTextArea.value).split("\n"),
muteInChat: muteInChatCheckbox.checked,
muteInRantStats: muteInRantStatsCheckbox.checked,
}
customMutedWordsTextArea.value = customMutedWords.join("\n")
}

/**
* Check if 2 sets of Options match
* @param options1 option 1 values
* @param options2 option 2 values
* @returns options match
*/
const doOptionsMatch = (options1: Options, options2: Options): boolean => {
let match = true
Object.entries(options1).forEach((entry1) => {
const key = entry1[0]
const value1 = entry1[1]
const value2 = options2[key]
let valuesMatch = value1 === value2
if (key === "customMutedWords") {
const value1Array = value1 as Array<string>
value1Array.sort()
const value2Array = value2 as Array<string>
value2Array.sort()
valuesMatch = JSON.stringify(value1Array) === JSON.stringify(value2Array)
}
match = match && valuesMatch
})
return match
}

/**
* Handle element change event
*/
const optionChanged = (): void => {
const currentOptions = getCurrentOptions()
const optionsMatch = doOptionsMatch(currentOptions, tempOptions)
setSaveButtonState(!optionsMatch)
}

/**
* Set the options to the default values
*/
const setDefault = (): void => {
setOptions(defaultOptions)
setSaveButtonState(false)
}

/**
* Save the option values from the HTML elements to storage
*/
const saveOptions = (): void => {
const currentOptions = getCurrentOptions()
customMutedWordsTextArea.value = currentOptions.customMutedWords.join("\n")

updateOptions(currentOptions).then(() => {
const status = document.getElementById("save-status") as HTMLParagraphElement
tempOptions = currentOptions
status.textContent = "Options saved"
setSaveButtonState(false)
setTimeout(() => {
status.textContent = ""
}, 750)
Expand All @@ -116,6 +175,9 @@ const loadOptions = (): void => {
// run clean history at the beginning of each load
cleanHistory().then()

// disable save button until something changes
setSaveButtonState(false)

getOptions(defaultOptions).then((options) => {
setOptions(options)
})
Expand Down Expand Up @@ -185,7 +247,22 @@ chrome.runtime.onMessage.addListener((message: Message, _sender, sendResponse) =
registerTab()

document.addEventListener("DOMContentLoaded", loadOptions)
document.getElementById("save").addEventListener("click", saveOptions)
saveButton.addEventListener("click", saveOptions)
sortOrderSelect.addEventListener("change", optionChanged)
historyInput.addEventListener("change", optionChanged)
historyInput.addEventListener("input", optionChanged)
themeSelect.addEventListener("change", optionChanged)
openLocationCheckbox.addEventListener("change", optionChanged)
bytesUseSpan.addEventListener("change", optionChanged)
showDeletedChatsCheckbox.addEventListener("change", optionChanged)
showMutedUsersCheckbox.addEventListener("change", optionChanged)
alternateColorsCheckbox.addEventListener("change", optionChanged)
hideMutedWordsCheckbox.addEventListener("change", optionChanged)
customMutedWordsTextArea.addEventListener("change", optionChanged)
customMutedWordsTextArea.addEventListener("input", optionChanged)
importMutedWordsButton.addEventListener("change", optionChanged)
muteInChatCheckbox.addEventListener("change", optionChanged)
muteInRantStatsCheckbox.addEventListener("change", optionChanged)
document.getElementById("clear").addEventListener("click", clearOptions)
document.getElementById("open-rants").addEventListener("click", triggerOpenRantsPage)

Expand Down
13 changes: 12 additions & 1 deletion src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { consoleLog } from "./log"
import { CONSTS } from "./types/consts"

const PATTERN_LEADING_SPACE = /^[ \r\n]+/gs
const PATTERN_TRAILING_SPACE = /[ \r\n]+$/gs
const PATTERN_SPACE = /([\r\n] +| +[\r\n])/gs
const PATTERN_EMPTY_LINE = /\n{2,}/gs
const PATTERN_VALID_TEXT = /[^a-zA-Z0-9 `~!@#$%^:*\-_=+\r\n]/gs

/**
Expand All @@ -25,5 +30,11 @@ export const getVideoIdFromDiv = (): string => {
* @returns cleaned text
*/
export const validateText = (text: string): string => {
return text.replace(PATTERN_VALID_TEXT, "")
consoleLog("before", text)
let tempText = text.replace(PATTERN_SPACE, "\n")
tempText = tempText.replace(PATTERN_LEADING_SPACE, "")
tempText = tempText.replace(PATTERN_TRAILING_SPACE, "")
tempText = tempText.replace(PATTERN_EMPTY_LINE, "\n")
consoleLog("after", tempText)
return tempText.replace(PATTERN_VALID_TEXT, "")
}

0 comments on commit 4fab5db

Please sign in to comment.