Skip to content

Commit

Permalink
features/share conversation (#22)
Browse files Browse the repository at this point in the history
  • Loading branch information
huyenNguyen20 authored Jun 17, 2023
1 parent 30fa60e commit d487395
Show file tree
Hide file tree
Showing 6 changed files with 165 additions and 19 deletions.
15 changes: 2 additions & 13 deletions chat.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@
import streamlit as st
from firestore_utils import clear_user_history
from utils import get_cid_from_session
import base64
import json
from debugger import debugger
from google_utils import sign_out_google, decode_token_from_params

from dotenv import load_dotenv
Expand Down Expand Up @@ -157,14 +156,4 @@ def main():

if __name__ == "__main__":
main()

with st.expander("Debug"):
col1, col2 = st.columns(2)
col1.write("Session State (w/o conversation, user_info))")
# exclude conversation from session_state
session_state = {
k: v for k, v in st.session_state.items() if k != "conversation"
}
col1.write(session_state)
col2.write("Conversation")
col2.write(st.session_state.get("conversation"))
debugger()
30 changes: 30 additions & 0 deletions custom_js.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import streamlit as st
import streamlit.components.v1 as components
import time


def delayed_execution(delay, function):
time.sleep(delay)
function()


def render_copy_shared_convo_link(shared_cid=None):
model = st.session_state.get("model", "gpt-3.5-turbo")

if shared_cid is not None:
js = f"""
<script>
window.parent.navigator.permissions.query({{ name: "write-on-clipboard" }}).then((result) => {{
if (result.state == "granted" || result.state == "prompt") {{
alert("Write access granted!");
}}
}});
const shareUrl = window.parent.location.origin + "/share" + "?cid={shared_cid}&model={model}"
window.parent.navigator.clipboard.writeText(shareUrl).then(() => {{
window.parent.alert("Copied to clipboard: " + shareUrl);
}});
</script>
"""

components.html(js, width=0, height=0)
14 changes: 14 additions & 0 deletions debugger.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import streamlit as st


def debugger():
with st.expander("Debug"):
col1, col2 = st.columns(2)
col1.write("Session State (w/o conversation, user_info))")
# exclude conversation from session_state
session_state = {
k: v for k, v in st.session_state.items() if k != "conversation"
}
col1.write(session_state)
col2.write("Conversation")
col2.write(st.session_state.get("conversation"))
12 changes: 11 additions & 1 deletion google_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,17 @@ def auth_with_google(st):
token = result["token"]
st.session_state["token"] = token
base64_token = dict_to_base64(token)
st.experimental_set_query_params(token=base64_token)
other_queries = st.experimental_get_query_params()
if "cid" in other_queries and "model" in other_queries:
cid = other_queries["cid"][0]
model = other_queries["model"][0]
st.experimental_set_query_params(
token=base64_token,
cid=cid,
model=model,
)
else:
st.experimental_set_query_params(token=base64_token)
sign_in_holder.empty()
else:
token = st.session_state["token"]
Expand Down
86 changes: 86 additions & 0 deletions pages/share.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import streamlit as st
from firestore_utils import load_conversation_by_id
from render_conversation import render_conversation
from render_auth import render_auth
from render_chat_form import render_chat_stream, save_messages_to_firestore
from google_utils import decode_token_from_params
from render_body import render_body
from debugger import debugger
import time


def is_authenticated(st):
if "token" not in st.session_state:
return False
else:
token = st.session_state["token"]
expires_at = token.get("expires_at")
if expires_at and expires_at < time.time():
return False
else:
return True


def controller():
st.session_state["conversation_expanded"] = True

token_dict = decode_token_from_params(st, "token")
if token_dict:
st.session_state["token"] = token_dict


def show_readonly_shared_conversation(st, cid, model):
# get the conversation from the cid
conversation = load_conversation_by_id(cid).to_dict()
st.title(conversation["title"])
# show messages for the conversation
render_conversation(st, conversation)

continue_convo_holder = st.empty()
continue_convo_btn = continue_convo_holder.button("Continue the chat")
if continue_convo_btn:
if not is_authenticated(st):
continue_convo_holder.write(
"You must be logged in to continue the conversation"
)
else:
continue_convo_holder.empty()
with st.container():
# Save conversation to firestore
st.session_state["messages"] = conversation["messages"]
st.session_state["model"] = model
st.session_state["conversation"] = conversation
# save the state
st.session_state[f"edit_shared_conversation_{cid}"] = True
# rerun the app
st.experimental_rerun()


def main():
st.set_page_config(
page_title="PushGPT Share", page_icon=":robot_face:", layout="wide"
)
controller()
try:
# get query cid from the queryStr
queryStr = st.experimental_get_query_params()
cid = queryStr["cid"][0]
model = queryStr["model"][0]

# render auth
render_auth(st)

# render body
isEdit = st.session_state.get(f"edit_shared_conversation_{cid}", False)
if not isEdit:
show_readonly_shared_conversation(st, cid, model)
else:
render_body(st)

except Exception as e:
st.title("No conversation found")


if __name__ == "__main__":
main()
debugger()
27 changes: 22 additions & 5 deletions utils.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from firestore_utils import delete_convo, edit_convo
from custom_js import render_copy_shared_convo_link


def link_button(st, text, path):
Expand Down Expand Up @@ -40,7 +41,7 @@ def button_row(st, cid, conversation, selected=False):
container = st.sidebar.container()

with container:
col1, col2, col3 = st.columns([6, 1, 1], gap="small")
col1, col2, col3, col4 = st.columns([6, 1, 1, 1], gap="small")

with col1:
is_edit = st.session_state.get(f"edit_convo_button_{cid}", False)
Expand Down Expand Up @@ -71,14 +72,23 @@ def button_row(st, cid, conversation, selected=False):
st.experimental_rerun()

with col2:
st.button(
":outbox_tray:",
key=f"share_convo_button_{cid}",
disabled=False,
use_container_width=True,
on_click=lambda: render_copy_shared_convo_link(cid),
)

with col3:
st.button(
":pencil2:",
key=f"edit_convo_button_{cid}",
disabled=selected,
use_container_width=True,
)

with col3:
with col4:
delete_button = st.button(
":wastebasket:",
key=f"delete_convo_button_{cid}",
Expand All @@ -104,7 +114,7 @@ def button_row(st, cid, conversation, selected=False):
div.css-ocqkz7.e1tzin5v3 .stButton > button:hover {
color: #6e6e6e;
}
div.css-ocqkz7.e1tzin5v3 [data-testid="column"]:first-child .stButton > button {
div.css-ocqkz7.e1tzin5v3 [data-testid="column"]:first-child .stButton > button{
justify-content: flex-start;
width: 220px;
overflow: hidden;
Expand All @@ -117,12 +127,19 @@ def button_row(st, cid, conversation, selected=False):
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
div.css-ocqkz7.e1tzin5v3 [data-testid="column"]:nth-child(2) .stButton{
div.css-ocqkz7.e1tzin5v3 [data-testid="column"]:nth-child(2) .stButton,
div.css-ocqkz7.e1tzin5v3 [data-testid="column"]:nth-child(3) .stButton{
position: relative;
}
div.css-ocqkz7.e1tzin5v3 [data-testid="column"]:nth-child(2) .stButton > button {
div.css-ocqkz7.e1tzin5v3 [data-testid="column"]:nth-child(2) .stButton > button,
div.css-ocqkz7.e1tzin5v3 [data-testid="column"]:nth-child(3) .stButton > button {
position: absolute;
top: 0;
}
div.css-ocqkz7.e1tzin5v3 [data-testid="column"]:nth-child(2) .stButton > button{
right: -23px;
}
div.css-ocqkz7.e1tzin5v3 [data-testid="column"]:nth-child(3) .stButton > button{
right: -15px;
}
</style>
Expand Down

0 comments on commit d487395

Please sign in to comment.