这是indexloc提供的服务,不要输入任何密码
Skip to content

Conversation

@shatfield4
Copy link
Collaborator

• Create PFP user menu and hooks to render the PFP everywhere
• Update backend to handle PFP uploads
• Update Prisma schema to support PFPs
• Create context and wrappers for PFP and logo since they function very similarly

@shatfield4 shatfield4 marked this pull request as ready for review December 4, 2023 20:58
@review-agent-prime
Copy link

frontend/src/pages/OnboardingFlow/OnboardingModal/Steps/PasswordProtection/index.jsx

Instead of using alert for error handling, it would be better to use a more user-friendly way to display errors. This could be a modal or a toast notification. This would improve the user experience and make the application more robust.
Create Issue
See the diff
Checkout the fix

    // Instead of this
    if (error) {
      alert(`Failed to set password: ${error}`, "error");
      return;
    }

    // Do something like this
    if (error) {
      displayError(`Failed to set password: ${error}`);
      return;
    }
git fetch origin && git checkout -b ReviewBot/Impro-jvb5cj6 origin/ReviewBot/Impro-jvb5cj6

Instead of using localStorage for storing the user's token, consider using sessionStorage. This would improve the security of the application as the data stored in sessionStorage gets cleared when the page session ends.
Create Issue
See the diff
Checkout the fix

    // Instead of this
    window.localStorage.setItem(AUTH_TOKEN, token);

    // Do something like this
    window.sessionStorage.setItem(AUTH_TOKEN, token);
git fetch origin && git checkout -b ReviewBot/Impro-ih16ajh origin/ReviewBot/Impro-ih16ajh

Consider using a more descriptive name for the setNewPassword function. This would make the code more readable and easier to understand.
Create Issue
See the diff
Checkout the fix

    // Instead of this
    const setNewPassword = (e) => setPassword(e.target.value);

    // Do something like this
    const updatePassword = (e) => setPassword(e.target.value);
git fetch origin && git checkout -b ReviewBot/Impro-5lndsf5 origin/ReviewBot/Impro-5lndsf5

frontend/src/components/WorkspaceChat/ChatContainer/ChatHistory/index.jsx

Instead of using the scrollTo method to scroll to the bottom of the chat history, you can directly set the scrollTop property of the chat history element to its scrollHeight. This approach is more performant as it doesn't involve smooth scrolling, which can be computationally expensive.
Create Issue
See the diff
Checkout the fix

    const scrollToBottom = () => {
      if (chatHistoryRef.current) {
        chatHistoryRef.current.scrollTop = chatHistoryRef.current.scrollHeight;
      }
    };
git fetch origin && git checkout -b ReviewBot/Impro-m3f6qhh origin/ReviewBot/Impro-m3f6qhh

frontend/src/pages/OnboardingFlow/OnboardingModal/Steps/LLMSelection/index.jsx

The variable name _settings is not very descriptive. Consider renaming it to something more meaningful, such as systemSettings.
Create Issue
See the diff
Checkout the fix

    async function fetchKeys() {
      const systemSettings = await System.keys();
      setSettings(systemSettings);
      setLLMChoice(systemSettings?.LLMProvider);
      setLoading(false);
    }
git fetch origin && git checkout -b ReviewBot/Impro-2bl3421 origin/ReviewBot/Impro-2bl3421

frontend/src/pages/OnboardingFlow/OnboardingModal/Steps/AppearanceSetup/index.jsx

The variable name _initLogo is not very descriptive. Consider renaming it to something more meaningful, such as initialLogo.
Create Issue
See the diff
Checkout the fix

    const { logo: initialLogo, setLogo: _setLogo } = useLogo();
git fetch origin && git checkout -b ReviewBot/Impro-28sbl8t origin/ReviewBot/Impro-28sbl8t

frontend/src/components/UserMenu/index.jsx

It's generally not a good practice to send passwords in plaintext over the network. Consider implementing a more secure way of handling password updates, such as hashing the password on the client side before sending it to the server.
Create Issue
See the diff
Checkout the fix

    import bcrypt from 'bcryptjs';

    // Hash password before sending to server
    const salt = bcrypt.genSaltSync(10);
    const hashedPassword = bcrypt.hashSync(data.password, salt);
    data.password = hashedPassword;
git fetch origin && git checkout -b ReviewBot/The-c-zjqlt48 origin/ReviewBot/The-c-zjqlt48

Consider caching the user's profile picture URL in the local storage or in a state management library like Redux. This way, you don't have to fetch the profile picture every time the user navigates to a different page or refreshes the page.
Create Issue
See the diff
Checkout the fix

    // Save profile picture URL to local storage
    localStorage.setItem('pfp', pfpUrl);
git fetch origin && git checkout -b ReviewBot/The-c-057klsj origin/ReviewBot/The-c-057klsj

frontend/src/pages/OnboardingFlow/OnboardingModal/Steps/VectorDatabaseConnection/index.jsx

Instead of using the alert function to display the error message, consider using a more user-friendly approach such as a toast notification or a modal. This will improve the user experience and make the application more interactive.
Create Issue
See the diff
Checkout the fix

    if (error) {
      // Use a toast notification or a modal to display the error message
      toast.error(`Failed to save settings: ${error}`);
      return;
    }
git fetch origin && git checkout -b ReviewBot/Impro-u8repg3 origin/ReviewBot/Impro-u8repg3

Consider wrapping the fetchKeys function inside a useCallback hook. This will prevent unnecessary re-renders and improve the performance of your application.
Create Issue
See the diff
Checkout the fix

    const fetchKeys = useCallback(async () => {
      const _settings = await System.keys();
      setSettings(_settings);
      setVectorDB(_settings?.VectorDB || "lancedb");
      setLoading(false);
    }, []);

    useEffect(() => {
      if (currentStep === "vector_database") {
        fetchKeys();
      }
    }, [currentStep, fetchKeys]);
git fetch origin && git checkout -b ReviewBot/Impro-ewecma8 origin/ReviewBot/Impro-ewecma8

frontend/src/models/system.js

It's a good practice to provide more descriptive error messages and to use console.error for error logging instead of console.log. This will help in debugging and understanding the error context better.
Create Issue
See the diff
Checkout the fix

    // In frontend/src/models/system.js
    // Replace console.log with console.error in catch blocks
    .catch((e) => {
        console.error(e);
        return { success: false, error: e.message };
      });
git fetch origin && git checkout -b ReviewBot/Impro-p6kpksr origin/ReviewBot/Impro-p6kpksr

server/utils/files/pfp.js

In server/utils/files/pfp.js, fs.readFileSync is used which is a blocking operation. It's better to use asynchronous file operations like fs.readFile to improve performance.
Create Issue
See the diff
Checkout the fix

    // In server/utils/files/pfp.js
    // Replace fs.readFileSync with fs.readFile
    fs.readFile(pfpPath, (err, data) => {
      if (err) throw err;
      return {
        buffer: data,
        size: data.length,
        mime: getType(pfpPath),
      };
    });
git fetch origin && git checkout -b ReviewBot/Impro-pxxm18l origin/ReviewBot/Impro-pxxm18l

server/prisma/migrations/20231129012019_add/migration.sql

It's a good practice to add a NOT NULL constraint to the columns where the value is mandatory. This will prevent any null values from being inserted into the "pfpFilename" column, ensuring data integrity.
Create Issue
See the diff
Checkout the fix

    ALTER TABLE "users" ADD COLUMN "pfpFilename" TEXT NOT NULL;
git fetch origin && git checkout -b ReviewBot/Addin-ehozgjp origin/ReviewBot/Addin-ehozgjp

It's a good practice to add a default value to the columns where the value is mandatory but not provided during the insertion. This will ensure that there is always a value in the "pfpFilename" column, improving data consistency.
Create Issue
See the diff
Checkout the fix

    ALTER TABLE "users" ADD COLUMN "pfpFilename" TEXT NOT NULL DEFAULT 'default.png';
git fetch origin && git checkout -b ReviewBot/Addin-raftvsg origin/ReviewBot/Addin-raftvsg

server/prisma/schema.prisma

It would be beneficial to add a comment next to the 'pfpFilename' field to describe its purpose. This will improve the readability of the code and make it easier for other developers to understand the purpose of this field.
Create Issue
See the diff
Checkout the fix

    pfpFilename     String?           // Profile picture filename
git fetch origin && git checkout -b ReviewBot/Addin-951icl3 origin/ReviewBot/Addin-951icl3

It would be beneficial to add a default value to the 'pfpFilename' field. This will prevent null values from being stored in the database, which can lead to performance issues and potential errors when retrieving this field.
Create Issue
See the diff
Checkout the fix

    pfpFilename     String?           @default("default.jpg")
git fetch origin && git checkout -b ReviewBot/Addin-omh581i origin/ReviewBot/Addin-omh581i

Comment on lines 39 to 46
const scrollToBottom = () => {
if (chatHistoryRef.current) {
chatHistoryRef.current.scrollTo({
top: chatHistoryRef.current.scrollHeight,
behavior: "smooth",
});
}
};

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replaced the scrollTo method with direct assignment of scrollTop to scrollHeight for better performance.

Suggested change
const scrollToBottom = () => {
if (chatHistoryRef.current) {
chatHistoryRef.current.scrollTo({
top: chatHistoryRef.current.scrollHeight,
behavior: "smooth",
});
}
};
const scrollToBottom = () => {
if (chatHistoryRef.current) {
chatHistoryRef.current.scrollTop = chatHistoryRef.current.scrollHeight;
}
};

Comment on lines 167 to 190
const handleUpdate = async (e) => {
e.preventDefault();

const data = {};
const form = new FormData(e.target);
for (var [key, value] of form.entries()) {
if (!value || value === null) continue;
data[key] = value;
}

console.log(data);
const { success, error } = await System.updateUser(data);

if (success) {
let storedUser = JSON.parse(localStorage.getItem(AUTH_USER));

if (storedUser) {
storedUser.username = data.username;
localStorage.setItem(AUTH_USER, JSON.stringify(storedUser));
}
window.location.reload();
} else {
showToast(`Failed to update user: ${error}`, "error");
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hash the user's password before sending it to the server to enhance security.

Suggested change
const handleUpdate = async (e) => {
e.preventDefault();
const data = {};
const form = new FormData(e.target);
for (var [key, value] of form.entries()) {
if (!value || value === null) continue;
data[key] = value;
}
console.log(data);
const { success, error } = await System.updateUser(data);
if (success) {
let storedUser = JSON.parse(localStorage.getItem(AUTH_USER));
if (storedUser) {
storedUser.username = data.username;
localStorage.setItem(AUTH_USER, JSON.stringify(storedUser));
}
window.location.reload();
} else {
showToast(`Failed to update user: ${error}`, "error");
}
import bcrypt from 'bcryptjs';
// Hash password before sending to server
const salt = bcrypt.genSaltSync(10);
const hashedPassword = bcrypt.hashSync(data.password, salt);
data.password = hashedPassword;

Comment on lines +138 to +154
const handleFileUpload = async (event) => {
const file = event.target.files[0];
if (!file) return false;

const formData = new FormData();
formData.append("file", file);
const { success, error } = await System.uploadPfp(formData);
if (!success) {
showToast(`Failed to upload profile picture: ${error}`, "error");
return;
}

const pfpUrl = await System.fetchPfp(user.id);
setPfp(pfpUrl);

showToast("Profile picture uploaded successfully.", "success");
};

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The profile picture URL is now being saved to local storage after being fetched. This will improve performance by reducing the number of network requests.

Suggested change
const handleFileUpload = async (event) => {
const file = event.target.files[0];
if (!file) return false;
const formData = new FormData();
formData.append("file", file);
const { success, error } = await System.uploadPfp(formData);
if (!success) {
showToast(`Failed to upload profile picture: ${error}`, "error");
return;
}
const pfpUrl = await System.fetchPfp(user.id);
setPfp(pfpUrl);
showToast("Profile picture uploaded successfully.", "success");
};
const handleFileUpload = async (event) => {
const file = event.target.files[0];
if (!file) return false;
const formData = new FormData();
formData.append("file", file);
const { success, error } = await System.uploadPfp(formData);
if (!success) {
showToast(`Failed to upload profile picture: ${error}`, "error");
return;
}
const pfpUrl = await System.fetchPfp(user.id);
setPfp(pfpUrl);
// Save profile picture URL to local storage
localStorage.setItem('pfp', pfpUrl);
showToast("Profile picture uploaded successfully.", "success");
};

@shatfield4 shatfield4 self-assigned this Dec 4, 2023
@timothycarambat
Copy link
Member

@shatfield4 can you rebase with master and solve merge conflicts?

@shatfield4
Copy link
Collaborator Author

@shatfield4 can you rebase with master and solve merge conflicts?

Resolved

@timothycarambat timothycarambat merged commit fcb591d into master Dec 7, 2023
@timothycarambat timothycarambat deleted the user-pfp-and-logo-context branch December 7, 2023 22:11
cabwds pushed a commit to cabwds/anything-llm that referenced this pull request Jul 3, 2025
* fix sizing of onboarding modals & lint

* fix extra scrolling on mobile onboarding flow

* added message to use desktop for onboarding

* linting

* add arrow to scroll to bottom (debounced) and fix chat scrolling to always scroll to very bottom on message history change

* fix for empty chat

* change mobile alert copy

* WIP adding PFP upload support

* WIP pfp for users

* edit account menu complete with change username/password and upload profile picture

* add pfp context to update all instances of usePfp hook on update

* linting

* add context for logo change to immediately update logo

* fix div with bullet points to use list-disc instead

* fix: small changes

* update multer file storage locations

* fix: use STORAGE_DIR for filepathing

---------

Co-authored-by: timothycarambat <rambat1010@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants