-
-
Notifications
You must be signed in to change notification settings - Fork 615
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: Public Recipe Browser #2525
feat: Public Recipe Browser #2525
Conversation
I'm just going to do the cookbook stuff now ¯\_(ツ)_/¯ I also found a few small bugs |
I created a new layout called "explore" which keeps the app sidebar, but removes the auth middleware (so you can stay logged-out). The sidebar is currently limited to only cookbooks, but that can be changed as soon as we make explore-friendly tag/category/tool pages: To get this to work I had to move around some of the layout components (I created a "DefaultLayout" component and moved the header, sidebar, etc. into the "LayoutParts" directory). I also updated the cookbook store, added an explore cookbook API, etc. (same as everything else above) I noticed during testing that we're getting an infinite loop of requests on these cookbook pages, but I confirmed this happens in nightly too so it's not a new bug: It's probably related to #2195 |
b61c718
to
ae57a24
Compare
Well this is an awesome work and hope it'll be added in the next version of Mealie. Just to make sure I understand correctly, there's currently no way of sharing a cookbook even though the interface says so? I can only get public links for single recipes atm. |
With this change cookbooks will have public links (I didn't add a "copy link" button, but you can navigate to them through the public browser). Basically anything accessible via the new general explore page doesn't require a login |
I'm running nightly, and I cannot see this change? |
Are you using the old docker hub image? Check out the new docs with the GitHub image: |
was this never included in a release? |
i have seen that but i am still having problems.
what am i missing? |
That is expected behavior, recipes are not shared between groups. Groups are fully isolated instances. To view the recipes of another group, you need to navigate to that group's URL. Every group has a unique URL. |
It would be nice to have a page within mealie to quickly browse between groups given users have permission to view those groups. I for one use groups to separate my recipes from my friends. But I would still like to be able to go to my friends recipes and comment on them / be able to show that I used their recipe in my timeline. It'd be nice to use the timeline as an internal social network to mealie to see what we are all cooking together. |
What type of PR is this?
(REQUIRED)
What this PR does / why we need it:
(REQUIRED)
This PR adds a public recipe browser, similar to the one in 0.5.x.
With this PR, we are ALMOST at feature parity with the old version of Mealie. Cookbooks are still not implementedJK we're at full parity now that cookbooks are implemented.Here's what it looks like:
![image](https://private-user-images.githubusercontent.com/71845777/263505763-b23c0e19-f4ca-4d9a-84b7-3fc60c9c4e18.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjExNDE0NTIsIm5iZiI6MTcyMTE0MTE1MiwicGF0aCI6Ii83MTg0NTc3Ny8yNjM1MDU3NjMtYjIzYzBlMTktZjRjYS00ZDlhLTg0YjctM2ZjNjBjOWM0ZTE4LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA3MTYlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwNzE2VDE0NDU1MlomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTAxYmQ3OWE0ZDNmY2ZhZDdjMDZmOTE5MDUyODFjMzI5Nzc2ZjBkZjQ4OWM0NmUyNDA0NjBlNTI1NTliZWY3NjgmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.NZSPUag0wruvgVOCdWvYrqfYubOTM2ZgoNk3M-bssSg)
Looks identical to the logged-in one,
minus the sidebar(this has been re-added, see below) and stuff in the header (just like the existing public recipe page). This PR aims to accomplish the following goals:To accomplish the recipe browser, several changes were made to both the backend and the frontend.
Backend
The backend changes were pretty minimal. I refactored the existing explore recipe route to inherit from a new
BasePublicExploreController
, which basically just injects the group into the controller using the slug from the path (and if it's missing or the group is missing/private, throw a 404):The rest of the work was pretty much copying the normal logged-in user
get
andget_all
routes into the new public explore controller. I'm not a fan of how I had to do some copy-pasting, but I couldn't for the life of me get separate routes to work (with different FastAPI routers) without the copy paste. It's pretty minimal, at least.Also, plenty of tests to make sure things are public/private as expected.
Frontend
After this PR I feel like I actually understand JS and TS now. I probably don't, but hey, let me have this. I had to make changes to the API clients, the organizer stores, and the rendered components/pages.
API Clients
I created a new set of base clients that are a smaller subset of the existing ones:
BaseCRUDAPIReadOnly
is the CRUD API, but only theget
andgetAll
methods (which makes it more of an R than a CRUD, but oh well)PublicRecipeApi
,PublicFoodsApi
, etc) to call the new backend explore APIsExploreApi
implements the new public APIsPublicExploreApi
extendsPublicApi
which requires agroupSlug
and grants access to theExploreApi
Importantly, the
ExploreApi
matches the signature of the existingUserApi
, which comes into play with the new...Organizer Stores
The organizer stores (e.g.
useFoodStore
,useTagStore
, ...) use the user API, and use theuseStoreActions
constructor. I created public replacements for these (usePublicExploreApi
,usePublicStoreActions
, ...) which only implement a subset of these (theget
andgetAll
). Since the signatures otherwise match, they work as drop-in replacements for the user API, which allows magic like this:Similarly, I modified
useLazyRecipes
:Since all of the modified components/pages only use
get
andgetAll
APIs, the drop-in works without any other changes.Pages/Components
Lastly, I had to update how the main page and some of the components work. The main page just wraps the new
RecipeExplorerPage
component (which is pretty much cut-paste of the home page, but dropped into a component). This is similar to how theRecipePage
component works.I tweaked a few components to reference the correct URLs (e.g. the App Bar needs to bring you to the explore home, not the logged-in home) and to prevent going to logged-in-user-only pages (e.g. I disabled clicking on categories and tags when not logged-in). I also removed most of the context menu items (and hid the context menu from the main explore page, since it's empty):
![image](https://private-user-images.githubusercontent.com/71845777/263506253-33b7ff84-e090-40e7-a1f9-0b89fc839d77.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjExNDE0NTIsIm5iZiI6MTcyMTE0MTE1MiwicGF0aCI6Ii83MTg0NTc3Ny8yNjM1MDYyNTMtMzNiN2ZmODQtZTA5MC00MGU3LWExZjktMGI4OWZjODM5ZDc3LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA3MTYlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwNzE2VDE0NDU1MlomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTFlMjM0YmU5ZWNiODcwZGIxYzY0MTQxZmVlNDBkYTk0MmUyMDMyY2JkODU5Y2U3NzBhNzg4NjE2NGU5ZjFlY2YmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0._L69d48WUMoHlZpzYSc2vvyn0PZl7yLWVNUOcem9mrc)
![image](https://private-user-images.githubusercontent.com/71845777/263506258-d96a088e-d2fa-448c-99ac-8cac21bc5ca3.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjExNDE0NTIsIm5iZiI6MTcyMTE0MTE1MiwicGF0aCI6Ii83MTg0NTc3Ny8yNjM1MDYyNTgtZDk2YTA4OGUtZDJmYS00NDhjLTk5YWMtOGNhYzIxYmM1Y2EzLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA3MTYlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwNzE2VDE0NDU1MlomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTZjYThiZjIzOTdhMDQxZDE5ZTUyNWZkNGFlMzM2ZGM1YTA3ZWJhM2M5NjU1OTRiNzRhMjIyNjNjZTk2MTQyMWImWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.CNt6gTE6QGWd3PTN1laezy7npAhlexCInOFoZ9bJHW4)
That's pretty much it. Otherwise, since we're using mostly drop-in replacements, everything else still works, like searches:
![image](https://private-user-images.githubusercontent.com/71845777/263506291-935932aa-ea5e-456b-8bab-e1fd739a1e78.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjExNDE0NTIsIm5iZiI6MTcyMTE0MTE1MiwicGF0aCI6Ii83MTg0NTc3Ny8yNjM1MDYyOTEtOTM1OTMyYWEtZWE1ZS00NTZiLThiYWItZTFmZDczOWExZTc4LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA3MTYlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwNzE2VDE0NDU1MlomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWUyNzdiYTdjZWExNDZiYmMzYjY4YTIyMmJkMTM2MDVmYjRjN2MwZDI0YTQzNTM2Zjk1YTViY2ZkNDFlYmU2NTYmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.iIln1Hh6w3TSQPmmPMIFy-MfvN72bZnmWp8-Sqf5jVE)
Oh, and I added the group explore link to the user profile page:
![image](https://private-user-images.githubusercontent.com/71845777/263506363-1a119172-e42e-4252-a985-80cececbccb3.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjExNDE0NTIsIm5iZiI6MTcyMTE0MTE1MiwicGF0aCI6Ii83MTg0NTc3Ny8yNjM1MDYzNjMtMWExMTkxNzItZTQyZS00MjUyLWE5ODUtODBjZWNlY2JjY2IzLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA3MTYlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwNzE2VDE0NDU1MlomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTI0YWNiM2M4MjViMjExMTU3YTMxMDgxNTcyZjIyZGMxOWQyMGQwY2UyM2U1OWM5OWQ3M2NmYWI5MzY0M2RmMjUmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.ZGzTStHpR_co5-KOqO1E6tFHVJ_Et2pzGSGhQ2fq1CM)
![image](https://private-user-images.githubusercontent.com/71845777/263506370-cced57d0-2620-4454-b7f2-f1a4f1f20d6d.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjExNDE0NTIsIm5iZiI6MTcyMTE0MTE1MiwicGF0aCI6Ii83MTg0NTc3Ny8yNjM1MDYzNzAtY2NlZDU3ZDAtMjYyMC00NDU0LWI3ZjItZjFhNGYxZjIwZDZkLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA3MTYlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwNzE2VDE0NDU1MlomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTI1OWYzMTE2MWE0NGYwYjNiZWJiYjBmMjA1NWViNjg0YzdlYTNkNDljNGQxOWQxMGRjYzBkNTc0MmM4Y2Y4ZWEmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.wDKo89e89XRXk3OFV6cXINOJlHNN6jnDp4ACF1FkI4c)
Unless your group is set to private:
![image](https://private-user-images.githubusercontent.com/71845777/263506389-4c14bbb0-22ff-4826-8bcc-1edc585709e2.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjExNDE0NTIsIm5iZiI6MTcyMTE0MTE1MiwicGF0aCI6Ii83MTg0NTc3Ny8yNjM1MDYzODktNGMxNGJiYjAtMjJmZi00ODI2LThiY2MtMWVkYzU4NTcwOWUyLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA3MTYlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwNzE2VDE0NDU1MlomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWNhYjc1MDhlYTA0MjY2MDJlNmRlNmUzNzU0YjA0MWJkNTk4ZDE5MmI5NjM4NDIwM2QyODM0NmEyODQ1MjExNzQmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.BJz9TbqaMxwSL38yqM2N5FoVp8ZodBGeIi1PuUFrvd8)
Which issue(s) this PR fixes:
(REQUIRED)
Resolves #1326
Special notes for your reviewer:
(fill-in or delete this section)
My hands hurt
Testing
(fill-in or delete this section)
Pytest for backend, lots of manual frontend testing. I don't know if we want to add tests for the new APIs/stores on the frontend, but the private ones don't have tests.
Release Notes
(REQUIRED)