Skip to content

Commit

Permalink
GH-29: Add first steps for auto updating
Browse files Browse the repository at this point in the history
  • Loading branch information
SetZero committed Jul 2, 2023
1 parent a66d440 commit 55d5fa7
Show file tree
Hide file tree
Showing 10 changed files with 128 additions and 111 deletions.
1 change: 1 addition & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
releaseId: ${{ needs.create-release.outputs.release_id }}
tagName: app-v__VERSION__ # the action automatically replaces \_\_VERSION\_\_ with the app version

- name: Add Windows Executeable
continue-on-error: true
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
"lru-cache": "^10.0.0",
"marked": "^5.0.2",
"marked-highlight": "^2.0.0",
"quill": "1.3.6",
"quill": "^1.3.7",
"react": "^18.2.0",
"react-color": "^2.19.3",
"react-dom": "^18.2.0",
Expand Down
2 changes: 1 addition & 1 deletion src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ patch = "0.7.0"
[dependencies]
serde_json = "1.0"
serde = { version = "1.0", features = ["derive"] }
tauri = { version = "1.4.0", features = ["dialog-open", "global-shortcut-all", "shell-open", "window-close", "window-hide", "window-maximize", "window-minimize", "window-start-dragging", "window-unmaximize", "window-unminimize"] }
tauri = { version = "1.4.0", features = ["dialog-open", "global-shortcut-all", "shell-open", "updater", "window-close", "window-hide", "window-maximize", "window-minimize", "window-start-dragging", "window-unmaximize", "window-unminimize"] }
futures = "0.3.4"
tokio = { version = "1", features = ["full"] }
tokio-native-tls = "0.3.1"
Expand Down
10 changes: 9 additions & 1 deletion src-tauri/tauri.conf.json
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,15 @@
"csp": null
},
"updater": {
"active": false
"active": true,
"endpoints": [
"https://github.com/Fancy-Mumble/FancyMumbleV2/releases/latest/download/latest.json"
],
"dialog": true,
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IDhGNTM4MDI3NDkwN0I1NQpSV1JWZTVCMEFqajFDQTdndmVuRDFmY1NNKy8vM1VWM3NESGNXSHM3MHFtZU45a212Qysvd0x0ZQo=",
"windows": {
"installMode": "passive"
}
},
"windows": [
{
Expand Down
48 changes: 36 additions & 12 deletions src/components/ChatMessageContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,30 +28,54 @@ const ChatMessageContainer = (props: ChatMessageContainerProps) => {
const prevPropsRef = useRef(props);

const scrollToBottom = () => {
//add some minor sleep to make sure the element is rendered
new Promise(r => setTimeout(r, 100)).then(() => {
messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
});
messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
}

useEffect(() => {
if (chatContainer.current) {
let el = chatContainer.current;
if (el.scrollTop < el.scrollHeight - el.clientHeight * 2) {
console.log("User scrolled", el.scrollTop, el.scrollHeight - el.clientHeight);
setUserScrolled(true);
} else {
setUserScrolled(false);
let messages = props.messages;
if (messages.length > 0) {
const isScrolledToBottom = (chatContainer?.current?.scrollHeight || 0) - (chatContainer?.current?.scrollTop || 0) === chatContainer?.current?.clientHeight;

if (isScrolledToBottom) {
messagesEndRef?.current?.scrollIntoView({ behavior: 'smooth' });
}
}
}, [props, prevPropsRef]); // Depend on props
}, [props.messages]);

useEffect(() => {
if (!userScrolled && chatContainer?.current) {
scrollToBottom();
}
}, [props, userScrolled]); // Depend on props and userScrolled

useEffect(() => {
const images = Array.from(document.getElementsByTagName('img'));
let loadedImagesCount = 0;

const handleImageLoad = () => {
loadedImagesCount++;

if (loadedImagesCount === images.length) {
scrollToBottom();
console.log("All images loaded")
}
};

images.forEach((img) => {
if (img.complete) {
handleImageLoad();
} else {
img.addEventListener('load', handleImageLoad);
}
});

return () => {
images.forEach((img) => {
img.removeEventListener('load', handleImageLoad);
});
};
}, [props.messages]);

const userIdToUserMap = useMemo(() => {
if (!userList) return new Map<number, UsersState>();

Expand Down
47 changes: 28 additions & 19 deletions src/components/CurrentUserInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,50 +13,59 @@ import { UpdateableUserState, UsersState } from "../store/features/users/userSli
import "./styles/common.css"
import { useCallback, useEffect, useMemo } from "react";

const selectCurrentUser = (state: RootState) => state.reducer.userInfo.currentUser;

function CurrentUserInfo() {
const dispatch = useDispatch();
const userInfo = useSelector((state: RootState) => state.reducer.userInfo);
const customEqual = (oldUser: UsersState | undefined, newUser: UsersState | undefined) => {
if (oldUser === newUser) return true;
if (oldUser === undefined || newUser === undefined) return false;

useEffect(() => {
console.log("CurrentUserInfo rendered");
});
return (
oldUser.comment === newUser.comment &&
oldUser.self_mute === newUser.self_mute &&
oldUser.self_deaf === newUser.self_deaf &&
oldUser.name === newUser.name &&
oldUser.id === newUser.id
);
};

const userBackground = useMemo(() => getBackgroundFromComment(userInfo.currentUser), [userInfo?.currentUser?.comment]);
function CurrentUserInfo() {
const currentUser = useSelector(selectCurrentUser, customEqual);

const userBackground = useMemo(() => getBackgroundFromComment(currentUser), [currentUser?.comment]);

const updateUserValue = useCallback((update: (currentUser: UsersState, operator: UpdateableUserState) => void) => {
if (userInfo.currentUser) {
let currentUser = userInfo.currentUser;
if (currentUser) {
let currentUserClone: UpdateableUserState = { id: currentUser.id };

update(currentUser, currentUserClone);
invoke('change_user_state', { userState: currentUserClone });
}
}, [userInfo.currentUser]);
}, [currentUser]);

const muteToggleUser = useCallback(() => {
updateUserValue((currentUser, currentUserClone) => currentUserClone.self_mute = !currentUser.self_mute);
}, [userInfo?.currentUser?.self_mute]);
}, [updateUserValue, currentUser?.self_mute]);

const deafToggleUser = useCallback(() => {
updateUserValue((currentUser, currentUserClone) => currentUserClone.self_deaf = !currentUser.self_deaf);
}, [userInfo?.currentUser?.self_deaf]);
}, [updateUserValue, currentUser?.self_deaf]);


const MicrophoneState = useMemo(() => {
if (userInfo.currentUser?.self_mute) {
if (currentUser?.self_mute) {
return (<MicOffIcon className="small_icon" />)
} else {
return (<MicIcon className="small_icon" />)
}
}, [userInfo.currentUser?.self_mute]);
}, [currentUser?.self_mute]);

const VolumeState = useMemo(() => {
if (userInfo.currentUser?.self_deaf) {
if (currentUser?.self_deaf) {
return (<VolumeOffIcon className="small_icon" />)
} else {
return (<VolumeUpIcon className="small_icon" />)
}
}, [userInfo.currentUser?.self_deaf]);
}, [currentUser?.self_deaf]);

return (
<Box style={{
Expand All @@ -72,15 +81,15 @@ function CurrentUserInfo() {
justifyContent: 'center',
}}>
<Avatar
alt={userInfo.currentUser?.name}
src={getProfileImage(userInfo.currentUser?.id || -1)}
alt={currentUser?.name}
src={getProfileImage(currentUser?.id || -1)}
sx={{ width: 48, height: 48 }}
/>
</Box>
<Box sx={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-end' }}>
<Box sx={{ display: 'flex', justifyContent: 'space-between', padding: '2px 10px', flexDirection: 'column', alignItems: 'center', width: '100%', textShadow: '1px 1px #000' }}>
<Box sx={{ display: 'flex', flexDirection: 'row', alignItems: 'center' }}>
<Typography sx={{ fontWeight: 'bold', textShadow: '2px 2px #000' }}>{userInfo.currentUser?.name ?? 'Unknown'}</Typography>
<Typography sx={{ fontWeight: 'bold', textShadow: '2px 2px #000' }}>{currentUser?.name ?? 'Unknown'}</Typography>
<Box onClick={muteToggleUser}>
{MicrophoneState}
</Box>
Expand Down
30 changes: 17 additions & 13 deletions src/components/QuillEditor.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
import React, { useEffect, useRef, useState } from 'react';
import Quill, { TextChangeHandler } from 'quill';

import Quill, {
QuillOptionsStatic,
RangeStatic,
BoundsStatic,
StringMap,
Sources,
} from 'quill';

import 'quill/dist/quill.snow.css';

Quill.register

interface QuillEditorProps {
theme?: 'bubble' | 'snow' | string;
placeholder?: string;
Expand All @@ -26,7 +36,11 @@ export const QuillEditor: React.FC<QuillEditorProps> = ({
bounds = 'document.body',
debug = 'warn',
formats = [],
modules = {},
modules = {
toolbar: {
toolbar: '#toolbar'
}
},
scrollingContainer = undefined,
style = {},
onKeyDown,
Expand All @@ -44,6 +58,7 @@ export const QuillEditor: React.FC<QuillEditorProps> = ({
// This runs once on component mount
useEffect(() => {
if (editorRef.current) {
console.log("editorRef.current", editorRef.current);
quill = new Quill(editorRef.current, {
theme,
placeholder,
Expand Down Expand Up @@ -101,17 +116,6 @@ export const QuillEditor: React.FC<QuillEditorProps> = ({
};
}, []); // Empty array means this effect runs once on mount and clean up on unmount


useEffect(() => {
if (editorRef.current) {


/*if (quillRef) {
quillRef.current = quill;
}*/
}
}, [theme, placeholder, readOnly, bounds, debug, formats, modules, scrollingContainer, quillRef]);

return <div className="quill-wrapper" style={style}>
{toolbarVisible && <div id="toolbar">/* Add toolbar contents here */</div>}
<div ref={editorRef} />
Expand Down
18 changes: 8 additions & 10 deletions src/components/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,32 @@ import LogoutIcon from '@mui/icons-material/Logout';
import InfoIcon from '@mui/icons-material/Info';
import { invoke } from "@tauri-apps/api";
import { useNavigate } from "react-router-dom";
import { useState } from "react";
import { useCallback, useState } from "react";
import { LoadingButton } from "@mui/lab";
import './Sidebar.css'
import ChannelViewer from "./ChannelViewer";
import CurrentUserInfo from "./CurrentUserInfo";
import SettingsIcon from '@mui/icons-material/Settings';
import React from "react";

interface SidebarProps {
}

function Sidebar(props: SidebarProps) {
function Sidebar() {

const navigate = useNavigate();
const [logoutInProgress, setLogoutInProgress] = useState(false);

function triggerLogout(event: React.MouseEvent<HTMLButtonElement, MouseEvent>) {
const triggerLogout = useCallback((event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
event.preventDefault();
setLogoutInProgress(true);
invoke('logout').then(e => {
setLogoutInProgress(false);
navigate("/");
})
}
}, [navigate]); // add dependencies here

function openSettings(event: React.MouseEvent<HTMLButtonElement, MouseEvent>): void {
const openSettings = useCallback((event: React.MouseEvent<HTMLButtonElement, MouseEvent>): void => {
event.preventDefault();
navigate("/settings");
}
}, [navigate]); // add dependencies here

return (
<Box sx={{ height: '100%', display: 'flex', flexDirection: 'column', alignItems: 'center', alignContent: 'center', width: '250px' }} className="sidebar">
Expand All @@ -53,4 +51,4 @@ function Sidebar(props: SidebarProps) {
)
}

export default Sidebar
export default React.memo(Sidebar);
Loading

0 comments on commit 55d5fa7

Please sign in to comment.