sex!!!!!!!!!!!!!!!!

This commit is contained in:
Fijxu 2023-10-18 03:54:57 -03:00
parent bf93d8410c
commit f34ffe3df6
9 changed files with 116 additions and 124 deletions

View file

@ -2,7 +2,7 @@ package api
import ( import (
"math/rand" "math/rand"
"net/http" // "net/http"
"time" "time"
) )
@ -21,25 +21,25 @@ func init() {
// //
// Responses: // Responses:
// 200: string // 200: string
func (s *Server) writeOptOutCode(w http.ResponseWriter, r *http.Request) { // func (s *Server) writeOptOutCode(w http.ResponseWriter, r *http.Request) {
code := randomString(6) // code := randomString(6)
s.bot.OptoutCodes.Store(code, true) // s.bot.OptoutCodes.Store(code, true)
go func() { // go func() {
time.Sleep(time.Second * 60) // time.Sleep(time.Second * 60)
s.bot.OptoutCodes.Delete(code) // s.bot.OptoutCodes.Delete(code)
}() // }()
writeJSON(code, http.StatusOK, w, r) // writeJSON(code, http.StatusOK, w, r)
} // }
var letterRunes = []rune("abcdefghijklmnopqrstuvwxyz1234567890") // var letterRunes = []rune("abcdefghijklmnopqrstuvwxyz1234567890")
func randomString(n int) string { // func randomString(n int) string {
b := make([]rune, n) // b := make([]rune, n)
for i := range b { // for i := range b {
b[i] = letterRunes[rand.Intn(len(letterRunes))] // b[i] = letterRunes[rand.Intn(len(letterRunes))]
} // }
return string(b) // return string(b)
} // }

View file

@ -126,7 +126,7 @@ func (s *Server) route(w http.ResponseWriter, r *http.Request) {
if url == "/list" { if url == "/list" {
if s.cfg.IsOptedOut(query.Get("userid")) || s.cfg.IsOptedOut(query.Get("channelid")) { if s.cfg.IsOptedOut(query.Get("userid")) || s.cfg.IsOptedOut(query.Get("channelid")) {
http.Error(w, "User or channel has opted out", http.StatusForbidden) http.Error(w, "User or channel is a cuck", http.StatusForbidden)
return return
} }
@ -139,10 +139,10 @@ func (s *Server) route(w http.ResponseWriter, r *http.Request) {
return return
} }
if url == "/optout" && r.Method == http.MethodPost { // if url == "/optout" && r.Method == http.MethodPost {
s.writeOptOutCode(w, r) // s.writeOptOutCode(w, r)
return // return
} // }
if strings.HasPrefix(url, "/admin/channels") { if strings.HasPrefix(url, "/admin/channels") {
success := s.authenticateAdmin(w, r) success := s.authenticateAdmin(w, r)

View file

@ -1,13 +0,0 @@
{
"admins": ["gempir"],
"logsDirectory": "./logs",
"adminAPIKey": "noshot",
"username": "gempbot",
"oauth": "oauthtokenforchat",
"botVerified": true,
"clientID": "mytwitchclientid",
"clientSecret": "mysecret",
"logLevel": "info",
"channels": ["77829817", "11148817"],
"archive": true
}

0
web/dist/.gitkeep vendored
View file

View file

@ -11,9 +11,10 @@
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons" /> <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons" />
<style> <style>
:root { :root {
--bg: #0e0e10;
--bg-bright: #18181b; --bg: #111111;
--bg-brighter: #3d4146; --bg-bright: #11111120;
--bg-brighter: #3d414620;
--bg-dark: #121416; --bg-dark: #121416;
--theme: #00CC66; --theme: #00CC66;
--theme-bright: #00FF80; --theme-bright: #00FF80;
@ -25,9 +26,15 @@
} }
body { body {
background-image: linear-gradient(
to bottom,
rgba(11, 11, 11, 0.8),
rgba(11, 11, 11, 0.8)
),
url(https://zzls.xyz/assets/bgs/bgtile.gif);
margin: 0; margin: 0;
padding: 0; padding: 0;
background: var(--bg); /* background: var(--bg); */
font-family: Helvetica, Arial, sans-serif; font-family: Helvetica, Arial, sans-serif;
height: 100%; height: 100%;
width: 100%; width: 100%;

View file

@ -53,7 +53,7 @@ export function ContentLog({ year, month }: { year: string, month: string }) {
return <ContentLogContainer onMouseEnter={handleMouseEnter}> return <ContentLogContainer onMouseEnter={handleMouseEnter}>
<TextField <TextField
className="search" className="search"
label="Search" label="Search / Buscar"
inputRef={search} inputRef={search}
onChange={e => setSearchText(e.target.value)} onChange={e => setSearchText(e.target.value)}
size="small" size="small"

View file

@ -1,4 +1,4 @@
import { Button, TextField } from "@mui/material"; import { Button, TextField, colors } from "@mui/material";
import { Autocomplete } from '@mui/material'; import { Autocomplete } from '@mui/material';
import React, { FormEvent, useContext } from "react"; import React, { FormEvent, useContext } from "react";
import { useQueryClient } from "react-query"; import { useQueryClient } from "react-query";
@ -6,14 +6,14 @@ import styled from "styled-components";
import { useChannels } from "../hooks/useChannels"; import { useChannels } from "../hooks/useChannels";
import { store } from "../store"; import { store } from "../store";
import { Docs } from "./Docs"; import { Docs } from "./Docs";
import { Optout } from "./Optout"; // import { Optout } from "./Optout";
import { Settings } from "./Settings"; import { Settings } from "./Settings";
const FiltersContainer = styled.form` const FiltersContainer = styled.form`
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
padding: 15px; padding: 15px;
background: var(--bg-bright); // background: var(--bg-bright);
border-bottom-left-radius: 3px; border-bottom-left-radius: 3px;
border-bottom-right-radius: 3px; border-bottom-right-radius: 3px;
margin: 0 auto; margin: 0 auto;
@ -57,17 +57,16 @@ export function Filters() {
<Autocomplete <Autocomplete
id="autocomplete-channels" id="autocomplete-channels"
options={channels.map(channel => channel.name)} options={channels.map(channel => channel.name)}
style={{ width: 225 }} style={{ width: 300 }}
defaultValue={state.currentChannel} defaultValue={state.currentChannel}
getOptionLabel={(channel: string) => channel} getOptionLabel={(channel: string) => channel}
clearOnBlur={false} clearOnBlur={false}
renderInput={(params) => <TextField {...params} name="channel" label="channel or id:123" variant="filled" autoFocus={state.currentChannel === null} />} renderInput={(params) => <TextField {...params} name="channel" label="channel or id:123" variant="filled" autoFocus={state.currentChannel === null} />}
/> />
<TextField error={state.error} name="username" label="username or id:123" variant="filled" autoComplete="off" defaultValue={state.currentUsername} autoFocus={state.currentChannel !== null && state.currentUsername === null} /> <TextField error={state.error} name="username" label="username or id:123" variant="filled" autoComplete="off" defaultValue={state.currentUsername} autoFocus={state.currentChannel !== null && state.currentUsername === null} />
<Button variant="contained" color="primary" size="large" type="submit">load</Button> <Button variant="contained" color="secondary" size="large" type="submit">load</Button>
<Settings /> <Settings />
<Docs /> <Docs />
<Optout />
</FiltersContainer> </FiltersContainer>
</FiltersWrapper> </FiltersWrapper>
} }

View file

@ -1,88 +1,88 @@
import { IconButton, Button } from "@mui/material"; // import { IconButton, Button } from "@mui/material";
import { useContext, useState } from "react"; // import { useContext, useState } from "react";
import styled from "styled-components"; // import styled from "styled-components";
import { store } from "../store"; // import { store } from "../store";
import CancelIcon from '@mui/icons-material/Cancel'; // import CancelIcon from '@mui/icons-material/Cancel';
const OptoutWrapper = styled.div` // const OptoutWrapper = styled.div`
`; // `;
export function Optout() { // export function Optout() {
const { state, setShowOptout } = useContext(store); // const { state, setShowOptout } = useContext(store);
const handleClick = () => { // const handleClick = () => {
setShowOptout(!state.showOptout); // setShowOptout(!state.showOptout);
} // }
return <OptoutWrapper> // return <OptoutWrapper>
<IconButton aria-controls="docs" aria-haspopup="true" onClick={handleClick} size="small" color={state.showOptout ? "primary" : "default"}> // <IconButton aria-controls="docs" aria-haspopup="true" onClick={handleClick} size="small" color={state.showOptout ? "primary" : "default"}>
<CancelIcon /> // <CancelIcon />
</IconButton> // </IconButton>
</OptoutWrapper>; // </OptoutWrapper>;
} // }
const OptoutPanelWrapper = styled.div` // const OptoutPanelWrapper = styled.div`
background: var(--bg-bright); // background: var(--bg-bright);
color: var(--text); // color: var(--text);
margin: 3rem; // margin: 3rem;
font-size: 1.5rem; // font-size: 1.5rem;
padding: 2rem; // padding: 2rem;
code { // code {
background: var(--bg); // background: var(--bg);
padding: 1rem; // padding: 1rem;
border-radius: 3px; // border-radius: 3px;
} // }
.generator { // .generator {
margin-top: 2rem; // margin-top: 2rem;
display: flex; // display: flex;
gap: 1rem; // gap: 1rem;
align-items: center; // align-items: center;
input { // input {
background: var(--bg); // background: var(--bg);
border: none; // border: none;
color: white; // color: white;
padding: 0.6rem; // padding: 0.6rem;
font-size: 1.5rem; // font-size: 1.5rem;
text-align: center; // text-align: center;
border-radius: 3px; // border-radius: 3px;
} // }
} // }
.small { // .small {
font-size: 0.8rem; // font-size: 0.8rem;
font-family: monospace; // font-family: monospace;
} // }
`; // `;
export function OptoutPanel() { // export function OptoutPanel() {
const { state } = useContext(store); // const { state } = useContext(store);
const [code, setCode] = useState(""); // const [code, setCode] = useState("");
const generateCode = () => { // const generateCode = () => {
fetch(state.apiBaseUrl + "/optout", { method: "POST" }).then(res => res.json()).then(setCode).catch(console.error); // fetch(state.apiBaseUrl + "/optout", { method: "POST" }).then(res => res.json()).then(setCode).catch(console.error);
}; // };
return <OptoutPanelWrapper> // return <OptoutPanelWrapper>
<p> // <p>
You can opt out from being logged. This will also disable access to your previously logged data.<br /> // You can opt out from being logged. This will also disable access to your previously logged data.<br />
This applies to all chats of that justlog instance.<br /> // This applies to all chats of that justlog instance.<br />
Opting out is permanent, there is no reverse action. So think twice if you want to opt out. // Opting out is permanent, there is no reverse action. So think twice if you want to opt out.
</p> // </p>
<p> // <p>
If you still want to optout generate a token here and paste the command into a logged chat.<br /> // If you still want to optout generate a token here and paste the command into a logged chat.<br />
You will receive a confirmation message from the bot "@username, opted you out". // You will receive a confirmation message from the bot "@username, opted you out".
</p> // </p>
<br /> // <br />
<div><code>!justlog optout {"<code>"}</code></div> // <div><code>!justlog optout {"<code>"}</code></div>
<div className="generator"> // <div className="generator">
<input readOnly type="text" value={code} /><Button variant="contained" onClick={generateCode} color="primary" size="large">Generate Code</Button> // <input readOnly type="text" value={code} /><Button variant="contained" onClick={generateCode} color="primary" size="large">Generate Code</Button>
</div> // </div>
{code && <p className="small"> // {code && <p className="small">
This code is valid for 60 seconds // This code is valid for 60 seconds
</p>} // </p>}
</OptoutPanelWrapper>; // </OptoutPanelWrapper>;
} // }

View file

@ -3,7 +3,7 @@ import styled from "styled-components";
import { store } from "../store"; import { store } from "../store";
import { Filters } from "./Filters"; import { Filters } from "./Filters";
import { LogContainer } from "./LogContainer"; import { LogContainer } from "./LogContainer";
import { OptoutPanel } from "./Optout"; // import { OptoutPanel } from "./Optout";
const PageContainer = styled.div` const PageContainer = styled.div`
@ -14,7 +14,6 @@ export function Page() {
return <PageContainer> return <PageContainer>
<Filters /> <Filters />
{state.showOptout && <OptoutPanel />}
<LogContainer /> <LogContainer />
</PageContainer>; </PageContainer>;
} }