sex!!!!!!!!!!!!!!!!
This commit is contained in:
parent
bf93d8410c
commit
f34ffe3df6
9 changed files with 116 additions and 124 deletions
|
@ -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)
|
||||||
}
|
// }
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
0
web/dist/.gitkeep
vendored
|
@ -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%;
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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>
|
||||||
}
|
}
|
|
@ -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>;
|
||||||
}
|
// }
|
|
@ -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>;
|
||||||
}
|
}
|
Loading…
Add table
Reference in a new issue