Compare commits

...

8 Commits

Author SHA1 Message Date
Tim
18fde1052f chore: remove obsolete login styles 2025-09-01 13:14:55 +08:00
tim
575e90e558 fix: telegram support 2025-09-01 13:02:13 +08:00
Tim
e63d66806d fix: tg 环境变量配置 2025-09-01 11:47:37 +08:00
Tim
1fc0118c5a Merge pull request #812 from nagisa77/codex/support-telegram-registration-and-login
feat: add Telegram authentication
2025-09-01 11:41:34 +08:00
Tim
d67cc326c4 Merge pull request #811 from nagisa77/codex/update-last-post-time-display
feat: show message when user has no posts
2025-09-01 11:31:09 +08:00
Tim
27c217a630 feat: show message when user has no posts 2025-09-01 11:30:56 +08:00
Tim
4e3e5f147c Merge pull request #810 from nagisa77/codex/fix-channel-ui-scroll-to-bottom
fix(frontend): scroll to bottom on channel entry
2025-09-01 11:30:40 +08:00
Tim
8767aa31d6 fix(frontend): scroll to bottom on channel entry 2025-09-01 11:30:16 +08:00
11 changed files with 190 additions and 194 deletions

View File

@@ -28,6 +28,7 @@ TWITTER_CLIENT_ID=<你的twitter-client-id>
TWITTER_CLIENT_SECRET=<你的-twitter-client-secret>
DISCORD_CLIENT_ID=<你的discord-client-id>
DISCORD_CLIENT_SECRET=<你的discord-client-secret>
TELEGRAM_BOT_TOKEN=<你的telegram-bot-token>
# === OPENAI ===
OPENAI_API_KEY=<你的openai-api-key>

View File

@@ -13,3 +13,4 @@ NUXT_PUBLIC_GOOGLE_CLIENT_ID=777830451304-nt8afkkap18gui4f9entcha99unal744.apps.
NUXT_PUBLIC_GITHUB_CLIENT_ID=Ov23liVkO1NPAX5JyWxJ
NUXT_PUBLIC_DISCORD_CLIENT_ID=1394985417044000779
NUXT_PUBLIC_TWITTER_CLIENT_ID=ZTRTU05KSk9KTTJrTTdrVC1tc1E6MTpjaQ
NUXT_PUBLIC_TELEGRAM_BOT_ID=8450237135

View File

@@ -14,3 +14,4 @@ NUXT_PUBLIC_GOOGLE_CLIENT_ID=777830451304-nt8afkkap18gui4f9entcha99unal744.apps.
NUXT_PUBLIC_GITHUB_CLIENT_ID=Ov23liVkO1NPAX5JyWxJ
NUXT_PUBLIC_DISCORD_CLIENT_ID=1394985417044000779
NUXT_PUBLIC_TWITTER_CLIENT_ID=ZTRTU05KSk9KTTJrTTdrVC1tc1E6MTpjaQ
NUXT_PUBLIC_TELEGRAM_BOT_ID=8450237135

View File

@@ -27,6 +27,16 @@
--code-highlight-background-color: rgb(241, 241, 241);
--login-background-color: rgb(248, 248, 248);
--login-background-color-hover: #e0e0e0;
--google-login-background-color: var(--login-background-color);
--google-login-background-color-hover: var(--login-background-color-hover);
--github-login-background-color: #000;
--github-login-background-color-hover: #333;
--discord-login-background-color: var(--login-background-color);
--discord-login-background-color-hover: var(--login-background-color-hover);
--twitter-login-background-color: var(--login-background-color);
--twitter-login-background-color-hover: var(--login-background-color-hover);
--telegram-login-background-color: var(--login-background-color);
--telegram-login-background-color-hover: var(--login-background-color-hover);
--text-color: rgb(70, 70, 70);
--blockquote-text-color: #6a737d;
--menu-width: 200px;
@@ -58,6 +68,16 @@
--code-highlight-background-color: #262b35;
--login-background-color: #575757;
--login-background-color-hover: #717171;
--google-login-background-color: var(--login-background-color);
--google-login-background-color-hover: var(--login-background-color-hover);
--github-login-background-color: #000;
--github-login-background-color-hover: #333;
--discord-login-background-color: var(--login-background-color);
--discord-login-background-color-hover: var(--login-background-color-hover);
--twitter-login-background-color: var(--login-background-color);
--twitter-login-background-color-hover: var(--login-background-color-hover);
--telegram-login-background-color: var(--login-background-color);
--telegram-login-background-color-hover: var(--login-background-color-hover);
--text-color: #eee;
--blockquote-text-color: #999;
--article-info-background-color: #747373;

View File

@@ -0,0 +1,151 @@
<template>
<div class="third-party-auth">
<div v-for="p in providers" :key="p.name" :class="['auth-button', p.name]" @click="p.authorize">
<img class="auth-button-icon" :src="p.icon" :alt="p.alt" />
<div class="auth-button-text">{{ p.text }} {{ props.action }}</div>
</div>
</div>
</template>
<script setup>
import { googleAuthorize } from '~/utils/google'
import { githubAuthorize } from '~/utils/github'
import { discordAuthorize } from '~/utils/discord'
import { twitterAuthorize } from '~/utils/twitter'
import { telegramAuthorize } from '~/utils/telegram'
import googleIcon from '~/assets/icons/google.svg'
import githubIcon from '~/assets/icons/github.svg'
import discordIcon from '~/assets/icons/discord.svg'
import twitterIcon from '~/assets/icons/twitter.svg'
import telegramIcon from '~/assets/icons/telegram.svg'
const props = defineProps({
action: {
type: String,
default: '登录',
},
inviteToken: {
type: String,
default: '',
},
})
const providers = [
{
name: 'google',
icon: googleIcon,
alt: 'Google Logo',
text: 'Google',
authorize: () => googleAuthorize(props.inviteToken),
},
{
name: 'github',
icon: githubIcon,
alt: 'GitHub Logo',
text: 'GitHub',
authorize: () => githubAuthorize(props.inviteToken),
},
{
name: 'discord',
icon: discordIcon,
alt: 'Discord Logo',
text: 'Discord',
authorize: () => discordAuthorize(props.inviteToken),
},
{
name: 'twitter',
icon: twitterIcon,
alt: 'Twitter Logo',
text: 'Twitter',
authorize: () => twitterAuthorize(props.inviteToken),
},
{
name: 'telegram',
icon: telegramIcon,
alt: 'Telegram Logo',
text: 'Telegram',
authorize: () => telegramAuthorize(props.inviteToken),
},
]
</script>
<style scoped>
.third-party-auth {
margin-left: 20px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 30%;
gap: 20px;
}
.auth-button {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
padding: 10px 20px;
border: 1px solid var(--normal-border-color);
border-radius: 10px;
cursor: pointer;
min-width: 150px;
gap: 10px;
background-color: var(--auth-bg);
}
.auth-button:hover {
background-color: var(--auth-bg-hover);
}
.auth-button-icon {
width: 20px;
height: 20px;
}
.auth-button-text {
font-size: 16px;
}
.auth-button.google {
--auth-bg: var(--google-login-background-color, var(--login-background-color));
--auth-bg-hover: var(--google-login-background-color-hover, var(--login-background-color-hover));
}
.auth-button.github {
--auth-bg: var(--github-login-background-color, var(--login-background-color));
--auth-bg-hover: var(--github-login-background-color-hover, var(--login-background-color-hover));
}
.auth-button.discord {
--auth-bg: var(--discord-login-background-color, var(--login-background-color));
--auth-bg-hover: var(--discord-login-background-color-hover, var(--login-background-color-hover));
}
.auth-button.twitter {
--auth-bg: var(--twitter-login-background-color, var(--login-background-color));
--auth-bg-hover: var(--twitter-login-background-color-hover, var(--login-background-color-hover));
}
.auth-button.telegram {
--auth-bg: var(--telegram-login-background-color, var(--login-background-color));
--auth-bg-hover: var(
--telegram-login-background-color-hover,
var(--login-background-color-hover)
);
}
@media (max-width: 768px) {
.third-party-auth {
margin-top: 20px;
margin-left: 0;
width: calc(100% - 40px);
gap: 10px;
}
.auth-button {
width: calc(100% - 40px);
}
}
</style>

View File

@@ -34,44 +34,15 @@
</div>
</div>
<div class="other-login-page-content">
<div class="login-page-button" @click="loginWithGoogle">
<img class="login-page-button-icon" src="../assets/icons/google.svg" alt="Google Logo" />
<div class="login-page-button-text">Google 登录</div>
</div>
<div class="login-page-button" @click="loginWithGithub">
<img class="login-page-button-icon" src="../assets/icons/github.svg" alt="GitHub Logo" />
<div class="login-page-button-text">GitHub 登录</div>
</div>
<div class="login-page-button" @click="loginWithDiscord">
<img class="login-page-button-icon" src="../assets/icons/discord.svg" alt="Discord Logo" />
<div class="login-page-button-text">Discord 登录</div>
</div>
<div class="login-page-button" @click="loginWithTwitter">
<img class="login-page-button-icon" src="../assets/icons/twitter.svg" alt="Twitter Logo" />
<div class="login-page-button-text">Twitter 登录</div>
</div>
<div class="login-page-button" @click="loginWithTelegram">
<img
class="login-page-button-icon"
src="../assets/icons/telegram.svg"
alt="Telegram Logo"
/>
<div class="login-page-button-text">Telegram 登录</div>
</div>
</div>
<ThirdPartyAuthButtons action="登录" />
</div>
</template>
<script setup>
import { toast } from '~/main'
import { setToken, loadCurrentUser } from '~/utils/auth'
import { googleAuthorize } from '~/utils/google'
import { githubAuthorize } from '~/utils/github'
import { discordAuthorize } from '~/utils/discord'
import { twitterAuthorize } from '~/utils/twitter'
import { telegramAuthorize } from '~/utils/telegram'
import BaseInput from '~/components/BaseInput.vue'
import ThirdPartyAuthButtons from '~/components/ThirdPartyAuthButtons.vue'
import { registerPush } from '~/utils/push'
const config = useRuntimeConfig()
const API_BASE_URL = config.public.apiBaseUrl
@@ -114,22 +85,6 @@ const submitLogin = async () => {
isWaitingForLogin.value = false
}
}
const loginWithGoogle = () => {
googleAuthorize()
}
const loginWithGithub = () => {
githubAuthorize()
}
const loginWithDiscord = () => {
discordAuthorize()
}
const loginWithTwitter = () => {
twitterAuthorize()
}
const loginWithTelegram = () => {
telegramAuthorize()
}
</script>
<style scoped>
@@ -202,16 +157,6 @@ const loginWithTelegram = () => {
font-size: 16px;
}
.other-login-page-content {
margin-left: 20px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 30%;
gap: 20px;
}
.login-page-button-primary {
margin-top: 20px;
display: flex;
@@ -241,33 +186,6 @@ const loginWithTelegram = () => {
background-color: var(--primary-color-disabled);
}
.login-page-button {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
padding: 10px 20px;
min-width: 150px;
background-color: var(--login-background-color);
border: 1px solid var(--normal-border-color);
border-radius: 10px;
cursor: pointer;
gap: 10px;
}
.login-page-button:hover {
background-color: var(--login-background-color-hover);
}
.login-page-button-icon {
width: 20px;
height: 20px;
}
.login-page-button-text {
font-size: 16px;
}
.login-page-button-secondary {
margin-top: 20px;
font-size: 16px;
@@ -305,16 +223,5 @@ const loginWithTelegram = () => {
margin-top: 0px;
font-size: 13px;
}
.other-login-page-content {
margin-top: 20px;
margin-left: 0px;
width: calc(100% - 40px);
gap: 10px;
}
.login-page-button {
width: calc(100% - 40px);
}
}
</style>

View File

@@ -334,6 +334,9 @@ onMounted(async () => {
if (currentUser.value) {
await fetchMessages(0)
await markConversationAsRead()
await nextTick()
// 初次进入频道时,平滑滚动到底部
scrollToBottomSmooth()
const token = getToken()
if (token && !isConnected.value) {
connect(token)

View File

@@ -68,43 +68,14 @@
</div>
</div>
<div class="other-signup-page-content">
<div class="signup-page-button" @click="signupWithGoogle">
<img class="signup-page-button-icon" src="~/assets/icons/google.svg" alt="Google Logo" />
<div class="signup-page-button-text">Google 注册</div>
</div>
<div class="signup-page-button" @click="signupWithGithub">
<img class="signup-page-button-icon" src="~/assets/icons/github.svg" alt="GitHub Logo" />
<div class="signup-page-button-text">GitHub 注册</div>
</div>
<div class="signup-page-button" @click="signupWithDiscord">
<img class="signup-page-button-icon" src="~/assets/icons/discord.svg" alt="Discord Logo" />
<div class="signup-page-button-text">Discord 注册</div>
</div>
<div class="signup-page-button" @click="signupWithTwitter">
<img class="signup-page-button-icon" src="~/assets/icons/twitter.svg" alt="Twitter Logo" />
<div class="signup-page-button-text">Twitter 注册</div>
</div>
<div class="signup-page-button" @click="signupWithTelegram">
<img
class="signup-page-button-icon"
src="~/assets/icons/telegram.svg"
alt="Telegram Logo"
/>
<div class="signup-page-button-text">Telegram 注册</div>
</div>
</div>
<ThirdPartyAuthButtons action="注册" :invite-token="inviteToken" />
</div>
</template>
<script setup>
import BaseInput from '~/components/BaseInput.vue'
import { toast } from '~/main'
import { discordAuthorize } from '~/utils/discord'
import { githubAuthorize } from '~/utils/github'
import { googleAuthorize } from '~/utils/google'
import { twitterAuthorize } from '~/utils/twitter'
import { telegramAuthorize } from '~/utils/telegram'
import ThirdPartyAuthButtons from '~/components/ThirdPartyAuthButtons.vue'
import { loadCurrentUser, setToken } from '~/utils/auth'
const route = useRoute()
@@ -225,21 +196,6 @@ const verifyCode = async () => {
isWaitingForEmailVerified.value = false
}
}
const signupWithGoogle = () => {
googleAuthorize(inviteToken.value)
}
const signupWithGithub = () => {
githubAuthorize(inviteToken.value)
}
const signupWithDiscord = () => {
discordAuthorize(inviteToken.value)
}
const signupWithTwitter = () => {
twitterAuthorize(inviteToken.value)
}
const signupWithTelegram = () => {
telegramAuthorize(inviteToken.value)
}
</script>
<style scoped>
@@ -312,16 +268,6 @@ const signupWithTelegram = () => {
font-size: 16px;
}
.other-signup-page-content {
margin-left: 20px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 30%;
gap: 20px;
}
.signup-page-button-primary {
margin-top: 20px;
display: flex;
@@ -351,33 +297,6 @@ const signupWithTelegram = () => {
background-color: var(--primary-color-hover);
}
.signup-page-button {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
padding: 10px 20px;
background-color: var(--login-background-color);
border: 1px solid var(--normal-border-color);
border-radius: 10px;
cursor: pointer;
min-width: 150px;
gap: 10px;
}
.signup-page-button:hover {
background-color: var(--login-background-color-hover);
}
.signup-page-button-icon {
width: 20px;
height: 20px;
}
.signup-page-button-text {
font-size: 16px;
}
.signup-page-button-secondary {
margin-top: 20px;
font-size: 16px;
@@ -423,16 +342,5 @@ const signupWithTelegram = () => {
margin-top: 0px;
font-size: 13px;
}
.other-signup-page-content {
margin-top: 20px;
margin-left: 0px;
width: calc(100% - 40px);
gap: 10px;
}
.signup-page-button {
width: calc(100% - 40px);
}
}
</style>

View File

@@ -4,6 +4,7 @@
<script setup>
import CallbackPage from '~/components/CallbackPage.vue'
import { I } from '~/dist/_nuxt/F7ewH_Zb'
import { telegramExchange } from '~/utils/telegram'
onMounted(async () => {
@@ -17,7 +18,8 @@ onMounted(async () => {
}
let authData
try {
const parsed = JSON.parse(decodeURIComponent(hash))
const decoded = atob(hash)
const parsed = JSON.parse(decoded)
authData = {
id: String(parsed.id),
firstName: parsed.first_name,

View File

@@ -58,7 +58,9 @@
</div>
<div class="profile-info-item">
<div class="profile-info-item-label">最后发帖时间:</div>
<div class="profile-info-item-value">{{ formatDate(user.lastPostTime) }}</div>
<div class="profile-info-item-value">
{{ user.lastPostTime != null ? formatDate(user.lastPostTime) : '暂无帖子' }}
</div>
</div>
<div class="profile-info-item">
<div class="profile-info-item-label">最后评论时间:</div>

View File

@@ -14,9 +14,9 @@ export function telegramAuthorize(inviteToken = '') {
const url =
`https://oauth.telegram.org/auth` +
`?bot_id=${encodeURIComponent(TELEGRAM_BOT_ID)}` +
`&origin=${encodeURIComponent(WEBSITE_BASE_URL)}` +
`&request_access=write` +
`&redirect_uri=${encodeURIComponent(redirectUri)}`
`&origin=${encodeURIComponent(redirectUri)}` +
`&request_access=write`
// `&redirect_uri=${encodeURIComponent(redirectUri)}`
window.location.href = url
}