diff --git a/web/app/Http/Controllers/Api/FeedController.php b/web/app/Http/Controllers/Api/FeedController.php index 7e97f52..8677201 100644 --- a/web/app/Http/Controllers/Api/FeedController.php +++ b/web/app/Http/Controllers/Api/FeedController.php @@ -9,26 +9,13 @@ use App\Models\User; use Carbon\Carbon; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; -use Illuminate\Support\Facades\DB; class FeedController extends Controller { protected function listjson() { // TODO: XlXi: Group shouts. - $postsQuery = Shout::where([['poster_type', 'user'], ['deleted', '0']]) - ->where(function($query) { - $query->where('poster_id', Auth::id()) - ->orWhereExists(function($query) { - $query->select(DB::raw('*')) - ->from('friends') - ->where('accepted', 1) - ->where(function($query) { - $query->whereColumn('shouts.poster_id', 'friends.sender_id') - ->orWhereColumn('shouts.poster_id', 'friends.receiver_id'); - }); - }); - }) + $postsQuery = Shout::getPosts() ->orderByDesc('created_at') ->cursorPaginate(15); diff --git a/web/app/Http/Controllers/Api/ShopController.php b/web/app/Http/Controllers/Api/ShopController.php index 43903fd..1f3dc1b 100644 --- a/web/app/Http/Controllers/Api/ShopController.php +++ b/web/app/Http/Controllers/Api/ShopController.php @@ -10,10 +10,36 @@ use Illuminate\Support\Facades\Validator; class ShopController extends Controller { + protected $validAssetTypeIds = [ + '2', // T-Shirts + '8', // Hats + '11', // Shirts + '12', // Pants + '17', // Heads + '18', // Faces + '19', // Gear + '32' // Packages + ]; + protected static function generateValidatorError($validator) { return response(ValidationHelper::generateErrorJSON($validator), 400); } + protected function getAssets($assetTypeIds, $gearGenre=null) + { + // TODO: XlXi: IMPORTANT!! Do not return raw DB response, return only needed values. + return Asset::where('approved', true) + ->where('moderated', false) + ->where('onSale', true) + ->where(function($query) use($assetTypeIds, $gearGenre) { + $query->whereIn('assetTypeId', explode(',', $assetTypeIds)); + + if ($gearGenre != null) + $query->whereIn('assetAttributeId', explode(',', $gearGenre)); + }) + ->get(); + } + protected function listjson(Request $request) { $validator = Validator::make($request->all(), [ @@ -27,13 +53,23 @@ class ShopController extends Controller $valid = $validator->valid(); + foreach(explode(',', $valid['assetTypeId']) as $assetTypeId) { + if(!in_array($assetTypeId, $this->validAssetTypeIds)) { + $validator->errors()->add('assetTypeId', 'Invalid assetTypeId supplied.'); + return ShopController::generateValidatorError($validator); + } + } + if($valid['assetTypeId'] != '19' && isset($valid['gearGenreId'])) { - $validator->errors()->add('gearGenreId', 'gearGenreId can only be used with typeId 19.'); + $validator->errors()->add('gearGenreId', 'gearGenreId can only be used with assetTypeId 19.'); return ShopController::generateValidatorError($validator); } + $assets = $this->getAssets($valid['assetTypeId'], (isset($valid['gearGenreId']) ? $valid['gearGenreId'] : null)); + return response([ - 'data' => [], + 'pages' => 123, + 'data' => $assets, 'next_cursor' => null, 'prev_cursor' => null ]); diff --git a/web/app/Models/Shout.php b/web/app/Models/Shout.php index 5312e3a..e8d15b1 100644 --- a/web/app/Models/Shout.php +++ b/web/app/Models/Shout.php @@ -4,6 +4,8 @@ namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; +use Illuminate\Support\Facades\Auth; +use Illuminate\Support\Facades\DB; class Shout extends Model { @@ -18,4 +20,21 @@ class Shout extends Model 'created_at' => 'datetime', 'updated_at' => 'datetime', ]; + + protected static function getPosts() + { + return self::where([['poster_type', 'user'], ['deleted', '0']]) + ->where(function($query) { + $query->where('poster_id', Auth::id()) + ->orWhereExists(function($query) { + $query->select(DB::raw('*')) + ->from('friends') + ->where('accepted', 1) + ->where(function($query) { + $query->whereColumn('shouts.poster_id', 'friends.sender_id') + ->orWhereColumn('shouts.poster_id', 'friends.receiver_id'); + }); + }); + }); + } } diff --git a/web/app/Models/asset.php b/web/app/Models/asset.php index 7d4bcf3..2fde861 100644 --- a/web/app/Models/asset.php +++ b/web/app/Models/asset.php @@ -4,8 +4,32 @@ namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; +use App\Models\AssetVersion; class Asset extends Model { use HasFactory; + + public function user() + { + return $this->belongsTo(User::class, 'creatorId'); + } + + public function latestVersion() + { + return $this->belongsTo(AssetVersion::class, 'assetVersionId'); + } + + // Version 0 is internally considered the latest. + public function getContent($version = 0) + { + if($version === 0) + return $this->latestVersion()->contentURL; + + $assetVersion = AssetVersion::where('parentAsset', $this->id) + ->where('localVersion', $version) + ->get(); + + return ($assetVersion !== null ? $assetVersion->contentURL : null); + } } diff --git a/web/resources/js/components/Shop.js b/web/resources/js/components/Shop.js index 08deddd..a1690e4 100644 --- a/web/resources/js/components/Shop.js +++ b/web/resources/js/components/Shop.js @@ -201,6 +201,8 @@ class Shop extends Component { selectedCategoryId: -1, pageItems: [], pageLoaded: true, + pageNumber: null, + pageCount: null, error: false }; @@ -235,7 +237,7 @@ class Shop extends Component { } navigateCategory(categoryId, data) { - this.setState({selectedCategoryId: categoryId, pageLoaded: false}); + this.setState({selectedCategoryId: categoryId, pageLoaded: false, pageNumber: null, pageCount: null}); let url = buildGenericApiUrl('api', 'catalog/v1/list-json'); let paramIterator = 0; @@ -252,15 +254,17 @@ class Shop extends Component { const items = res.data; this.nextCursor = items.next_cursor; - this.setState({ pageItems: items.data, pageLoaded: true, error: false }); + this.prevCursor = items.prev_cursor; + + this.setState({ pageItems: items.data, pageCount: items.pages, pageNumber: 1, pageLoaded: true, error: false }); }).catch(err => { - const data = err.response; + const data = err.response.data; let errorMessage = 'An error occurred while processing your request.'; if(data.errors) errorMessage = data.errors[0].message; - this.setState({ pageItems: [], pageLoaded: true, error: errorMessage }); + this.setState({ pageItems: [], pageCount: null, pageNumber: null, pageLoaded: true, error: errorMessage }); this.inputBox.current.focus(); }); } @@ -323,15 +327,15 @@ class Shop extends Component {