hjortur17

hjortur17

Member Since 1 Year Ago

Grindavík

Experience Points 29,670
Experience Level 6

330 experience to go until the next level!

In case you were wondering, you earn Laracasts experience when you:

  • Complete a lesson — 100pts
  • Create a forum thread — 50pts
  • Reply to a thread — 10pts
  • Leave a reply that is liked — 50pts
  • Receive a "Best Reply" award — 500pts
Lessons Completed 220
Lessons
Completed
Best Reply Awards 0
Best Reply
Awards
  • Start Your Engines Achievement

    Start Your Engines

    Earned once you have completed your first Laracasts lesson.

  • First Thousand Achievement

    First Thousand

    Earned once you have earned your first 1000 experience points.

  • One Year Member Achievement

    One Year Member

    Earned when you have been with Laracasts for 1 year.

  • Two Year Member Achievement

    Two Year Member

    Earned when you have been with Laracasts for 2 years.

  • Three Year Member Achievement

    Three Year Member

    Earned when you have been with Laracasts for 3 years.

  • Four Year Member Achievement

    Four Year Member

    Earned when you have been with Laracasts for 4 years.

  • Five Year Member Achievement

    Five Year Member

    Earned when you have been with Laracasts for 5 years.

  • School In Session Achievement

    School In Session

    Earned when at least one Laracasts series has been fully completed.

  • Welcome To The Community Achievement

    Welcome To The Community

    Earned after your first post on the Laracasts forum.

  • Full Time Learner Achievement

    Full Time Learner

    Earned once 100 Laracasts lessons have been completed.

  • Pay It Forward Achievement

    Pay It Forward

    Earned once you receive your first "Best Reply" award on the Laracasts forum.

  • Subscriber Achievement

    Subscriber

    Earned if you are a paying Laracasts subscriber.

  • Lifer Achievement

    Lifer

    Earned if you have a lifetime subscription to Laracasts.

  • Laracasts Evangelist Achievement

    Laracasts Evangelist

    Earned if you share a link to Laracasts on social media. Please email [email protected] with your username and post URL to be awarded this badge.

  • Chatty Cathy Achievement

    Chatty Cathy

    Earned once you have achieved 500 forum replies.

  • Laracasts Veteran Achievement

    Laracasts Veteran

    Earned once your experience points passes 100,000.

  • Ten Thousand Strong Achievement

    Ten Thousand Strong

    Earned once your experience points hits 10,000.

  • Laracasts Master Achievement

    Laracasts Master

    Earned once 1000 Laracasts lessons have been completed.

  • Laracasts Tutor Achievement

    Laracasts Tutor

    Earned once your "Best Reply" award count is 100 or more.

  • Laracasts Sensei Achievement

    Laracasts Sensei

    Earned once your experience points passes 1 million.

  • Top 50 Achievement

    Top 50

    Earned once your experience points ranks in the top 50 of all Laracasts users.

07 Jun
2 weeks ago

hjortur17 left a reply on Update Avatar Path

@SIANGBOON - It's working.

hjortur17 left a reply on Update Avatar Path

So my if statement ended up beeing like this:

if (request()->hasFile('avatar'))
        {
            request()->validate([
                'avatar' => ['image']
            ]);

            auth()->user()->update([
                'avatar_path' => request()->file('avatar')->store('avatars', 'public')
            ]);
        }
        

@siangboon - The hasFile() got it to work! Thanks!

hjortur17 left a reply on Update Avatar Path

@SIANGBOON - I have type=file at my input and enctype="multipart/form-data" on my form.

hjortur17 left a reply on Update Avatar Path

@SIANGBOON - So changed my input to this

<input type="file" accept="image/*" name="avatar">

But the function still won't enter the if statement.

if (request()->filled('avatar'))
        {
            dd('avatar_path');

            request()->validate([
                'avatar' => ['image']
            ]);

            auth()->user()->update([r
                'avatar_path' => request()->file('avatar')->store('avatars', 'public')
            ]);
        }

hjortur17 left a reply on Update Avatar Path

Here is my input,

And my migration:

        Schema::create('users', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('role')->nullable();
            $table->string('name');
            $table->string('username')->unique();
            $table->string('social_id');
            $table->string('study_program')->nullable();
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->string('avatar_path')->nullable();

            $table->string('snapchat_username')->nullable();
            $table->string('instagram_username')->nullable();
            $table->string('twitter_username')->nullable();
            $table->string('facebook_username')->nullable();
            $table->string('website')->nullable();

            $table->rememberToken();
            $table->timestamps();
        });

hjortur17 left a reply on Update Avatar Path

@FTIERSCH - What do you mean?

hjortur17 started a new conversation Update Avatar Path

I'm trying to update my avatar path but my function won't​ enter the if statement

if (request()->filled('avatar_path'))
        {
            dd('avatar_path');

            request()->validate([
                'avatar' => ['image']
            ]);

            auth()->user()->update([
                'avatar_path' => request()->file('avatar')->store('avatars', 'public')
            ]);
        }

hjortur17 left a reply on Update User

@FTIERSCH - Thanks! It worked!

I justed this solution:

request()->filled('password')

hjortur17 left a reply on How To Change Title With Vue

@ROBSTAR - So I have a dropdown menu, and when I click something in the dropdown menu I want that to be the title inside the box.

Sort

Click the button and the dropdown comes down:

Popular
Most Comment

And then if I click Popular I want it to be:

Popular

Click the button and the dropdown comes down:

Popular
Most Comment

Does this explain this better?

06 Jun
2 weeks ago

hjortur17 left a reply on Update User

@FTIERSCH - Hi, when I try to update the password it just skips the IF statement. Any ideas on how to make it run the if statement?


public function update(User $user)
    {
        $user->fill(request()->except('password'));

        if (! request()->input('password') === '')
        {
            dd('password');
            
            request()->validate([
                'password' => 'confirmed'
            ]);

            $user->password = bcrypt(request()->input('password'));
        }
        
        $user->save();

        return redirect()->route('profile', $user);
    }
```​

hjortur17 left a reply on How To Change Title With Vue

@MUSHOOD - But how do I get the title of the

  • ?

    <button @click="toggle" class="bg-grey-light text-grey-darker rounded-full px-4 py-2 text-sm focus:outline-none hover:shadow transition" v-on-clickaway="hide"> {{ title }}

        <div v-if="active" class="w-64 bg-white shadow-md rounded p-4 mt-2 absolute z-20">
            <ul class="list-reset">
                <li class="py-2">
                    <a href="/fréttir?nýjast=1" class="font-semibold">
                        <svg xmlns="http://www.w3.org/2000/svg" width="15px" height="15px" viewBox="0 0 576 512" class="mr-2"><path d="M552 64H88c-13.255 0-24 10.745-24 24v8H24c-13.255 0-24 10.745-24 24v272c0 30.928 25.072 56 56 56h472c26.51 0 48-21.49 48-48V88c0-13.255-10.745-24-24-24zM56 400a8 8 0 0 1-8-8V144h16v248a8 8 0 0 1-8 8zm236-16H140c-6.627 0-12-5.373-12-12v-8c0-6.627 5.373-12 12-12h152c6.627 0 12 5.373 12 12v8c0 6.627-5.373 12-12 12zm208 0H348c-6.627 0-12-5.373-12-12v-8c0-6.627 5.373-12 12-12h152c6.627 0 12 5.373 12 12v8c0 6.627-5.373 12-12 12zm-208-96H140c-6.627 0-12-5.373-12-12v-8c0-6.627 5.373-12 12-12h152c6.627 0 12 5.373 12 12v8c0 6.627-5.373 12-12 12zm208 0H348c-6.627 0-12-5.373-12-12v-8c0-6.627 5.373-12 12-12h152c6.627 0 12 5.373 12 12v8c0 6.627-5.373 12-12 12zm0-96H140c-6.627 0-12-5.373-12-12v-40c0-6.627 5.373-12 12-12h360c6.627 0 12 5.373 12 12v40c0 6.627-5.373 12-12 12z" fill="#3490dc"/></svg>
                        Nýjast
                    </a>
                </li>
                <li class="py-2">
                    <a href="/fréttir?vinsælt=1" class="font-semibold">
                        <svg xmlns="http://www.w3.org/2000/svg" width="15px" height="15px" viewBox="0 0 576 512" class="mr-2"><path d="M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z" fill="#3490dc"/></svg>
                        Vinsælt
                    </a>
                </li>
                <li class="py-2">
                    <a href="/fréttir?flestUmmæli=1" class="font-semibold">
                        <svg xmlns="http://www.w3.org/2000/svg" width="15px" height="15px" viewBox="0 0 512 512" class="mr-2"><path d="M448 0H64C28.7 0 0 28.7 0 64v288c0 35.3 28.7 64 64 64h96v84c0 9.8 11.2 15.5 19.1 9.7L304 416h144c35.3 0 64-28.7 64-64V64c0-35.3-28.7-64-64-64zM288 264c0 4.4-3.6 8-8 8H136c-4.4 0-8-3.6-8-8v-16c0-4.4 3.6-8 8-8h144c4.4 0 8 3.6 8 8v16zm96-96c0 4.4-3.6 8-8 8H136c-4.4 0-8-3.6-8-8v-16c0-4.4 3.6-8 8-8h240c4.4 0 8 3.6 8 8v16z" fill="#3490dc"/></svg>
                        Flest ummæli
                    </a>
                </li>
            </ul>
        </div>
    </div>
    

  • hjortur17 left a reply on Update User

    @FTIERSCH - Thanks!

    hjortur17 left a reply on Help With Test

    @KEVINBUI - Here you go,

    public function index(Channel $channel, ThreadFilters $filters, Trending $trending)
        {
            $threads = $this->getThreads($channel, $filters);
    
            if (request()->wantsJson()) {
                return $threads;
            }
    
            return view('threads.index', [
                'threads' => $threads,
                'trending' => $trending->get()
            ]);
        }
    
    protected function getThreads(Channel $channel, ThreadFilters $filters)
        {
            $threads = Thread::latest()->filter($filters);
            
            if ($channel->exists) {
                $threads->where('channel_id', $channel->id);
            }
        
            return $threads->paginate(35);
        }
    
    <?php
    
    namespace App\Filters;
    
    use App\User;
    
    class ThreadFilters extends Filters
    {
        protected $filters = [
            'nýjast',
            'vinsælt',
            'flestUmmæli'
        ];
    
        protected function nýjast()
        {
            $this->builder->getQuery()->orders = [];
            
            return $this->builder->orderBy('created_at', 'desc');
        }
    
        protected function vinsælt()
        {
            $this->builder->getQuery()->orders = [];
            
            return $this->builder->orderBy('visits', 'desc');
        }
    
        protected function flestUmmæli()
        {
            $this->builder->getQuery()->orders = [];
            
            return $this->builder->orderBy('replies_count', 'desc');
        }
    }
    

    hjortur17 started a new conversation Update User

    Hi I can't figure out how I can update $user. I always get the password is null. Any ideas how to get it to pass with making the user update the password every time he is updating maybe the username.

    Here is the update function:

    public function update(User $user)
        {
            if (! request()->input('password') === '')
            {
                $user->password = bcrypt(request()->input('password'));
            }
    
            $user->update(request()->all());
    
            return redirect()->back();
        }
    
    03 Jun
    3 weeks ago

    hjortur17 left a reply on Help With Test

    ...

    hjortur17 started a new conversation Store Date's In MySQL

    Hi, I can't figure out how to store a date in the database. I can't use string because I'm using diffForHumans()

    Here is what I have tried:

    $table->timestamps('date');
    
    28 May
    4 weeks ago

    hjortur17 left a reply on Help With Test

    Here is my migration

    <?php
    
    use Illuminate\Support\Facades\Schema;
    use Illuminate\Database\Schema\Blueprint;
    use Illuminate\Database\Migrations\Migration;
    
    class CreateThreadsTable extends Migration
    {
        /**
         * Run the migrations.
         *
         * @return void
         */
        public function up()
        {
            Schema::create('threads', function (Blueprint $table) {
                $table->bigIncrements('id');
                $table->string('slug')->unique()->nullable();
                $table->unsignedInteger('user_id');
                $table->unsignedInteger('channel_id');
                $table->unsignedInteger('replies_count')->default(0);
                $table->unsignedInteger('visits')->default(0);
                $table->string('title');
                $table->text('body');
                $table->boolean('locked')->default(false);
                $table->timestamps();
            });
        }
    
        /**
         * Reverse the migrations.
         *
         * @return void
         */
        public function down()
        {
            Schema::dropIfExists('threads');
        }
    }
    

    And here is my model:

    <?php
    
    namespace App;
    
    use Illuminate\Database\Eloquent\Model;
    use Illuminate\Database\Eloquent\Builder;
    
    use App\Filters\ThreadFilters;
    use App\Notifications\ThreadWasUpdated;
    use App\Events\ThreadReceviedNewReply;
    
    class Thread extends Model
    {
        use RecordsActivity;
    
        protected $guarded = [];
    
        protected $with = ['creator', 'channel'];
    
        protected $appends = ['isSubscribedTo'];
    
        protected $casts = [
            'locked' => 'boolean'
        ];
    
        protected static function boot() {
            parent::boot();
    
            static::addGlobalScope('replyCount', function ($builder) {
                $builder->withCount('replies');
            });
    
            static::deleting(function ($thread) {
                $thread->replies->each->delete();
            });
    
            static::created(function ($thread) {
                $thread->update(['slug' => $thread->title]);
            });
        }
    
        public function path()
        {
            return "/fréttir/{$this->channel->slug}/{$this->slug}";
        }
    
        public function creator()
        {
            return $this->belongsTo(User::class, 'user_id');
        }
    
        public function replies()
        {
            return $this->hasMany(Reply::class);
        }
    
        public function addReply($reply)
        {
            $reply = $this->replies()->create($reply);
    
            event(new ThreadReceviedNewReply($reply));
            
            return $reply;
        }
    
        public function channel()
        {
            return $this->belongsTo(Channel::class);
        }
    
        public function scopeFilter($query, ThreadFilters $filters)
        {
            return $filters->apply($query);
        }
    
        public function subscribe($userId = null)
        {
            $this->subscriptions()->create([
                'user_id' => $userId ?: auth()->id()
            ]);
            
            return $this;
        }
    
        public function unsubscribe($userId = null)
        {
            $this->subscriptions()
                ->where('user_id', $userId ?: auth()->id())
                ->delete();
        }
    
        public function subscriptions()
        {
            return $this->hasMany(ThreadSubscription::class);
        }
    
        public function getIsSubscribedToAttribute()
        {
            return $this->subscriptions()
                ->where('user_id', auth()->id())
                ->exists();
        }
    
        public function hasUpdatedFor($user = null)
        {
            $key = $user->visitedThreadCacheKey($this);
            
            return $this->updated_at > cache($key);
        }
    
        public function getRouteKeyName()
        {
            return 'slug';
        }
    
        public function setSlugAttribute($value)
        {
            $slug = str_slug($value);
            $original = $slug;
            $count = 2;
    
            while (static::whereSlug($slug)->exists()) {
                $slug = "{$original}-" . $count++;
            }
    
            $this->attributes['slug'] = $slug;
        }
    
        public function getBodyAttribute($body)
        {
            return \Purify::clean($body); 
        }
    }
    
    
    <?php
    
    namespace App;
    
    use Illuminate\Database\Eloquent\Model;
    
    use Carbon\Carbon;
    
    class Reply extends Model
    {
        use Favoritable, RecordsActivity;
    
        protected $guarded = [];
    
        protected $with = ['owner', 'favorites'];
    
        protected $appends = ['favoritesCount', 'isFavorited'];
        
        public function owner()
        {
            return $this->belongsTo(User::class, 'user_id');
        }
    
        public function thread()
        {
            return $this->belongsTo(Thread::class);
        }
    
        public function wasJustPublished()
        {
            return $this->created_at->gt(Carbon::now()->subMinute());
        }
    
        public function mentionedUsers()
        {
            preg_match_all("/@([\w\-]+)/", $this->body, $matches);
    
            return $matches[1];
        }
    
        public function path()
        {
            return $this->thread->path() . "#athugarsemd-{$this->id}";
        }
    
        public function setBodyAttribute($body)
        {
            $this->attributes['body'] = preg_replace('/@([\w\-]+)/', '<a href="/notendur/">LARACASTS_SNIPPET_PLACEHOLDER</a>', $body);
        }
        
        public function getBodyAttribute($body)
        {
            return \Purify::clean($body); 
        }
    }
    
    

    hjortur17 started a new conversation Help With Test

    Hi, I can't get this to work.

    /** @test */
        public function a_user_can_filter_threads_by_popularity()
        {
            $threadWithTwoReplies = create('App\Thread');
            create('App\Reply', ['thread_id' => $threadWithTwoReplies->id], 2);
            
            $threadWithThreeReplies = create('App\Thread');
            create('App\Reply', ['thread_id' => $threadWithThreeReplies->id], 3);
            
            $threadWithNoReplies = $this->thread;
            
            $response = $this->getJson('fréttir?vinsælt=1')->json();
            
            $this->assertEquals([3, 2, 0], array_column($response['data'], 'replies_count'));
        }
    

    This is what the terminal says:

    ➜  project git:(master) ✗ pf ReadThreadsTest
    PHPUnit 7.5.11 by Sebastian Bergmann and contributors.
    
    ...F..                                                              6 / 6 (100%)
    
    Time: 424 ms, Memory: 28.00 MB
    
    There was 1 failure:
    
    1) Tests\Feature\ReadThreadsTest::a_user_can_filter_threads_by_popularity
    Failed asserting that two arrays are equal.
    --- Expected
    +++ Actual
    @@ @@
     Array (
    -    0 => 3
    -    1 => 2
    -    2 => 0
    +    0 => '0'
    +    1 => '2'
    +    2 => '3'
     )
    
    /Users/hjorturfreyrlarusson/websites/project/tests/Feature/ReadThreadsTest.php:63
    /Users/hjorturfreyrlarusson/.composer/vendor/phpunit/phpunit/src/TextUI/Command.php:208
    /Users/hjorturfreyrlarusson/.composer/vendor/phpunit/phpunit/src/TextUI/Command.php:164
    
    FAILURES!
    Tests: 6, Assertions: 10, Failures: 1.
    

    hjortur17 left a reply on Help Regarding My Blade File

    But if the user is not logged in then I get a error about the prop can not be empty

    hjortur17 started a new conversation Change Vue Data Attribute

    Hi, I'm trying to create Vue Sort Component and when you click a link I want to show the title in my button. For example first time a see the button it says show, but then I click it and get the dropdown and see for example Popular and I click it I want to make the button say: Popular instead of Sort.

    Do you understand?

    Here is my SortThreads.vue

    <template>
        <div class="p-2">
            <button @click="toggle" class="bg-grey-light text-grey-darker rounded-full px-4 py-2" v-on-clickaway="hide" v-text="title"></button>
    
            <div v-if="active" class="w-64 bg-white shadow-md rounded p-4 mt-2 absolute z-20">
                <ul class="list-reset">
                    <li class="mb-3">
                        <a href="/fréttir?vinsælt=1">Vinsælt</a>
                    </li>
                    <li>Homi</li>
                </ul>
            </div>
        </div>
    </template>
    
    <script>
        import { mixin as clickaway } from 'vue-clickaway';
    
        export default {
            mixins: [ clickaway ],
    
            data() {
                return {
                    active: false,
                    title: ""
                }
            },
    
            methods: {
                toggle() {
                    this.active ? this.hide() : this.show();
                },
    
                show() {
                    flash("já");
                    this.active = true;
                },
    
                hide() {
                    flash("nei");
    
                    this.active = false;
                }
            }   
        }
    </script>
    
    27 May
    4 weeks ago

    hjortur17 started a new conversation Help With Moving Tag From Blade

    Hi, in my master.blade.php file I have this

    window.App ={!! json_encode([
        'signedIn' => Auth::check(),
        'user' => Auth::user(),
    ]) !!};
    

    because I have some vue components that need to know about the user. But I want to move this somewhere else than​ having​ it in the layout file.

    22 May
    1 month ago

    hjortur17 left a reply on Auth::user() Not Returning All Elements

    @ftiersch - But if I remove it from the $hidden and console log the user it shows the correct role for the user but my script is still returning false.

    Any ideas how to fix that?

    isAdmin() {
            console.log(['admin'].includes(user.username));         => false
            console.log(user);                                      => {id: 101, role: "admin", username...}
            
            return ['admin'].includes(user.username);
        }
    

    hjortur17 left a reply on Auth::user() Not Returning All Elements

    @snapey - Also if I try this: console.log(['hjortur17'].includes(user.username));. It also return false

    hjortur17 left a reply on Auth::user() Not Returning All Elements

    This is the full file:

    let user = window.App.user;
    
    module.exports = {
        owns (model, prop = 'user_id') {
            return model[prop] === user.id;
        },
    
        isAdmin() {
            console.log(user);
            console.log(user.role);
            
            console.log(['admin'].includes(user.role));
        }
    };
    

    hjortur17 left a reply on Auth::user() Not Returning All Elements

    And my database show I have admin in my role

    hjortur17 left a reply on Auth::user() Not Returning All Elements

    In my database I have a role.

    This is my create_user_table

    
    Schema::create('users', function (Blueprint $table) {
                $table->bigIncrements('id');
                $table->string('role')->nullable();
                $table->string('name');
                $table->string('username')->unique();
                $table->string('social_id');
                $table->string('email')->unique();
                $table->timestamp('email_verified_at')->nullable();
                $table->string('password');
                $table->string('avatar_path')->nullable();
                $table->rememberToken();
                $table->timestamps();
            });
    
    

    hjortur17 started a new conversation Auth::user() Not Returning All Elements

    Hi, I'm trying to get the role of every user but Auth::user() is not returning it.

    I have this in my master.blade.php

    window.App ={!! json_encode([
        'signedIn' => Auth::check(),
        'user' => Auth::user(),
    ]) !!};
    

    and this in my .js file

    isAdmin() {
        console.log(user);                                               => {id: 101, name: "Hjörtur Freyr Lárusson", username: …}
        console.log(user.role);                  => undefined
            
        console.log(['admin'].includes(user.role));  => false
    }
    

    Any ideas why this is happening?

    This is the full return from user

    avatar_path: "http://project.test/avatars/fhVx37enhNNcaBnUDsQv2iHtymbbKKPiDPml2AWr.jpeg"
    created_at: "2019-05-21 17:39:25"
    email_verified_at: null
    id: 101
    name: "Hjörtur Freyr Lárusson"
    updated_at: "2019-05-21 18:02:02"
    username: "hjortur17"
    __proto__:
    constructor: ƒ Object()
    hasOwnProperty: ƒ hasOwnProperty()
    isPrototypeOf: ƒ isPrototypeOf()
    propertyIsEnumerable: ƒ propertyIsEnumerable()
    toLocaleString: ƒ toLocaleString()
    toString: ƒ toString()
    valueOf: ƒ valueOf()
    __defineGetter__: ƒ __defineGetter__()
    __defineSetter__: ƒ __defineSetter__()
    __lookupGetter__: ƒ __lookupGetter__()
    __lookupSetter__: ƒ __lookupSetter__()
    get __proto__: ƒ __proto__()
    set __proto__: ƒ __proto__()
    
    21 May
    1 month ago

    hjortur17 left a reply on Authorization With Vue

    Fixed it, it had a ​typo.

    hjortur17 started a new conversation Pass Data From One Component To Another

    Hi, I have one component which needs to know of what's happening in another component. So I have Thread.vue which​ is the parent and then I have LockButton.vue and Replies.vue. In Replies.vue I'm using a component called NewReply.vue and NewReply.vue needs to know if LockButton.vue has locked set to true or false.

    So here is the components and a view, (Thread.vue is an​ inline-template in show.blade.php)

    Thread.vue

    <script>
        import Replies from '../components/Replies.vue';
        import SubscribeButton from '../components/SubscribeButton.vue';
        import LockButton from '../components/LockButton.vue';
    
        export default {
            props: ['initalRepliesCount'],
    
            components: { Replies, SubscribeButton, LockButton },
    
            data() {
                return {
                    repliesCount: this.initalRepliesCount
                }
            }
        }
    </script>
    

    Replies.vue

    <template>
        <div>
            <div v-for="(reply, index) in items" :key="reply.id">
                <reply :attributes="reply" @deleted="remove(index)"></reply>
            </div>
    
            <paginator :dataSet="dataSet" @changed="fetch"></paginator>
    
            <new-reply @created="add" v-if="! $parent.LockButton.locked"></new-reply>
        </div>
    </template>
    
    <script>
        import Reply from './Reply.vue';
        import NewReply from './NewReply.vue';
        import collection from '../mixins/collection.js';
    
        export default {
            components: { Reply, NewReply },
    
            mixins: [collection],
    
            data() {
                return { dataSet: false };
            },
    
            created() {
                this.fetch();
            },
    
            methods: {
                fetch(page) {
                    axios.get(this.url(page)).then(this.refresh);
                },
    
                url(page) {
                    if (! page) {
                        let query = location.search.match(/page=(\d)/);
    
                        page = query ? query[1] : 1;
                    }
                    return location.pathname + '/athugasemdir?page=' + page;
                },
    
                refresh({data}) {
                    this.dataSet = data;
                    this.items = data.data;
    
                    window.scrollTo(0,0);
                }
            }
        }
    </script>
    

    NewReply.vue

    <template>
        <div id="reply-form" class="pt-8">
            <div class="flex" v-if="signedIn">
                <div class="w-10 item-start">
                    <img :src="image" class="rounded-full w-10 h-10" style="object-fit: cover;">
                </div>
                <div class="w-full pl-3 self-center">
                    <div class="flex items-center bg-grey-lighter rounded-full text-grey-darker focus:text-black resize-none outline-none text-sm">
                        <input class="appearance-none bg-transparent rounded-full text-grey-dark w-full pl-4 leading-tight focus:outline-none focus:text-grey-darkest transition" type="text" placeholder="Vitlu leggja orð í belg?" name="body" id="replyInput" v-model="body" required>
                        <button class="flex-no-shrink bg-blue p-2 px-4 rounded-full" type="submit" @click="addReply">
                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="15px" height="15px"><path d="M476 3.2L12.5 270.6c-18.1 10.4-15.8 35.6 2.2 43.2L121 358.4l287.3-253.2c5.5-4.9 13.3 2.6 8.6 8.3L176 407v80.5c0 23.6 28.5 32.9 42.5 15.8L282 426l124.6 52.2c14.2 6 30.4-2.9 33-18.2l72-432C515 7.8 493.3-6.8 476 3.2z" fill="#fff"/></svg>
                        </button>
                    </div>
                </div>
            </div>
            <p class="text-sm text-grey-dark" v-else>Þú þarft að vera <a href="/login" class="text-blue-light no-underline hover:text-blue transition">skráð/ur inn</a> til þess að taka þátt í umræðuni</p>
        </div>
    </template>
    
    <script>
        import 'jquery.caret';
        import 'at.js';
    
        export default {
            data() {
                return {
                    body: ''
                };
            },
    
            computed: {
                image() {
                    return window.App.user.avatar_path;
                }
            },
    
            mounted() {
                $('#replyInput').atwho({
                    at: "@",
                    delay: 750,
                    callbacks: {
                        remoteFilter: function(query, callback) {
                            $.getJSON("/api/users", {name: query}, function (usernames) {
                                callback(usernames)
                            });
                        }
                    }
                })
            },
    
            methods: {
                addReply() {
                    axios.post(location.pathname + '/athugasemdir', { body: this.body })
                        .catch(error => {
                            flash(error.response.data, 'danger');
                        })
                        .then(({data}) => {
                            this.body = '';
                            
                            flash('Kommentið þitt hefur verið póstað');
                            
                            this.$emit('created', data);
                        });
                }
            }
        }
    </script>
    

    LockButton.vue

    <template>
        <a class="cursor-pointer mr-4" @click="locked=true">
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512" height="16px"><path :d="paths" :fill="fills"/></svg>
        </a>
    </template>
    
    <script>
        export default {
            data() {
                return {
                    locked: false,
                }
            },
    
            computed: {
                paths() {
                    return [this.locked ? 'M400 224h-24v-72C376 68.2 307.8 0 224 0S72 68.2 72 152v72H48c-26.5 0-48 21.5-48 48v192c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V272c0-26.5-21.5-48-48-48zm-104 0H152v-72c0-39.7 32.3-72 72-72s72 32.3 72 72v72z' : 'M400 224h-16v-62.5C384 73.1 312.9.3 224.5 0 136-.3 64 71.6 64 160v64H48c-26.5 0-48 21.5-48 48v192c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V272c0-26.5-21.5-48-48-48zM96 160c0-70.6 57.4-128 128-128s128 57.4 128 128v64H96v-64zm304 320H48c-8.8 0-16-7.2-16-16V272c0-8.8 7.2-16 16-16h352c8.8 0 16 7.2 16 16v192c0 8.8-7.2 16-16 16z'];
                },
    
                fills() {
                    return [this.locked ? '#f2d024' : '#3d4852'];
                }
            }
        }
    </script>
    

    show.blade.php

    @extends ('layouts.master')
    
    @section ('include-css-head')
        <link rel="stylesheet" type="text/css" href="/css/vendor/jquery.atwho.css">
    @endsection
    
    @section ('section-1')
        <thread-view :inital-replies-count="{{ $thread->replies_count }}" inline-template>
            <div>
                <nav class="py-12">
                    <div class="flex">
                        <div class="flex-1 text-left">
                            <a href="{{ route('home') }}">
                                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" height="16px"><path d="M231.536 475.535l7.071-7.07c4.686-4.686 4.686-12.284 0-16.971L60.113 273H436c6.627 0 12-5.373 12-12v-10c0-6.627-5.373-12-12-12H60.113L238.607 60.506c4.686-4.686 4.686-12.284 0-16.971l-7.071-7.07c-4.686-4.686-12.284-4.686-16.97 0L3.515 247.515c-4.686 4.686-4.686 12.284 0 16.971l211.051 211.05c4.686 4.686 12.284 4.686 16.97-.001z" fill="#3d4852"/></svg>
                            </a>
                        </div>
    
                        @if (Auth::check())
                            <div class="flex-1 text-right">
                                <lock-button></lock-button>
                                <subscribe-button :active="{{ json_encode($thread->isSubscribedTo) }}"></subscribe-button>
                            </div>
                        @endif
                    </div>
                </nav>
    
                <article>
                    <img src="/images/news.jpg" class="h-72 w-full rounded object-cover shadow">
    
                    <div class="flex flex-row py-4">
                        <div class="flex-1 text-left">
                            <a href="{{ route('profile', $thread->creator) }}" class="no-underline text-grey-darkest hover:text-blue transition"><p class="text-sm">{{ $thread->creator->name }}</p></a>
                        </div>
                        <div class="flex-1 text-right">
                            <p class="text-sm text-grey-darkest">{{ $thread->updated_at->diffForHumans() }}</p>
                        </div>
                    </div>
    
                    <h1 class="py-4 text-black">{{ $thread->title }}</h1>
                    <p class="leading-normal">{{ $thread->body }}</p>
    
    
                    <div class="pt-12 pb-6">
                        <ul class="list-reset flex">
                            <li class="pr-4">
                                <p class="text-grey-dark text-sm">
                                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" height="13px" width="13px" class="inline-flex"><path d="M288 288a64 64 0 0 0 0-128c-1 0-1.88.24-2.85.29a47.5 47.5 0 0 1-60.86 60.86c0 1-.29 1.88-.29 2.85a64 64 0 0 0 64 64zm284.52-46.6C518.29 135.59 410.93 64 288 64S57.68 135.64 3.48 241.41a32.35 32.35 0 0 0 0 29.19C57.71 376.41 165.07 448 288 448s230.32-71.64 284.52-177.41a32.35 32.35 0 0 0 0-29.19zM288 96a128 128 0 1 1-128 128A128.14 128.14 0 0 1 288 96zm0 320c-107.36 0-205.46-61.31-256-160a294.78 294.78 0 0 1 129.78-129.33C140.91 153.69 128 187.17 128 224a160 160 0 0 0 320 0c0-36.83-12.91-70.31-33.78-97.33A294.78 294.78 0 0 1 544 256c-50.53 98.69-148.64 160-256 160z" fill="#8795a1"/></svg>
                                    <span class="self-center">{{ $thread->visits }}</span>
                                </p>
                            </li>
                            <li>
                                <p class="text-grey-dark text-sm">
                                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" height="13px" width="13px" class="inline-flex"><path d="M569.9 441.1c-.5-.4-22.6-24.2-37.9-54.9 27.5-27.1 44-61.1 44-98.2 0-80-76.5-146.1-176.2-157.9C368.4 72.5 294.3 32 208 32 93.1 32 0 103.6 0 192c0 37 16.5 71 44 98.2-15.3 30.7-37.3 54.5-37.7 54.9-6.3 6.7-8.1 16.5-4.4 25 3.6 8.5 12 14 21.2 14 53.5 0 96.7-20.2 125.2-38.8 9.1 2.1 18.4 3.7 28 4.8 31.5 57.5 105.5 98 191.8 98 20.8 0 40.8-2.4 59.8-6.8 28.5 18.5 71.6 38.8 125.2 38.8 9.2 0 17.5-5.5 21.2-14 3.6-8.5 1.9-18.3-4.4-25zM155.4 314l-13.2-3-11.4 7.4c-20.1 13.1-50.5 28.2-87.7 32.5 8.8-11.3 20.2-27.6 29.5-46.4L83 283.7l-16.5-16.3C50.7 251.9 32 226.2 32 192c0-70.6 79-128 176-128s176 57.4 176 128-79 128-176 128c-17.7 0-35.4-2-52.6-6zm289.8 100.4l-11.4-7.4-13.2 3.1c-17.2 4-34.9 6-52.6 6-65.1 0-122-25.9-152.4-64.3C326.9 348.6 416 278.4 416 192c0-9.5-1.3-18.7-3.3-27.7C488.1 178.8 544 228.7 544 288c0 34.2-18.7 59.9-34.5 75.4L493 379.7l10.3 20.7c9.4 18.9 20.8 35.2 29.5 46.4-37.1-4.2-67.5-19.4-87.6-32.4z" fill="#8795a1"/></svg>
                                    <span v-text="repliesCount" class="self-center"></span>
                                </p>
                            </li>
                        </ul>
                    </div>
                </article>
                
                <section id="replies">
                    <div class="bg-white rounded-t-lg shadow-md px-6 pb-8">
                        <replies @added="repliesCount++" @removed="repliesCount--"></replies>
                    </div>
                </section>
            </div>
        </thread-view>
    @endsection
    

    hjortur17 left a reply on Authorization With Vue

    Any ideas?

    20 May
    1 month ago

    hjortur17 started a new conversation Authorization With Vue

    Hi, I'm trying to create Vue Component and to make this component function correctly I need to do authorization. On my User.php I have isAdmin method and a middleware called admin but in Vue I need to check if the sign in user has a role = admin

    Here is what I tried, (authorizations.js)

    let user = window.App.user;
    
    module.exports = {
        owns (model, prop = 'user_id') {
            return model[prop] === user.id;
        },
    
        isAdmin() {
            return ['admin'].includes(user.role);
        }
    };
    

    And this is in my master.blade.php:

    window.App ={!! json_encode([
                'signedIn' => Auth::check(),
                'user' => Auth::user(),
            ]) !!};
    

    And this in my bootstrap.js file:

    window.Vue = require('vue');
    
    let authorizations = require('./authorizations.js');
    
    Vue.prototype.authorize = function(...params) {
        if (! window.App.signedIn) return false;
    
        if (typeof params[0] === 'string') {
            return authorizations[params[0]](params[1]);
        }
    
        return params[0](window.App.user);
    };
    

    hjortur17 left a reply on Slug

    I looked thru Jeffreys code and pasted all in and it worked. Must have had been a typo.

    hjortur17 left a reply on Slug

    @KUNDEFINE - Will the slug nr. 3 be pass-your-title-1-2?

    19 May
    1 month ago
    18 May
    1 month ago

    hjortur17 left a reply on Slug

    This is the error I'm getting:

    Illuminate\Database\QueryException: SQLSTATE[23000]: Integrity constraint violation: 19 UNIQUE constraint failed: threads.slug (SQL: insert into "threads" ("slug", "user_id", "channel_id", "title", "body", "updated_at", "created_at") values (foo-title-2, 1, 1, Foo Title, Exercitationem omnis rem fugit quos alias occaecati. Quisquam laborum vero aut molestias eligendi ducimus quisquam. Sit id voluptate quod beatae. Aut nam quia molestiae quia ut., 2019-05-18 21:33:44, 2019-05-18 21:33:44))
    

    hjortur17 left a reply on Slug

    @SNAPEY - Yeah I’m following this tutorial

    hjortur17 left a reply on Laravel And Mailtrap.io

    @CRONIX - When I put your code in my tinker I received an email, I also changed my RegisterController.php to this and it worked.

    protected function create(array $data)
        {
            $user = User::create([
                'name' => $data['name'],
                'username' => $data['username'],
                'social_id' => $data['social_id'],
                'email' => $data['email'],
                'password' => Hash::make($data['password']),
            ]);
    
            $user->sendEmailVerificationNotification();
    
            return $user;
        }
    

    hjortur17 left a reply on Laravel And Mailtrap.io

    @CRONIX - And how do I do that?

    hjortur17 left a reply on Laravel And Mailtrap.io

    @CRONIX - I'm checking on mailtrap website

    hjortur17 left a reply on Laravel And Mailtrap.io

    @CRONIX - But if I try to paste this in my tinker locally I get null

    hjortur17 left a reply on Laravel And Mailtrap.io

    @CRONIX - The site isn't live, I'm still developing

    hjortur17 started a new conversation Slug

    Hello, I'm trying to use slug for my threads. I have a script to check if the slug and then add to it a number if somewhere in my forum a thread has the same title and slug. For example:

    foo-bar
    foo-bar-2
    foo-bar-3
    

    And here is my test:

    /** @test */
        function a_thread_requires_a_unique_slug()
        {
            $this->signIn();
    
            $thread = create('App\Thread', ['title' => 'Foo Title', 'slug' => 'foo-title']);
    
            $this->assertEquals($thread->fresh()->slug, 'foo-title');
    
            $this->post('/fréttir', $thread->toArray());
    
            $this->assertTrue(Thread::whereSlug('foo-title-2')->exists());
    
            $this->post('/fréttir', $thread->toArray());
    
            $this->assertTrue(Thread::whereSlug('foo-title-3')->exists());
        }
    

    And here is my function inside Thread.php

    public function getRouteKeyName()
        {
            return 'slug';
        }
    
        public function setSlugAttribute($value)
        {
            if (static::whereSlug($slug = str_slug($value))->exists()) {
                $slug = $this->incrementSlug($slug);
            }
        
            $this->attributes['slug'] = $slug;
        }
    
        protected function incrementSlug($slug)
        {
            $max = static::whereTitle($this->title)->latest('id')->value('slug');
            
            if (is_numeric($max[-1])) {
                return preg_replace_callback('/(\d+)$/', function ($matches) {
                    return $matches[1] + 1;
                }, $max);
            }
        
            return "{$slug}-2";
        }
    

    hjortur17 left a reply on Laravel And Mailtrap.io

    @CLICK - It's on sync

    hjortur17 left a reply on Laravel And Mailtrap.io

    @CLICK - How do I know that? I just followed Laravel steps of using Confirm Email

    hjortur17 left a reply on Laravel And Mailtrap.io

    There is no log file for today.

    hjortur17 left a reply on Laravel And Mailtrap.io

    It's not working, I have tried adding your @cronix solution​ but it's not working and I don't have any # in my .env

    hjortur17 left a reply on Laravel And Mailtrap.io

    @FAHADKHAN1740 - Yes, multiple​ times.

    hjortur17 left a reply on Laravel And Mailtrap.io

    So I'm trying to getting the user to confirm their email, I used Laravel to do it. So I'm not getting any errors but if I go on a page that you need to confirm before seeing it looks like Laravel has​ sent​ the mail.