Updated err handleing
This commit is contained in:
parent
8e3714028d
commit
9574d3b031
40
Chat.go
40
Chat.go
@ -43,6 +43,7 @@ func DeleteMessageHandler(c *fiber.Ctx) error {
|
||||
|
||||
messageUUID, err := edgedb.ParseUUID(messageId)
|
||||
if err != nil {
|
||||
fmt.Print("Error parsing UUID")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@ -54,6 +55,7 @@ func DeleteMessageHandler(c *fiber.Ctx) error {
|
||||
FILTER .position >= messageArea.position AND .conversation = messageArea.conversation;
|
||||
`, messageUUID)
|
||||
if err != nil {
|
||||
fmt.Print("Error deleting messages")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@ -91,6 +93,7 @@ func generateChatHTML() string {
|
||||
err := edgeClient.QuerySingle(edgeCtx, `
|
||||
SELECT global currentConversation { name }`, ¤tConv)
|
||||
if err != nil {
|
||||
fmt.Print("Error getting current conversation")
|
||||
panic(err)
|
||||
}
|
||||
fmt.Println("Current conversation: ", currentConv.Name)
|
||||
@ -120,6 +123,7 @@ func generateChatHTML() string {
|
||||
ORDER BY .date ASC
|
||||
`, &Messages)
|
||||
if err != nil {
|
||||
fmt.Print("Error getting messages")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@ -132,6 +136,7 @@ func generateChatHTML() string {
|
||||
htmlContent := markdownToHTML(message.Content)
|
||||
userOut, err := userTmpl.Execute(pongo2.Context{"Content": htmlContent, "ID": message.ID.String()})
|
||||
if err != nil {
|
||||
fmt.Print("Error executing user template")
|
||||
panic(err)
|
||||
}
|
||||
htmlString += userOut
|
||||
@ -164,6 +169,7 @@ func generateChatHTML() string {
|
||||
|
||||
botOut, err := botTmpl.Execute(pongo2.Context{"Messages": templateMessages, "ConversationAreaId": i})
|
||||
if err != nil {
|
||||
fmt.Print("Error executing bot template")
|
||||
panic(err)
|
||||
}
|
||||
htmlString += botOut
|
||||
@ -192,11 +198,13 @@ func GetUserMessageHandler(c *fiber.Ctx) error {
|
||||
.id = <uuid>$0;
|
||||
`, &selectedMessage, messageUUID)
|
||||
if err != nil {
|
||||
fmt.Print("Error getting message")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
out, err := userTmpl.Execute(pongo2.Context{"Content": markdownToHTML(selectedMessage.Content), "ID": id})
|
||||
if err != nil {
|
||||
fmt.Print("Error executing user template")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@ -285,6 +293,7 @@ func generateWelcomeChatHTML() string {
|
||||
|
||||
botOut, err := botTmpl.Execute(pongo2.Context{"Messages": NextMessages, "ConversationAreaId": 0, "NotClickable": true})
|
||||
if err != nil {
|
||||
fmt.Print("Error executing bot template")
|
||||
panic(err)
|
||||
}
|
||||
htmlString += botOut
|
||||
@ -320,6 +329,7 @@ func generateEnterKeyChatHTML() string {
|
||||
|
||||
botOut, err := botTmpl.Execute(pongo2.Context{"Messages": NextMessages, "ConversationAreaId": 0, "NotClickable": true})
|
||||
if err != nil {
|
||||
fmt.Print("Error executing bot template")
|
||||
panic(err)
|
||||
}
|
||||
htmlString += botOut
|
||||
@ -363,6 +373,7 @@ func generateTermAndServiceChatHTML() string {
|
||||
|
||||
botOut, err := botTmpl.Execute(pongo2.Context{"Messages": NextMessages, "ConversationAreaId": 0, "NotClickable": true})
|
||||
if err != nil {
|
||||
fmt.Print("Error executing bot template")
|
||||
panic(err)
|
||||
}
|
||||
htmlString += botOut
|
||||
@ -379,6 +390,7 @@ func generateLimitReachedChatHTML() string {
|
||||
var result User
|
||||
err := edgeClient.QuerySingle(edgeCtx, "SELECT global currentUser { stripe_id, email } LIMIT 1;", &result)
|
||||
if err != nil {
|
||||
fmt.Print("Error getting current user")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@ -406,6 +418,7 @@ func generateLimitReachedChatHTML() string {
|
||||
|
||||
botOut, err := botTmpl.Execute(pongo2.Context{"Messages": NextMessages, "ConversationAreaId": 0, "NotClickable": true})
|
||||
if err != nil {
|
||||
fmt.Print("Error executing bot template")
|
||||
panic(err)
|
||||
}
|
||||
htmlString += botOut
|
||||
@ -427,6 +440,7 @@ func GetEditMessageFormHandler(c *fiber.Ctx) error {
|
||||
FILTER .id = <uuid>$0;
|
||||
`, &message, idUUID)
|
||||
if err != nil {
|
||||
fmt.Print("Error getting message")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@ -439,6 +453,7 @@ func GetEditMessageFormHandler(c *fiber.Ctx) error {
|
||||
tmpl := pongo2.Must(pongo2.FromFile("views/partials/message-edit-form.html"))
|
||||
out, err := tmpl.Execute(pongo2.Context{"Content": message.Content, "ID": id, "Rows": rows})
|
||||
if err != nil {
|
||||
fmt.Print("Error executing user template")
|
||||
panic(err)
|
||||
}
|
||||
return c.SendString(out)
|
||||
@ -451,7 +466,7 @@ func RedoMessageHandler(c *fiber.Ctx) error {
|
||||
var selectedLLMIds []string
|
||||
err := json.Unmarshal([]byte(c.FormValue("selectedLLMIds")), &selectedLLMIds)
|
||||
if err != nil {
|
||||
// Handle the error
|
||||
fmt.Print("Error unmarshalling selected LLM IDs")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@ -461,6 +476,7 @@ func RedoMessageHandler(c *fiber.Ctx) error {
|
||||
FILTER .id = <uuid>$0;
|
||||
`, &message, messageUUID)
|
||||
if err != nil {
|
||||
fmt.Print("Error getting message")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@ -472,6 +488,7 @@ func RedoMessageHandler(c *fiber.Ctx) error {
|
||||
FILTER .position > messageArea.position AND .conversation = messageArea.conversation AND .conversation.user = global currentUser;
|
||||
`, messageUUID)
|
||||
if err != nil {
|
||||
fmt.Print("Error deleting messages")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@ -486,7 +503,7 @@ func EditMessageHandler(c *fiber.Ctx) error {
|
||||
var selectedLLMIds []string
|
||||
err := json.Unmarshal([]byte(c.FormValue("selectedLLMIds")), &selectedLLMIds)
|
||||
if err != nil {
|
||||
// Handle the error
|
||||
fmt.Print("Error unmarshalling selected LLM IDs")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@ -502,6 +519,7 @@ func EditMessageHandler(c *fiber.Ctx) error {
|
||||
FILTER .position >= messageArea.position AND .conversation = messageArea.conversation AND .conversation.user = global currentUser;
|
||||
`, messageUUID)
|
||||
if err != nil {
|
||||
fmt.Print("Error deleting messages")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@ -515,6 +533,7 @@ func ClearChatHandler(c *fiber.Ctx) error {
|
||||
FILTER .conversation = global currentConversation;
|
||||
`)
|
||||
if err != nil {
|
||||
fmt.Print("Error deleting messages")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@ -534,6 +553,7 @@ func LoadUsageKPIHandler(c *fiber.Ctx) error {
|
||||
var InputDate time.Time
|
||||
InputDate, err := time.Parse("01-2006", InputDateID)
|
||||
if err != nil {
|
||||
fmt.Print("Error parsing date")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@ -574,6 +594,7 @@ func LoadUsageKPIHandler(c *fiber.Ctx) error {
|
||||
} FILTER .total_count > 0 ORDER BY .total_cost DESC
|
||||
`, &usages, InputDate, InputDate.AddDate(0, 1, 0))
|
||||
if err != nil {
|
||||
fmt.Print("Error getting usage")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@ -597,6 +618,7 @@ func LoadUsageKPIHandler(c *fiber.Ctx) error {
|
||||
"IsActive": IsActive,
|
||||
})
|
||||
if err != nil {
|
||||
fmt.Print("Error generating usage")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@ -620,6 +642,7 @@ func LoadKeysHandler(c *fiber.Ctx) error {
|
||||
"AnyExists": openaiExists || anthropicExists || mistralExists || groqExists || gooseaiExists || googleExists,
|
||||
})
|
||||
if err != nil {
|
||||
fmt.Print("Error loading keys")
|
||||
panic(err)
|
||||
}
|
||||
return c.SendString(out)
|
||||
@ -648,6 +671,7 @@ func GenerateModelPopoverHTML(refresh bool) string {
|
||||
ORDER BY .position
|
||||
`, &llms)
|
||||
if err != nil {
|
||||
fmt.Print("Error loading LLMs")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@ -668,6 +692,7 @@ func GenerateModelPopoverHTML(refresh bool) string {
|
||||
"IsSub": IsCurrentUserSubscribed(),
|
||||
})
|
||||
if err != nil {
|
||||
fmt.Print("Error generating model popover")
|
||||
panic(err)
|
||||
}
|
||||
return out
|
||||
@ -692,6 +717,7 @@ func GenerateConversationPopoverHTML(isActive bool) string {
|
||||
ORDER BY .position
|
||||
`, &conversations)
|
||||
if err != nil {
|
||||
fmt.Print("Error loading conversations")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@ -700,6 +726,7 @@ func GenerateConversationPopoverHTML(isActive bool) string {
|
||||
"IsActive": isActive,
|
||||
})
|
||||
if err != nil {
|
||||
fmt.Print("Error generating conversation popover")
|
||||
panic(err)
|
||||
}
|
||||
return out
|
||||
@ -731,6 +758,7 @@ func LoadSettingsHandler(c *fiber.Ctx) error {
|
||||
FILTER .id = global currentUser.id
|
||||
`, &user)
|
||||
if err != nil {
|
||||
fmt.Print("Error loading user")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@ -754,6 +782,7 @@ func LoadSettingsHandler(c *fiber.Ctx) error {
|
||||
"StripeSubLink": stripeSubLink,
|
||||
})
|
||||
if err != nil {
|
||||
fmt.Print("Error loading settings")
|
||||
panic(err)
|
||||
}
|
||||
return c.SendString(out)
|
||||
@ -778,6 +807,7 @@ func CreateConversationHandler(c *fiber.Ctx) error {
|
||||
}
|
||||
`, name)
|
||||
if err != nil {
|
||||
fmt.Print("Error creating conversation")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@ -789,7 +819,7 @@ func DeleteConversationHandler(c *fiber.Ctx) error {
|
||||
|
||||
conversationUUID, err := edgedb.ParseUUID(conversationId)
|
||||
if err != nil {
|
||||
// Handle the error
|
||||
fmt.Print("Error parsing UUID")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@ -798,6 +828,7 @@ func DeleteConversationHandler(c *fiber.Ctx) error {
|
||||
FILTER .user = global currentUser AND .id = <uuid>$0;
|
||||
`, conversationUUID)
|
||||
if err != nil {
|
||||
fmt.Print("Error deleting conversation")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@ -808,7 +839,7 @@ func SelectConversationHandler(c *fiber.Ctx) error {
|
||||
conversationId := c.FormValue("conversation-id")
|
||||
conversationUUID, err := edgedb.ParseUUID(conversationId)
|
||||
if err != nil {
|
||||
// Handle the error
|
||||
fmt.Print("Error parsing UUID")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@ -822,6 +853,7 @@ func SelectConversationHandler(c *fiber.Ctx) error {
|
||||
);
|
||||
`, conversationUUID)
|
||||
if err != nil {
|
||||
fmt.Print("Error selecting conversation")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
|
9
LLM.go
9
LLM.go
@ -14,7 +14,7 @@ func deleteLLM(c *fiber.Ctx) error {
|
||||
var selectedLLMIds []string
|
||||
err := json.Unmarshal([]byte(c.FormValue("selectedLLMIds")), &selectedLLMIds)
|
||||
if err != nil {
|
||||
// Handle the error
|
||||
fmt.Print("Error unmarshalling selected LLM IDs")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@ -28,6 +28,7 @@ func deleteLLM(c *fiber.Ctx) error {
|
||||
};
|
||||
`, idUUID)
|
||||
if err != nil {
|
||||
fmt.Print("Error deleting LLM")
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
@ -86,6 +87,7 @@ func createLLM(c *fiber.Ctx) error {
|
||||
};
|
||||
`, name, systemPrompt, temperatureFloat, url, token, customID) // TODO Add real max token
|
||||
if err != nil {
|
||||
fmt.Print("Error creating LLM")
|
||||
panic(err)
|
||||
}
|
||||
} else {
|
||||
@ -102,6 +104,7 @@ func createLLM(c *fiber.Ctx) error {
|
||||
}
|
||||
`, name, systemPrompt, temperatureFloat, modelID)
|
||||
if err != nil {
|
||||
fmt.Print("Error creating LLM")
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
@ -123,6 +126,7 @@ func updateLLMPositionBatch(c *fiber.Ctx) error {
|
||||
for _, update := range positionUpdates {
|
||||
idUUID, err := edgedb.ParseUUID(update.ID)
|
||||
if err != nil {
|
||||
fmt.Print("Error parsing UUID")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@ -134,6 +138,7 @@ func updateLLMPositionBatch(c *fiber.Ctx) error {
|
||||
};
|
||||
`, idUUID, int32(update.Position))
|
||||
if err != nil {
|
||||
fmt.Print("Error updating LLM position")
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
@ -152,6 +157,7 @@ func updateConversationPositionBatch(c *fiber.Ctx) error {
|
||||
fmt.Println(update.ID)
|
||||
idUUID, err := edgedb.ParseUUID(update.ID)
|
||||
if err != nil {
|
||||
fmt.Print("Error parsing UUID")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@ -163,6 +169,7 @@ func updateConversationPositionBatch(c *fiber.Ctx) error {
|
||||
};
|
||||
`, idUUID, int32(update.Position))
|
||||
if err != nil {
|
||||
fmt.Print("Error updating conversation position")
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ func GeneratePlaceholderHandler(c *fiber.Ctx) error {
|
||||
var selectedLLMIds []string
|
||||
err := json.Unmarshal([]byte(c.FormValue("selectedLLMIds")), &selectedLLMIds)
|
||||
if err != nil {
|
||||
// Handle the error
|
||||
fmt.Print("Error unmarshalling selected LLM IDs")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@ -74,6 +74,7 @@ func GeneratePlaceholderHTML(message string, selectedLLMIds []string, with_user_
|
||||
.id = <uuid>$0;
|
||||
`, &selectedLLM, idUUID)
|
||||
if err != nil {
|
||||
fmt.Print("Error getting LLM")
|
||||
panic(err)
|
||||
}
|
||||
selectedLLMs = append(selectedLLMs, selectedLLM)
|
||||
@ -163,7 +164,7 @@ func GenerateMultipleMessagesHandler(c *fiber.Ctx) error {
|
||||
FILTER .id = <uuid>$0;
|
||||
`, &message, messageID)
|
||||
if err != nil {
|
||||
fmt.Println("Panic here but why ?")
|
||||
fmt.Print("Error getting message")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@ -192,6 +193,7 @@ func GenerateMultipleMessagesHandler(c *fiber.Ctx) error {
|
||||
"ConversationAreaId": message.Area.Position,
|
||||
})
|
||||
if err != nil {
|
||||
fmt.Print("Error generating HTML content")
|
||||
panic(err)
|
||||
}
|
||||
outBtn = strings.ReplaceAll(outBtn, "\n", "")
|
||||
@ -218,6 +220,7 @@ func GenerateMultipleMessagesHandler(c *fiber.Ctx) error {
|
||||
"ConversationAreaId": message.Area.Position,
|
||||
})
|
||||
if err != nil {
|
||||
fmt.Print("Error generating HTML content")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@ -255,6 +258,7 @@ func addUsage(inputCost float32, outputCost float32, inputToken int32, outputTok
|
||||
}
|
||||
`, inputCost, outputCost, inputToken, outputToken, modelID)
|
||||
if err != nil {
|
||||
fmt.Print("Error adding usage")
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
@ -51,6 +51,7 @@ func addGoogleMessage(llm LLM, selected bool) edgedb.UUID {
|
||||
|
||||
chatCompletion, err := RequestGoogle(llm.Model.ModelID, Messages, float64(llm.Temperature), llm.Context)
|
||||
if err != nil {
|
||||
fmt.Print("Error fetching user profile")
|
||||
panic(err)
|
||||
} else if len(chatCompletion.Choices) == 0 {
|
||||
fmt.Println("No response from Google")
|
||||
|
@ -38,6 +38,7 @@ func addGooseaiMessage(llm LLM, selected bool) edgedb.UUID {
|
||||
|
||||
chatCompletion, err := RequestGooseai(llm.Model.ModelID, Messages, float64(llm.Temperature))
|
||||
if err != nil {
|
||||
fmt.Print("Error fetching user profile")
|
||||
panic(err)
|
||||
} else if len(chatCompletion.Choices) == 0 {
|
||||
fmt.Println("No response from GooseAI")
|
||||
|
@ -42,6 +42,7 @@ func addHuggingfaceMessage(llm LLM, selected bool) edgedb.UUID {
|
||||
|
||||
chatCompletion, err := RequestHuggingface(llm, Messages, float64(llm.Temperature))
|
||||
if err != nil {
|
||||
fmt.Print("Error fetching user profile")
|
||||
panic(err)
|
||||
} else if len(chatCompletion.Choices) == 0 {
|
||||
fmt.Println("No response from Endpoint")
|
||||
|
@ -42,6 +42,7 @@ func addOpenaiMessage(llm LLM, selected bool) edgedb.UUID {
|
||||
|
||||
chatCompletion, err := RequestOpenai(llm.Model.ModelID, Messages, float64(llm.Temperature), llm.Context)
|
||||
if err != nil {
|
||||
fmt.Print("Error fetching user profile")
|
||||
panic(err)
|
||||
} else if len(chatCompletion.Choices) == 0 {
|
||||
fmt.Println("No response from OpenAI")
|
||||
|
23
Stripe.go
23
Stripe.go
@ -22,6 +22,7 @@ func generatePricingTableChatHTML() string {
|
||||
var result User
|
||||
err := edgeClient.QuerySingle(edgeCtx, "SELECT global currentUser { stripe_id, email } LIMIT 1;", &result)
|
||||
if err != nil {
|
||||
fmt.Print("Error getting user")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@ -59,6 +60,7 @@ func generatePricingTableChatHTML() string {
|
||||
|
||||
botOut, err := botTmpl.Execute(pongo2.Context{"Messages": NextMessages, "ConversationAreaId": 0, "NotClickable": true, "notFlex": true})
|
||||
if err != nil {
|
||||
fmt.Print("Error executing template")
|
||||
panic(err)
|
||||
}
|
||||
htmlString += botOut
|
||||
@ -85,10 +87,12 @@ func IsCurrentUserSubscribed() bool {
|
||||
var user User
|
||||
err := edgeClient.QuerySingle(edgeCtx, "SELECT global currentUser { stripe_id } LIMIT 1;", &user)
|
||||
if err != nil {
|
||||
fmt.Print("Error getting user")
|
||||
panic(err)
|
||||
}
|
||||
result, err := customer.Get(user.StripeID, nil)
|
||||
if err != nil {
|
||||
fmt.Print("Error getting customer")
|
||||
panic(err)
|
||||
}
|
||||
if result.Subscriptions.TotalCount == 0 {
|
||||
@ -110,6 +114,7 @@ func IsCurrentUserLimiteReached() bool {
|
||||
SELECT count(U)
|
||||
`, &count)
|
||||
if err != nil {
|
||||
fmt.Print("Error counting Usage")
|
||||
panic(err)
|
||||
}
|
||||
return count >= 500
|
||||
@ -119,6 +124,7 @@ func CreateClientSecretSession() string {
|
||||
var user User
|
||||
err := edgeClient.QuerySingle(edgeCtx, "SELECT global currentUser { stripe_id } LIMIT 1;", &user)
|
||||
if err != nil {
|
||||
fmt.Print("Error getting user")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@ -130,7 +136,8 @@ func CreateClientSecretSession() string {
|
||||
|
||||
req, err := http.NewRequest(method, url, bytes.NewBuffer(payload))
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("failed to create request: %v", err))
|
||||
fmt.Print("failed to create request")
|
||||
panic(err)
|
||||
}
|
||||
req.Header.Add("Authorization", "Bearer "+apiKey)
|
||||
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
|
||||
@ -138,18 +145,21 @@ func CreateClientSecretSession() string {
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("failed to execute request: %v", err))
|
||||
fmt.Print("failed to execute request")
|
||||
panic(err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
body, _ := io.ReadAll(resp.Body)
|
||||
panic(fmt.Sprintf("failed to create customer session: status code %d, response: %s", resp.StatusCode, string(body)))
|
||||
fmt.Print("failed to create customer session")
|
||||
panic(fmt.Sprintf("failed to create customer session: %s", string(body)))
|
||||
}
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("failed to read response body: %v", err))
|
||||
fmt.Print("failed to read response body")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
type CustomerSessionResponse struct {
|
||||
@ -159,11 +169,12 @@ func CreateClientSecretSession() string {
|
||||
|
||||
var customerSession CustomerSessionResponse
|
||||
if err := json.Unmarshal(body, &customerSession); err != nil {
|
||||
panic(fmt.Sprintf("failed to unmarshal response: %v", err))
|
||||
fmt.Print("failed to unmarshal response")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if user.StripeID != customerSession.CustomerID {
|
||||
panic(fmt.Sprintf("customer_id does not match: got %s, expected %s", customerSession.CustomerID, user.StripeID))
|
||||
panic("customer_id does not match")
|
||||
}
|
||||
|
||||
return customerSession.ClientSecret
|
||||
|
@ -5,6 +5,7 @@ package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/edgedb/edgedb-go"
|
||||
@ -121,6 +122,7 @@ func init() {
|
||||
var ctx = context.Background()
|
||||
client, err := edgedb.CreateClient(ctx, edgedb.Options{})
|
||||
if err != nil {
|
||||
fmt.Print("Error connecting to edgedb")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@ -146,6 +148,7 @@ func insertArea() (edgedb.UUID, int64) {
|
||||
}
|
||||
`, &inserted)
|
||||
if err != nil {
|
||||
fmt.Print("Error inserting area")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@ -177,6 +180,7 @@ func insertUserMessage(content string) edgedb.UUID {
|
||||
LIMIT 1
|
||||
`, &lastArea)
|
||||
if err != nil {
|
||||
fmt.Print("Error getting last area")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@ -197,6 +201,7 @@ func insertUserMessage(content string) edgedb.UUID {
|
||||
}
|
||||
`, &inserted, "user", content, lastArea.ID)
|
||||
if err != nil {
|
||||
fmt.Print("Error inserting user message")
|
||||
panic(err)
|
||||
}
|
||||
return inserted.id
|
||||
@ -213,6 +218,7 @@ func insertBotMessage(content string, selected bool, llmUUID edgedb.UUID) edgedb
|
||||
LIMIT 1
|
||||
`, &lastArea)
|
||||
if err != nil {
|
||||
fmt.Print("Error getting last area")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@ -240,6 +246,7 @@ func insertBotMessage(content string, selected bool, llmUUID edgedb.UUID) edgedb
|
||||
}
|
||||
`, &inserted, "bot", llmUUID, content, selected, lastArea.ID)
|
||||
if err != nil {
|
||||
fmt.Print("Error inserting bot message")
|
||||
panic(err)
|
||||
}
|
||||
return inserted.id
|
||||
@ -272,6 +279,7 @@ func getAllSelectedMessages() []Message {
|
||||
ORDER BY .date ASC
|
||||
`, &messages)
|
||||
if err != nil {
|
||||
fmt.Print("Error getting messages")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
|
77
login.go
77
login.go
@ -38,28 +38,33 @@ func getGoogleUserProfile(providerToken string) (string, string, string) {
|
||||
// Fetch the discovery document
|
||||
resp, err := http.Get("https://accounts.google.com/.well-known/openid-configuration")
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("failed to fetch discovery document: %v", err))
|
||||
fmt.Print("Error fetching discovery document")
|
||||
panic(err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
panic(fmt.Sprintf("failed to fetch discovery document: status code %d", resp.StatusCode))
|
||||
fmt.Print("Error fetching discovery document")
|
||||
panic(resp.StatusCode)
|
||||
}
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("failed to read discovery document response: %v", err))
|
||||
fmt.Print("Error reading discovery document")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
var discoveryDocument DiscoveryDocument
|
||||
if err := json.Unmarshal(body, &discoveryDocument); err != nil {
|
||||
panic(fmt.Sprintf("failed to unmarshal discovery document: %v", err))
|
||||
fmt.Print("Error unmarshalling discovery document")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Fetch the user profile
|
||||
req, err := http.NewRequest("GET", discoveryDocument.UserInfoEndpoint, nil)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("failed to create user profile request: %v", err))
|
||||
fmt.Print("Error fetching user profile")
|
||||
panic(err)
|
||||
}
|
||||
req.Header.Set("Authorization", "Bearer "+providerToken)
|
||||
req.Header.Set("Accept", "application/json")
|
||||
@ -67,22 +72,26 @@ func getGoogleUserProfile(providerToken string) (string, string, string) {
|
||||
client := &http.Client{}
|
||||
resp, err = client.Do(req)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("failed to fetch user profile: %v", err))
|
||||
fmt.Print("Error fetching user profile")
|
||||
panic(err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
panic(fmt.Sprintf("failed to fetch user profile: status code %d", resp.StatusCode))
|
||||
fmt.Print("Error fetching user profile")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
body, err = io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("failed to read user profile response: %v", err))
|
||||
fmt.Print("Error reading user profile")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
var userProfile UserProfile
|
||||
if err := json.Unmarshal(body, &userProfile); err != nil {
|
||||
panic(fmt.Sprintf("failed to unmarshal user profile: %v", err))
|
||||
fmt.Print("Error unmarshalling user profile")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return userProfile.Email, userProfile.Name, userProfile.AvatarGoogle
|
||||
@ -92,7 +101,8 @@ func getGitHubUserProfile(providerToken string) (string, string, string) {
|
||||
// Create the request to fetch the user profile
|
||||
req, err := http.NewRequest("GET", "https://api.github.com/user", nil)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("failed to create user profile request: %v", err))
|
||||
fmt.Print("failed to create request: %v", err)
|
||||
panic(err)
|
||||
}
|
||||
req.Header.Set("Authorization", "Bearer "+providerToken)
|
||||
req.Header.Set("Accept", "application/vnd.github+json")
|
||||
@ -101,22 +111,26 @@ func getGitHubUserProfile(providerToken string) (string, string, string) {
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("failed to fetch user profile: %v", err))
|
||||
fmt.Print("failed to execute request")
|
||||
panic(err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
panic(fmt.Sprintf("failed to fetch user profile: status code %d", resp.StatusCode))
|
||||
fmt.Print("failed to fetch user profile: status code")
|
||||
panic(resp.StatusCode)
|
||||
}
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("failed to read user profile response: %v", err))
|
||||
fmt.Print("failed to read response body")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
var userProfile UserProfile
|
||||
if err := json.Unmarshal(body, &userProfile); err != nil {
|
||||
panic(fmt.Sprintf("failed to unmarshal user profile: %v", err))
|
||||
fmt.Print("failed to unmarshal user profile")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return userProfile.Email, userProfile.Name, userProfile.AvatarGitHub
|
||||
@ -126,6 +140,7 @@ func generatePKCE() (string, string) {
|
||||
verifier_source := make([]byte, 32)
|
||||
_, err := rand.Read(verifier_source)
|
||||
if err != nil {
|
||||
fmt.Print("failed to generate PKCE")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@ -152,30 +167,34 @@ func handleCallbackSignup(c *fiber.Ctx) error {
|
||||
code := c.Query("code")
|
||||
if code == "" {
|
||||
err := c.Query("error")
|
||||
return c.Status(fiber.StatusBadRequest).SendString(fmt.Sprintf("OAuth callback is missing 'code'. OAuth provider responded with error: %s", err))
|
||||
fmt.Print("OAuth callback is missing 'code'. OAuth provider responded with error")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
verifier := c.Cookies("jade-edgedb-pkce-verifier", "")
|
||||
if verifier == "" {
|
||||
return c.Status(fiber.StatusBadRequest).SendString("Could not find 'verifier' in the cookie store. Is this the same user agent/browser that started the authorization flow?")
|
||||
panic("Could not find 'verifier' in the cookie store. Is this the same user agent/browser that started the authorization flow?")
|
||||
}
|
||||
|
||||
codeExchangeURL := fmt.Sprintf("%s/token?code=%s&verifier=%s", EDGEDB_AUTH_BASE_URL, code, verifier)
|
||||
resp, err := http.Get(codeExchangeURL)
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusBadRequest).SendString(fmt.Sprintf("Error from the auth server: %s", err.Error()))
|
||||
fmt.Print("Error exchanging code for access token")
|
||||
panic(err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != fiber.StatusOK {
|
||||
body, _ := io.ReadAll(resp.Body)
|
||||
return c.Status(fiber.StatusBadRequest).SendString(fmt.Sprintf("Error from the auth server: %s", string(body)))
|
||||
fmt.Print("Error exchanging code for access token")
|
||||
panic(string(body))
|
||||
}
|
||||
|
||||
var tokenResponse TokenResponse
|
||||
err = json.NewDecoder(resp.Body).Decode(&tokenResponse)
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusBadRequest).SendString(fmt.Sprintf("Error decoding auth server response: %s", err.Error()))
|
||||
fmt.Print("Error decoding auth server response")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
c.Cookie(&fiber.Cookie{
|
||||
@ -190,6 +209,7 @@ func handleCallbackSignup(c *fiber.Ctx) error {
|
||||
var identity Identity
|
||||
identityUUID, err := edgedb.ParseUUID(tokenResponse.IdentityID)
|
||||
if err != nil {
|
||||
fmt.Print("Error parsing UUID")
|
||||
panic(err)
|
||||
}
|
||||
err = edgeClient.QuerySingle(edgeCtx, `
|
||||
@ -198,6 +218,7 @@ func handleCallbackSignup(c *fiber.Ctx) error {
|
||||
} FILTER .id = <uuid>$0
|
||||
`, &identity, identityUUID)
|
||||
if err != nil {
|
||||
fmt.Print("Error fetching identity")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@ -231,7 +252,8 @@ func handleCallbackSignup(c *fiber.Ctx) error {
|
||||
}
|
||||
`, stripCustID, providerEmail, providerName, providerAvatar, identityUUID)
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusInternalServerError).SendString(fmt.Sprintf("Error in edgedb.QuerySingle: in handleCallbackSignup: %s", err.Error()))
|
||||
fmt.Print("Error creating user")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
edgeClient = edgeClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": tokenResponse.AuthToken})
|
||||
@ -243,6 +265,7 @@ func handleCallbackSignup(c *fiber.Ctx) error {
|
||||
position := 1
|
||||
}`)
|
||||
if err != nil {
|
||||
fmt.Print("Error creating default conversation")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@ -253,30 +276,34 @@ func handleCallback(c *fiber.Ctx) error {
|
||||
code := c.Query("code")
|
||||
if code == "" {
|
||||
err := c.Query("error")
|
||||
return c.Status(fiber.StatusBadRequest).SendString(fmt.Sprintf("OAuth callback is missing 'code'. OAuth provider responded with error: %s", err))
|
||||
fmt.Print("OAuth callback is missing 'code'. OAuth provider responded with error")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
verifier := c.Cookies("jade-edgedb-pkce-verifier", "")
|
||||
if verifier == "" {
|
||||
return c.Status(fiber.StatusBadRequest).SendString("Could not find 'verifier' in the cookie store. Is this the same user agent/browser that started the authorization flow?")
|
||||
panic("Could not find 'verifier' in the cookie store. Is this the same user agent/browser that started the authorization flow?")
|
||||
}
|
||||
|
||||
codeExchangeURL := fmt.Sprintf("%s/token?code=%s&verifier=%s", EDGEDB_AUTH_BASE_URL, code, verifier)
|
||||
resp, err := http.Get(codeExchangeURL)
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusBadRequest).SendString(fmt.Sprintf("Error from the auth server: %s", err.Error()))
|
||||
fmt.Print("Error exchanging code for access token")
|
||||
panic(err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != fiber.StatusOK {
|
||||
body, _ := io.ReadAll(resp.Body)
|
||||
return c.Status(fiber.StatusBadRequest).SendString(fmt.Sprintf("Error from the auth server: %s", string(body)))
|
||||
fmt.Print("Error exchanging code for access token")
|
||||
panic(string(body))
|
||||
}
|
||||
|
||||
var tokenResponse TokenResponse
|
||||
err = json.NewDecoder(resp.Body).Decode(&tokenResponse)
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusBadRequest).SendString(fmt.Sprintf("Error decoding auth server response: %s", err.Error()))
|
||||
fmt.Print("Error decoding auth server response")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
c.Cookie(&fiber.Cookie{
|
||||
|
18
main.go
18
main.go
@ -206,6 +206,7 @@ func addKeys(c *fiber.Ctx) error {
|
||||
);
|
||||
`, &Exists)
|
||||
if err != nil {
|
||||
fmt.Print("Error checking if OpenAI key exists")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@ -217,6 +218,7 @@ func addKeys(c *fiber.Ctx) error {
|
||||
}
|
||||
`, "openai", openaiKey)
|
||||
if err != nil {
|
||||
fmt.Print("Error updating OpenAI key")
|
||||
panic(err)
|
||||
}
|
||||
} else {
|
||||
@ -234,6 +236,7 @@ func addKeys(c *fiber.Ctx) error {
|
||||
)
|
||||
}`, openaiKey)
|
||||
if err != nil {
|
||||
fmt.Print("Error adding OpenAI key")
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
@ -253,6 +256,7 @@ func addKeys(c *fiber.Ctx) error {
|
||||
);
|
||||
`, &Exists)
|
||||
if err != nil {
|
||||
fmt.Print("Error checking if Anthropic key exists")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@ -264,6 +268,7 @@ func addKeys(c *fiber.Ctx) error {
|
||||
}
|
||||
`, anthropicKey)
|
||||
if err != nil {
|
||||
fmt.Print("Error updating Anthropic key")
|
||||
panic(err)
|
||||
}
|
||||
} else {
|
||||
@ -281,6 +286,7 @@ func addKeys(c *fiber.Ctx) error {
|
||||
)
|
||||
}`, anthropicKey)
|
||||
if err != nil {
|
||||
fmt.Print("Error adding Anthropic key")
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
@ -300,6 +306,7 @@ func addKeys(c *fiber.Ctx) error {
|
||||
);
|
||||
`, &Exists)
|
||||
if err != nil {
|
||||
fmt.Print("Error checking if Mistral key exists")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@ -311,6 +318,7 @@ func addKeys(c *fiber.Ctx) error {
|
||||
}
|
||||
`, mistralKey)
|
||||
if err != nil {
|
||||
fmt.Print("Error updating Mistral key")
|
||||
panic(err)
|
||||
}
|
||||
} else {
|
||||
@ -328,6 +336,7 @@ func addKeys(c *fiber.Ctx) error {
|
||||
)
|
||||
}`, mistralKey)
|
||||
if err != nil {
|
||||
fmt.Print("Error adding Mistral key")
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
@ -347,6 +356,7 @@ func addKeys(c *fiber.Ctx) error {
|
||||
);
|
||||
`, &Exists)
|
||||
if err != nil {
|
||||
fmt.Print("Error checking if Groq key exists")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@ -358,6 +368,7 @@ func addKeys(c *fiber.Ctx) error {
|
||||
}
|
||||
`, groqKey)
|
||||
if err != nil {
|
||||
fmt.Print("Error updating Groq key")
|
||||
panic(err)
|
||||
}
|
||||
} else {
|
||||
@ -375,6 +386,7 @@ func addKeys(c *fiber.Ctx) error {
|
||||
)
|
||||
}`, groqKey)
|
||||
if err != nil {
|
||||
fmt.Print("Error adding Groq key")
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
@ -394,6 +406,7 @@ func addKeys(c *fiber.Ctx) error {
|
||||
);
|
||||
`, &Exists)
|
||||
if err != nil {
|
||||
fmt.Print("Error checking if Gooseai key exists")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@ -405,6 +418,7 @@ func addKeys(c *fiber.Ctx) error {
|
||||
}
|
||||
`, gooseaiKey)
|
||||
if err != nil {
|
||||
fmt.Print("Error updating Gooseai key")
|
||||
panic(err)
|
||||
}
|
||||
} else {
|
||||
@ -422,6 +436,7 @@ func addKeys(c *fiber.Ctx) error {
|
||||
)
|
||||
}`, gooseaiKey)
|
||||
if err != nil {
|
||||
fmt.Print("Error adding Gooseai key")
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
@ -441,6 +456,7 @@ func addKeys(c *fiber.Ctx) error {
|
||||
);
|
||||
`, &Exists)
|
||||
if err != nil {
|
||||
fmt.Print("Error checking if Google key exists")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@ -452,6 +468,7 @@ func addKeys(c *fiber.Ctx) error {
|
||||
}
|
||||
`, googleKey)
|
||||
if err != nil {
|
||||
fmt.Print("Error updating Google key")
|
||||
panic(err)
|
||||
}
|
||||
} else {
|
||||
@ -469,6 +486,7 @@ func addKeys(c *fiber.Ctx) error {
|
||||
)
|
||||
}`, googleKey)
|
||||
if err != nil {
|
||||
fmt.Print("Error adding Google key")
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
11
utils.go
11
utils.go
@ -5,6 +5,7 @@ package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"regexp"
|
||||
|
||||
"github.com/yuin/goldmark"
|
||||
@ -19,7 +20,8 @@ func markdownToHTML(markdownText string) string {
|
||||
),
|
||||
)
|
||||
if err := md.Convert([]byte(markdownText), &buf); err != nil {
|
||||
panic(err) // Handle the error appropriately
|
||||
fmt.Print("failed to convert markdown to HTML")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return addCopyButtonsToCode(buf.String())
|
||||
@ -61,6 +63,7 @@ func getExistingKeys() (bool, bool, bool, bool, bool, bool) {
|
||||
);
|
||||
`, &openaiExists)
|
||||
if err != nil {
|
||||
fmt.Print("Error checking if OpenAI key exists")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@ -71,6 +74,7 @@ func getExistingKeys() (bool, bool, bool, bool, bool, bool) {
|
||||
);
|
||||
`, &anthropicExists)
|
||||
if err != nil {
|
||||
fmt.Print("Error checking if Anthropic key exists")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@ -81,6 +85,7 @@ func getExistingKeys() (bool, bool, bool, bool, bool, bool) {
|
||||
);
|
||||
`, &mistralExists)
|
||||
if err != nil {
|
||||
fmt.Print("Error checking if Mistral key exists")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@ -91,6 +96,7 @@ func getExistingKeys() (bool, bool, bool, bool, bool, bool) {
|
||||
);
|
||||
`, &groqExists)
|
||||
if err != nil {
|
||||
fmt.Print("Error checking if Groq key exists")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@ -101,6 +107,7 @@ func getExistingKeys() (bool, bool, bool, bool, bool, bool) {
|
||||
);
|
||||
`, &gooseaiExists)
|
||||
if err != nil {
|
||||
fmt.Print("Error checking if GooseAI key exists")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@ -111,6 +118,7 @@ func getExistingKeys() (bool, bool, bool, bool, bool, bool) {
|
||||
);
|
||||
`, &googleExists)
|
||||
if err != nil {
|
||||
fmt.Print("Error checking if Google key exists")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@ -178,6 +186,7 @@ func GetAvailableModels() []ModelInfo {
|
||||
} FILTER .modelID != 'none' AND .company.name != 'huggingface' AND .company IN global currentUser.setting.keys.company
|
||||
`, &models)
|
||||
if err != nil {
|
||||
fmt.Print("Error getting models")
|
||||
panic(err)
|
||||
}
|
||||
return models
|
||||
|
64
views/partials/logo_animation.html
Normal file
64
views/partials/logo_animation.html
Normal file
@ -0,0 +1,64 @@
|
||||
<style>
|
||||
svg {
|
||||
font-family: 'Russo One', sans-serif;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
svg text {
|
||||
text-transform: uppercase;
|
||||
animation: stroke 7s forwards;
|
||||
/* Play once and use 'forwards' to retain the final state */
|
||||
stroke-width: 2;
|
||||
|
||||
stroke: #000;
|
||||
font-size: 20vw;
|
||||
opacity: 1;
|
||||
/* Ensure the text is fully visible at the start */
|
||||
}
|
||||
|
||||
@keyframes stroke {
|
||||
|
||||
0%,
|
||||
14.3% {
|
||||
fill: #fff;
|
||||
stroke: #000;
|
||||
stroke-dashoffset: 25%;
|
||||
stroke-dasharray: 0 50%;
|
||||
stroke-width: 8;
|
||||
}
|
||||
|
||||
64.3%,
|
||||
71.5% {
|
||||
fill: #fff;
|
||||
stroke: #000;
|
||||
}
|
||||
|
||||
85.7%,
|
||||
100% {
|
||||
fill: #fff;
|
||||
stroke: #000;
|
||||
stroke-dashoffset: -25%;
|
||||
stroke-dasharray: 50% 0;
|
||||
stroke-width: 1;
|
||||
/* Ensure stroke-width is 0 at the end */
|
||||
opacity: 1;
|
||||
/* Full opacity until 85.7% of the animation */
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 0;
|
||||
/* Fade out completely at the very end */
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<svg viewBox="0 0 300 300">
|
||||
<text x="50%" y="50%" dy=".35em" text-anchor="middle">
|
||||
JADE
|
||||
</text>
|
||||
</svg>
|
Loading…
x
Reference in New Issue
Block a user