Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feat] Home feed configuration #301

Closed
melMass opened this issue May 31, 2023 · 10 comments
Closed

[feat] Home feed configuration #301

melMass opened this issue May 31, 2023 · 10 comments

Comments

@melMass
Copy link
Member

melMass commented May 31, 2023

Describe the problem

I want to choose the first feed I'm welcomed with on teia.art

Describe the solution you'd like

Probably just added there as a local setting for now:
https://teia.art/settings

Alternatives considered

Whatever we might choose for a better option (IPNS was mentioned, "hijacking" the subjkt json etc...)

Additional context

🫶

@caaatisgood
Copy link
Contributor

hey @melMass could you help me understand the options of the first feed we're looking to let users choose? would love to help on this improvement!

@melMass
Copy link
Member Author

melMass commented Jul 26, 2023

Hey @caaatisgood thanks a lot for the proposal, that would be great.
It shouldn't be too hard. I wanted to wait my huge PR before addressing these but I don't think it makes much sense now and I'll have time soonish to address it properly.

For now let's go with option 1: use the browser local storage! Here are the rough steps, don't hesitate to ask questions:

  1. We have this store here that uses Zustand and is automatically tied to local storage, so it should be a matter of adding the proper key for the type and the setter for the store (for instance startFeed or something like that):

    export const useLocalSettings = create<LocalSettingsState>()(
    subscribeWithSelector(
    persist<LocalSettingsState>(
    (set, get) => ({
    ...defaultValues,
    setHasSeenBanner: (has_seen_banner) => set({ has_seen_banner }),
    setTilted: (tilted) => set({ tilted }),
    toggleViewMode: () =>
    set((state) => ({
    viewMode: state.viewMode === 'single' ? 'masonry' : 'single',
    })),
    toggleZen: () => set((state) => ({ zen: !state.zen })),
    setZen: (zen) => set({ zen }),
    toggleTheme: () =>
    set((state) => ({
    theme:
    state.theme === state.themeDark
    ? state.themeLight
    : state.themeDark,
    })),
    setViewMode: (viewMode: ViewMode) => set({ viewMode }),
    setTheme: (theme, apply) => {
    set({ theme })
    if (apply) {
    get().applyTheme(theme)
    }
    },
    applyTheme: (theme) => {
    const root = document.documentElement
    root.setAttribute('data-theme', theme)
    },
    getRpcNode: () => {
    const rpcNode = get().rpcNode
    if (rpcNode === 'custom') {
    const custom = get().customRpcNode
    return custom || rpcNode
    }
    return rpcNode
    },
    setCustomRpcNode: (customRpcNode: string) => {
    if (!customRpcNode) {
    return
    }
    if (!customRpcNode.startsWith('http')) {
    customRpcNode = `https://${customRpcNode}`
    }
    set({ customRpcNode })
    },
    setRpcNode: async (rpcNode) => {
    // const show = useModalStore.getState().show
    set({ rpcNode })
    // show(
    // 'RPC Node Changed',
    // 'Please reload the page for it to take effect.'
    // )
    // await useUserStore.getState().sync({ rpcNode })
    },
    setNsfwFriendly: (nsfwFriendly) => set({ nsfwFriendly }),
    setPhotosensitiveFriendly: (photosensitiveFriendly) =>
    set({ photosensitiveFriendly }),
    }),
    {
    name: 'settings',
    storage: createJSONStorage(() => localStorage), // or sessionStorage?
    version: 2,
    partialize: (state) =>
    Object.fromEntries(
    Object.entries(state).filter(([key]) =>
    Object.keys(defaultValues).includes(key)
    )
    ) as LocalSettingsState,
    onRehydrateStorage: (state) => {
    return (state, error) => {
    if (error) {
    console.error('an error happened during hydration', error)
    }
    }
    },
    migrate: (persistedState: any, version: number) => {
    console.debug('migrating settings from version', version)
    // here we can check against the version of the storage and makes updates accordingly.
    // useful to rename keys or restore value, we will first use it for the banner updates.
    persistedState.has_seen_banner = false
    return persistedState
    },
    }
    )
    )
    )

  2. Then to actually add an UI for it you can add a Select component in the Settings.jsx file (check the rpc line to see how to use it):
    https://github.com/teia-community/teia-ui/blob/main/src/pages/config/Settings.jsx

  3. Finally to actually use the setting's value as the actual start feed, you will need to edit this line:

    <Route index element={<RecentSalesFeed />} />
    with the store value (you will probably need a map between string -> feedComponent, a bit like this but with the names as key and the component as value

@caaatisgood
Copy link
Contributor

Hey @melMass thank you so much for the walkthrough. Very very useful! Just wanted to make sure that I understand the whole user flow and edge cases here.

What we want to achieve

Give users the option to choose their preferred default feed (or startFeed). The list of options is here.

How we could achieve

Follow 1, 2 you mentioned above. And then, this is the main part I'd like to confirm, in <RecentSalesFeed />, we'd like to:

  • Read the startFeed and redirect to it. ie if I chose "New OBJKTs" as my startFeed, I should be redirected to /feed/newobjkts when visiting the /.

If the above is the case. Then we'll also need to make sure the users are able to still navigate to / from the startFeed page. Essentially skipping the startFeed redirect in this particular case. The whole flow would look like this:

  • The user starts a new session on Teia, starting from /
    • We check if the user has startFeed state, if
      • truthy -> redirect them to startFeed page
      • falsy -> do nothing (stays at /)
  • (now let's assume that the user has startFeed "New OBJKTs") The user gets redirected to /feed/newobjkts
  • Then the user clicks on the dropdown attempting to navigate back to /
  • The user then gets redirected back to /
    • In this case, the user should stay at / regardless of their startFeed.

Okay if we're still on the same page til this point. I suggest that we keep a boolean state such as hasVisitedRootPage to make sure user stays on / if they are navigated from other feeds. The code on / would look something like this

useEffect(() => {
  // note that states are all from `Zustand`
  if (hasVisitedRootPage) {
    return
  }
  // we set `hasVisitedRootPage` to `true` here
  if (!startFeed || startFeed === '/') {
    return
  }
  navigate(startFeed)
}, [/* ... */])

This would make sure that only the first / visit in a session will we check user's startFeed and redirect them to it. Afterward they could jump back on / or any other feeds freely without any startFeed checks.

LMK if it makes sense :)

@melMass
Copy link
Member Author

melMass commented Jul 27, 2023

Almost but I don't think redirection is a good idea, and it could be much simpler overall.

This line here:

<Route index element={<RecentSalesFeed />} />

Uses the index key of the react-router, that's where (in place of the current RecentSalesFeed- you will put the evaluated map value from the user settings (this is basically /), one thing that I did not think about in my previous message is that you will also need to make a proper route for RecentSales, but besides that there shouldn't be more steps

@caaatisgood
Copy link
Contributor

ah right, utilizing the index key of react-router makes so much more sense. think i'm half way through it and will likely be submitting a pr in 1-3 days.

@caaatisgood
Copy link
Contributor

Hey @melMass, apologies for the delay. Changes are nearly done. But I'm stuck on adding a commit with this pretty-quick-related error:

🔍  Finding changed files since git revision a43083cc.
/Users/xxxxx/.npm/_npx/15f9efe159c89f49/node_modules/pretty-quick/dist/isSupportedExtension.js:12
  ..._prettier.resolveConfig.sync(file, {
                             ^

TypeError: _prettier.resolveConfig.sync is not a function
    at /Users/xxxxx/.npm/_npx/15f9efe159c89f49/node_modules/pretty-quick/dist/isSupportedExtension.js:12:30
    at Array.filter (<anonymous>)
    at _default (/Users/xxxxx/.npm/_npx/15f9efe159c89f49/node_modules/pretty-quick/dist/index.js:53:157)
    at Object.<anonymous> (/Users/xxxxx/.npm/_npx/15f9efe159c89f49/node_modules/pretty-quick/bin/pretty-quick.js:17:27)
    at Module._compile (node:internal/modules/cjs/loader:1198:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1252:10)
    at Module.load (node:internal/modules/cjs/loader:1076:32)
    at Function.Module._load (node:internal/modules/cjs/loader:911:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
    at node:internal/main/run_main_module:22:47
husky - pre-commit hook exited with code 1 (error)

I've tried to install eslint-plugin-prettier@^4.0.0 (following this) but didn't work. Do you have an idea what might be the problem? I'm on Node.js v16.20.1 btw.

@caaatisgood
Copy link
Contributor

quick demo on what i got so far

Kapture.2023-08-08.at.22.26.18.mp4

@melMass
Copy link
Member Author

melMass commented Aug 8, 2023

Hey @melMass, apologies for the delay. Changes are nearly done. But I'm stuck on adding a commit with this pretty-quick

No pressure at all, take the time you need!
Yes it seems that Javier had the issue too on his end, I can't reproduce on either mac or windows, but I did find many issues about it, under the hood it just calls prettier, so I switched to lint-staged, you can apply the changes from here:
ee5711f (#316)

We will then resolve the merge from you PR easily, but it should let you commit and format the code properly

caaatisgood added a commit to caaatisgood/teia-ui that referenced this issue Aug 23, 2023
Make home feed customizable via configs teia-community#301
@caaatisgood
Copy link
Contributor

Thanks @melMass! It worked, just raised a PR #325

@melMass
Copy link
Member Author

melMass commented Sep 18, 2023

And merged! Thanks again @caaatisgood

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants