FEAT: Add crown icon to messages by users who are subscribed
This commit is contained in:
@@ -5,47 +5,6 @@ import {
|
|||||||
EmbeddedCheckout,
|
EmbeddedCheckout,
|
||||||
} from "@stripe/react-stripe-js";
|
} from "@stripe/react-stripe-js";
|
||||||
|
|
||||||
//! Unsure whether this component is used/needed in the project
|
|
||||||
// export const Return: React.FC = () => {
|
|
||||||
// const [status, setStatus] = useState<string | null>(null);
|
|
||||||
// const [customerEmail, setCustomerEmail] = useState("");
|
|
||||||
|
|
||||||
// useEffect(() => {
|
|
||||||
// const queryString = window.location.search;
|
|
||||||
// const urlParams = new URLSearchParams(queryString);
|
|
||||||
// const sessionId = urlParams.get("session_id");
|
|
||||||
|
|
||||||
// if (sessionId) {
|
|
||||||
// console.log("1");
|
|
||||||
// fetch(`/api/session-status?session_id=${sessionId}`)
|
|
||||||
// .then((res) => res.json())
|
|
||||||
// .then((data) => {
|
|
||||||
// console.log("Response Data:", data);
|
|
||||||
// setStatus(data.status);
|
|
||||||
// setCustomerEmail(data.customer_email);
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// }, []);
|
|
||||||
|
|
||||||
// if (status === "open") {
|
|
||||||
// return <Navigate to="/checkout" />;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (status === "complete") {
|
|
||||||
// return (
|
|
||||||
// <section id="success">
|
|
||||||
// <p>
|
|
||||||
// We appreciate your business! A confirmation email will be sent to{" "}
|
|
||||||
// {customerEmail}. If you have any questions, please email{" "}
|
|
||||||
// <a href="mailto:orders@example.com">orders@example.com</a>.
|
|
||||||
// </p>
|
|
||||||
// </section>
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return null;
|
|
||||||
// };
|
|
||||||
|
|
||||||
interface CheckoutFormProps {
|
interface CheckoutFormProps {
|
||||||
streamerID: number;
|
streamerID: number;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
@@ -77,7 +36,7 @@ const CheckoutForm: React.FC<CheckoutFormProps> = ({ streamerID, onClose }) => {
|
|||||||
<>
|
<>
|
||||||
<div
|
<div
|
||||||
id="blurring-layer"
|
id="blurring-layer"
|
||||||
className="fixed z-10 inset-0 w-screen h-screen backdrop-blur-sm"
|
className="fixed z-50 inset-0 w-screen h-screen backdrop-blur-sm"
|
||||||
></div>
|
></div>
|
||||||
<div
|
<div
|
||||||
id="modal-container"
|
id="modal-container"
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ const Navbar: React.FC<NavbarProps> = ({ variant = "default" }) => {
|
|||||||
<ToggleButton
|
<ToggleButton
|
||||||
extraClasses={`absolute group text-[1rem] top-[2vh] ${
|
extraClasses={`absolute group text-[1rem] top-[2vh] ${
|
||||||
showQuickSettings ? "right-[21vw]" : "right-[20px]"
|
showQuickSettings ? "right-[21vw]" : "right-[20px]"
|
||||||
} cursor-pointer`}
|
} cursor-pointer z-[20]`}
|
||||||
onClick={() => handleQuickSettings()}
|
onClick={() => handleQuickSettings()}
|
||||||
toggled={showQuickSettings}
|
toggled={showQuickSettings}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import ThemeSetting from "./ThemeSetting";
|
import ThemeSetting from "./ThemeSetting";
|
||||||
import { useTheme } from "../../context/ThemeContext";
|
|
||||||
import { useQuickSettings } from "../../context/QuickSettingsContext";
|
import { useQuickSettings } from "../../context/QuickSettingsContext";
|
||||||
import Screenshot from "../Functionality/Screenshot";
|
import Screenshot from "../Functionality/Screenshot";
|
||||||
import BrightnessControl from "../Functionality/BrightnessControl";
|
import BrightnessControl from "../Functionality/BrightnessControl";
|
||||||
|
|
||||||
const QuickSettings: React.FC = () => {
|
const QuickSettings: React.FC = () => {
|
||||||
const { theme } = useTheme();
|
|
||||||
const { showQuickSettings } = useQuickSettings();
|
const { showQuickSettings } = useQuickSettings();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -21,10 +19,7 @@ const QuickSettings: React.FC = () => {
|
|||||||
>
|
>
|
||||||
<h1 className="text-[2rem] font-black">Quick Settings</h1>
|
<h1 className="text-[2rem] font-black">Quick Settings</h1>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div id="quick-settings-menu" className="flex flex-col my-8 gap-4 mb-20">
|
||||||
id="quick-settings-menu"
|
|
||||||
className="flex flex-col my-8 gap-4 mb-20"
|
|
||||||
>
|
|
||||||
<ThemeSetting />
|
<ThemeSetting />
|
||||||
</div>
|
</div>
|
||||||
<Screenshot />
|
<Screenshot />
|
||||||
|
|||||||
@@ -6,12 +6,17 @@ import { useAuthModal } from "../../hooks/useAuthModal";
|
|||||||
import { useAuth } from "../../context/AuthContext";
|
import { useAuth } from "../../context/AuthContext";
|
||||||
import { useSocket } from "../../context/SocketContext";
|
import { useSocket } from "../../context/SocketContext";
|
||||||
import { useChat } from "../../context/ChatContext";
|
import { useChat } from "../../context/ChatContext";
|
||||||
import { ArrowLeftFromLineIcon, ArrowRightFromLineIcon } from "lucide-react";
|
import {
|
||||||
|
ArrowLeftFromLineIcon,
|
||||||
|
ArrowRightFromLineIcon,
|
||||||
|
CrownIcon,
|
||||||
|
} from "lucide-react";
|
||||||
|
|
||||||
interface ChatMessage {
|
interface ChatMessage {
|
||||||
chatter_username: string;
|
chatter_username: string;
|
||||||
message: string;
|
message: string;
|
||||||
time_sent: string;
|
time_sent: string;
|
||||||
|
is_subscribed: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ChatPanelProps {
|
interface ChatPanelProps {
|
||||||
@@ -210,7 +215,7 @@ const ChatPanel: React.FC<ChatPanelProps> = ({
|
|||||||
<div className="flex items-center space-x-0.5em">
|
<div className="flex items-center space-x-0.5em">
|
||||||
{/* Username */}
|
{/* Username */}
|
||||||
<span
|
<span
|
||||||
className={`font-bold text-[1em] ${
|
className={`flex items-center gap-2 font-bold text-[1em] ${
|
||||||
msg.chatter_username === username
|
msg.chatter_username === username
|
||||||
? "text-purple-600"
|
? "text-purple-600"
|
||||||
: "text-green-400 cursor-pointer"
|
: "text-green-400 cursor-pointer"
|
||||||
@@ -221,7 +226,8 @@ const ChatPanel: React.FC<ChatPanelProps> = ({
|
|||||||
: (window.location.href = `/user/${msg.chatter_username}`)
|
: (window.location.href = `/user/${msg.chatter_username}`)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{msg.chatter_username}
|
{msg.chatter_username}
|
||||||
|
{msg.is_subscribed && <CrownIcon size={20} color="gold" />}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
{/* Message content */}
|
{/* Message content */}
|
||||||
|
|||||||
@@ -76,19 +76,32 @@ def get_past_chat(stream_id: int):
|
|||||||
# Connect to the database
|
# Connect to the database
|
||||||
db = Database()
|
db = Database()
|
||||||
|
|
||||||
# fetched in format: [(username, message, time_sent)]
|
# fetched in format: [(username, message, time_sent, is_subscribed)]
|
||||||
all_chats = db.fetchall("""
|
all_chats = db.fetchall("""
|
||||||
SELECT username, message, time_sent
|
SELECT
|
||||||
FROM chat
|
u.username,
|
||||||
JOIN users ON chat.chatter_id = users.user_id
|
c.message,
|
||||||
WHERE stream_id = ?
|
c.time_sent,
|
||||||
ORDER BY time_sent ASC
|
CASE
|
||||||
|
WHEN s.user_id IS NOT NULL AND s.expires > CURRENT_TIMESTAMP THEN 1
|
||||||
|
ELSE 0
|
||||||
|
END AS is_subscribed
|
||||||
|
FROM chat c
|
||||||
|
JOIN users u ON c.chatter_id = u.user_id
|
||||||
|
LEFT JOIN subscribes s ON c.chatter_id = s.user_id AND s.subscribed_id = ?
|
||||||
|
WHERE c.stream_id = ?
|
||||||
|
ORDER BY c.time_sent ASC
|
||||||
LIMIT 50;
|
LIMIT 50;
|
||||||
""", (stream_id,))
|
""", (stream_id, stream_id))
|
||||||
|
|
||||||
db.close_connection()
|
db.close_connection()
|
||||||
|
|
||||||
# Create JSON output of chat_history to pass through NGINX proxy
|
# Create JSON output of chat_history to pass through NGINX proxy
|
||||||
chat_history = [{"chatter_username": chat["username"], "message": chat["message"], "time_sent": chat["time_sent"]} for chat in all_chats]
|
chat_history = [{"chatter_username": chat["username"],
|
||||||
|
"message": chat["message"],
|
||||||
|
"time_sent": chat["time_sent"],
|
||||||
|
"is_subscribed": bool(chat["is_subscribed"])} for chat in all_chats]
|
||||||
|
print(chat_history)
|
||||||
|
|
||||||
# Pass the chat history to the proxy
|
# Pass the chat history to the proxy
|
||||||
return jsonify({"chat_history": chat_history}), 200
|
return jsonify({"chat_history": chat_history}), 200
|
||||||
|
|||||||
Reference in New Issue
Block a user