wire-elements / spotlight

Livewire component that brings Spotlight/Alfred-like functionality to your Laravel application.
MIT License
925 stars 72 forks source link

Different Spotlight behavior depending on the page component? #46

Closed seabasss closed 2 years ago

seabasss commented 3 years ago

Is there any way to tell Spotlight what the page component is and cater the behavior to that?

An example. If I open Spotlight on my dashboard and type "New post" it should ask me what project I want to create the post for - great, but if I'm already inside a project, can this info be pre-populated somehow? E.g. can I tell Spotlight that it was opened on a project page and now assume that you want to create the post for that project?

Thanks!

Edit // When I think about it. I may even have some options that should only show up in Spotlight if it's called from a certain component. Either way, I think both ways would be solved if I could tell Spotlight where it was called from. Maybe this is already possible?

PhiloNL commented 3 years ago

I haven't tested this but you could try:

    public function shouldBeShown(Request $request): bool
    {
        if($request->route('project')) {
            return true;
        }

        return false;
    }
seabasss commented 3 years ago

Sweet, I changed it to $request->routeIs and it worked! Thanks! Perfect.

seabasss commented 3 years ago

One more question. Can I reach $request from the execute method as well? When I added it it seems like I get the request from Spotlight instead of the original request. I also tried to set a public variable on the class, but got a message that it couldn't be done before initialization.

I'm trying to do something like this:

public function execute(Spotlight $spotlight, Request $request)
{
    $spotlight->emit('openModal', 'create-post', ['projectId' => basename($request->path()]);
}

public function shouldBeShown(Request $request): bool
{
    if ($request->routeIs('project')) {
        return true;
    }
}
PhiloNL commented 3 years ago

Unfortunately, that will not work. The shouldBeShown method is executed on the current route, while the execute method is executed on a subsequent request. I'll think about a way to take forward data from the original request. As a workaround, it may work to use sessions.

public function shouldBeShown(Request $request): bool
{
    if ($request->routeIs('project')) {
        session()->flash('productId', $request->route('project')->id); 
        return true;
    }
}

public function execute(Spotlight $spotlight, Request $request)
{
    $spotlight->emit('openModal', 'create-post', ['projectId' => session('projectId')));
}
seabasss commented 3 years ago

Cool thanks!!

It seems like $request->routeIs('project') is only true on initial load. If I open the spotlight a second time, it's no longer true and $request is now Spotlight itself.

So setting the session there only works first time for me. I could change from flash to a persistent session, but then I need to figure out how to remove it when I'm done which gets a little messy since sometimes you go all the way to execute and sometimes cancel out early.

Let me know if you can think of something :)

Huge thanks again.

seabasss commented 3 years ago

This worked, but kinda ugly hehe :) Welcome to my brain lol.

public function shouldBeShown(Request $request): bool
{
    if ($request->routeIs('project')) {
        session(['projectId' => basename($request->path())]);
    } else {
        if ($request->route()->getName() != 'livewire.message') {
            session()->forget('projectId');
        }
    }

    return true;
}