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

Feature/image blocking #926

Open
wants to merge 3 commits into
base: develop
Choose a base branch
from

Conversation

CH3RVB
Copy link

@CH3RVB CH3RVB commented Apr 26, 2024

This is my first PR to here, so be nice to me /hj

This is my third (i think) crack at making something like this. Everything else was either too clunky or felt... annoying to use? So this is my final solution. LOL.

Adds a modular image blocking system for users. Users can curate their own blocklist by blocking a specific model + ID. Blocked models + IDs have their image blurred out until they become unblocked again by the user. I say model + ID because right now it's an image only thing, but theoretically you could apply this in other ways?

With a small dosage of Moif magic, it automatically applies to all mentions of the blocked image across the site, as long as they hotlink directly to the image URL. Very easy to use across exts, simply plug in the block widget, block an image, and go.

I'm unsure about some aspects, such as the route for the image blocking, as well as how many different world/other entries I should even put this thing on. Maybe the button is also too annoying to look at? Dunno. Either way, it's here :')


if ($block) {
return true;
} else {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Generally speaking, with returns, you don't need to encase the second in the if/else-- nothing beyond a return is executed to begin with, so you can simply have the first in the if, then the second freestanding.

Copy link
Contributor

Choose a reason for hiding this comment

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

+1, can even just
return $block ? true : false

Copy link
Contributor

@ScuffedNewt ScuffedNewt May 8, 2024

Choose a reason for hiding this comment

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

actually follow up on this i'd do

function checkImageBlock($image, $user)
{
    return App\Models\ImageBlock::where([
        ['image_id', '=', $image->id],
        ['image_type', '=', get_class($image)],
        ['user_id', '=', $user->id],
    ])->exists();
}

Copy link
Collaborator

@itinerare itinerare left a comment

Choose a reason for hiding this comment

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

A good stab at an arguably relatively complex task!

* @var array
*/
protected $fillable = [
'item_id', 'item_type', 'user_id'
Copy link
Collaborator

Choose a reason for hiding this comment

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

Referring to non-specific objects as "items" when "item" is a concept already extant in the codebase is... very confusing.

Copy link
Contributor

Choose a reason for hiding this comment

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

+1, recommend block_object_id or image_id image_type etc

@if (Auth::check() && count(Auth::user()->blockedImages))
<style>
@foreach (Auth::user()->blockedImages as $image)
[src="{{ $image->item->imageUrl ? $image->item->imageUrl : ($image->item->currencyImageUrl ? $image->item->currencyImageUrl : ($image->item->avatarUrl ? $image->item->avatarUrl : '')) }}"] {
Copy link
Collaborator

Choose a reason for hiding this comment

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

This logic would be better done in an attribute on the image block model, I think. Would be a good use case for a switch statement, potentially.

@@ -82,6 +82,18 @@
@endif

@include('feed::links')

{{-- Image Blocking --}}
@if (Auth::check() && count(Auth::user()->blockedImages))
Copy link
Collaborator

Choose a reason for hiding this comment

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

The count here should just be able to be Auth::user()->blockedImages->count(), since iirc what you get out of a relation is either directly or functionally a collection.

$model = get_class($item);
@endphp
<input type="hidden" name="item_type" value="{{ $model }}" />
{!! Form::submit(checkItemBlock($item, Auth::user()) ? 'Unblock' : 'Block', ['class' => 'btn btn-success btn-sm '.(isset($float) && $float ? 'float-right' : '')]) !!}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Probably this should be clearer about what's being blocked.

@php
$model = get_class($item);
@endphp
<input type="hidden" name="item_type" value="{{ $model }}" />
Copy link
Collaborator

Choose a reason for hiding this comment

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

While the risk is low in a project like this that's already open source, it's generally not the best idea to plunk stuff like model names out in the open; comments already went through this, so have a look at the form for those, etc. for an idea as to what to do about it.

@@ -52,6 +52,8 @@
Route::post('bookmarks/edit/{id}', 'BookmarkController@postCreateEditBookmark');
Route::get('bookmarks/delete/{id}', 'BookmarkController@getDeleteBookmark');
Route::post('bookmarks/delete/{id}', 'BookmarkController@postDeleteBookmark');

Route::post('image-blocks/block/{id}', 'AccountController@postBlockUnblockImage');
Copy link
Collaborator

Choose a reason for hiding this comment

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

If you go a similar route to comments (wrt the above), this'll probably need to be changed accordingly, but the general gist and placement of the route are fine.


//check it's not already blocked, if not, make the block

$block = ImageBlock::where([
Copy link
Collaborator

Choose a reason for hiding this comment

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

You could probably trim off a little work and express this as $user->blockedImages->where([non-user-id-conditions etc etc])->first() too!


try {
$model = $data['item_type'];
$item = $model::find($id);
Copy link
Collaborator

Choose a reason for hiding this comment

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

It might be worthwhile to double-check that the object exists just to be safe, since it's technically in the 'accepting semi-arbitrary input from users' zone.

@itinerare itinerare added enhancement New feature or request needs review Pull requests that are pending community review labels Apr 26, 2024
@itinerare
Copy link
Collaborator

Belatedly, also... it might seem counterintuitive, but it might be an idea to have a page (akin to bookmarks) with the current user's blocked images, as a ready point of reference.

Copy link
Contributor

@ScuffedNewt ScuffedNewt left a comment

Choose a reason for hiding this comment

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

mostly nits, agree with what mercury has said
apologies if comments are short - in work PR review mode

Copy link
Contributor

Choose a reason for hiding this comment

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

nit: run composer lint to stop these weird style changes

Copy link
Collaborator

@itinerare itinerare May 8, 2024

Choose a reason for hiding this comment

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

Probably I'm just going to switch the relevant workflow to running on push for all branches again so neither reviewers nor contributors need to think about it, since my clever idea wrt running on PRs only was stymied (fairly reasonably) by repo perms... It was worth a shot |D

Copy link
Contributor

Choose a reason for hiding this comment

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

👌

It was worth a shot |D

can't work out all the time!

Copy link
Collaborator

Choose a reason for hiding this comment

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

Did that while I was thinking about it-- so it should now be as easy as just merging in latest develop. Hopefully.


if ($block) {
return true;
} else {
Copy link
Contributor

Choose a reason for hiding this comment

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

+1, can even just
return $block ? true : false

Copy link
Contributor

Choose a reason for hiding this comment

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

again with composer lint

]);

if ($service->blockUnblockImage($data, $id)) {

Copy link
Contributor

Choose a reason for hiding this comment

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

should this be blank? if yes, change it to !$service... and remove else block

* @var array
*/
protected $fillable = [
'item_id', 'item_type', 'user_id'
Copy link
Contributor

Choose a reason for hiding this comment

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

+1, recommend block_object_id or image_id image_type etc

Copy link
Contributor

Choose a reason for hiding this comment

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

+1 to lint

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
Copy link
Contributor

Choose a reason for hiding this comment

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

this should be class FileName extends Migration to stop errors on older installs

Copy link
Collaborator

Choose a reason for hiding this comment

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

Does this cause issues? My understanding was that upstream (wrt Laravel) this change was following PHP supporting it, so it doesn't make much sense to me that (assuming PHP is upgraded, which needs to happen regardless) this should be a problem.

Copy link
Contributor

Choose a reason for hiding this comment

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

I've found on SOME sites it can be an issue, & quiet often on local (people on windows / older xampp)
perhaps in this case it should be fine since this is on v3 which should implicitly mean that the php version is up to par, so take this comment with a grain of salt

Copy link
Collaborator

@itinerare itinerare May 8, 2024

Choose a reason for hiding this comment

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

I'm inclined to let this be since yeah, v3 explicitly requires PHP be reasonably up-to-date (whereas on current release it's supported but not technically forced, at least by the Laravel version)...

@@ -6,6 +6,9 @@
<div class="col-md-2 text-center">
<!-- User Icon -->
<img src="{{ $user->avatarUrl }}" class="img-fluid rounded-circle" style="max-height: 125px;" alt="{{ $user->name }}'s Avatar">
@if(Auth::check())
@include('widgets._item_block', ['item' => $user])
@endif
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: indents

Copy link
Contributor

Choose a reason for hiding this comment

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

double nit: item should not be the variable name

@@ -0,0 +1,7 @@
{!! Form::open(['url' => 'account/image-blocks/block/' . $item->id]) !!}
@php
$model = get_class($item);
Copy link
Contributor

Choose a reason for hiding this comment

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

further on prior nit: $item is not the best variable name

@@ -8,6 +8,9 @@
<h3>{{ $currency->name }} @if ($currency->abbreviation)
({{ $currency->abbreviation }})
@endif
@if(Auth::check())
@include('widgets._item_block', ['item' => $currency, 'float' => true])
Copy link
Contributor

Choose a reason for hiding this comment

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

float seems to be true in most places, consider it being default to true and explicitly pass it as false, but that's mostly preference

@ScuffedNewt
Copy link
Contributor

Also unrelated, I find this a little bit strange to include in the default LK install, considering things like toyhouse etc etc don't employ this on general images, and if a specific lorekeeper has such images on items etc that may need to be blocked its best installed individually, imo
@itinerare thoughts?

@itinerare
Copy link
Collaborator

On some level, I agree... but users may need to block seemingly innocuous stuff in certain cases, so it's not necessarily sufficient to install it on a case-by-case basis/only where more common points of friction occur.

@CH3RVB
Copy link
Author

CH3RVB commented May 8, 2024

Also unrelated, I find this a little bit strange to include in the default LK install, considering things like toyhouse etc etc don't employ this on general images, and if a specific lorekeeper has such images on items etc that may need to be blocked its best installed individually, imo @itinerare thoughts?

On some level, I agree... but users may need to block seemingly innocuous stuff in certain cases, so it's not necessarily sufficient to install it on a case-by-case basis/only where more common points of friction occur.

Is this a good time to add a toggle or leave as-is? Could fulfill both arguments technically, then?

@itinerare
Copy link
Collaborator

To some degree, I feel like if it's worth including in core at all then there's no sense in undercutting it by putting it behind a toggle...

I think the other part of it is that TH has a different use case than we do, so it's not necessarily practical to make a direct comparison there; TH doesn't really have images that persistently exist around the site in the same way (items, etc.) to be an issue in the first place. Generally speaking, you have more leeway to simply not look at a character or image on there that causes issues, and iirc can block characters-- so it does have some manner of comparable function, just that the context is different.
The more direct analogue would probably be pet sites-- and imo the fact that those generally don't have this kind of option isn't in their favor.

It's one of those things where it's the safer and more considerate thing to be proactive about it and spare folks unnecessary stress, even if it feels like "overkill" in a lot of cases/to include in core.

@ScuffedNewt
Copy link
Contributor

The more direct analogue would probably be pet sites

definitely, hit the nail on the head! brain wasn't braining yday

It's one of those things where it's the safer and more considerate thing to be proactive about it and spare folks unnecessary stress, even if it feels like "overkill" in a lot of cases/to include in core.

firmly in the camp of <this is probably not a feature conducive? to core> since most items etc should not be causing these issues ideally, especially when compared to Lorekeepers mainstream counterparts
That being said, I think this would be better placed as having Characters as default -- since when #876 is inevitably cleaned and finished, users may still find that they want to block a certain character even if does is not necessarily fall under a "warning needed" category.
In fact, I think that would be a much more requested feature than items

TLDR; IMO, if this feature is to be added...

  • Change the primary focus of the default configuration to be for characters
  • A toggle, if not (since other use cases would need to be manually added by a developer)

*
* @var string
*/
protected $table = 'image_blocks';
Copy link
Contributor

Choose a reason for hiding this comment

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

following up on my prior comment about user space too, ideally the table should be user_image_blocks in similar fashion

Copy link
Collaborator

Choose a reason for hiding this comment

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

Likewise, agree on this

@itinerare
Copy link
Collaborator

definitely, hit the nail on the head! brain wasn't braining yday

Haha, all good, been there.

Anyhow, yeah, I'm inclined to agree that characters are the bigger/more probable use case, so I think it's sensible enough to aim this more firmly at that use case-- with support for other things essentially as a side benefit (albeit one that I do still find in favor of, personally). I'd agree that most items, etc. shouldn't cause issues/it's generally good to avoid making ones that are liable to, but I'd rather provide users the ability to address these things for themselves.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request needs review Pull requests that are pending community review
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants