Support changing texture model from skinlib
This commit is contained in:
parent
bcf8710019
commit
e0c7292d35
|
|
@ -295,6 +295,35 @@ class SkinlibController extends Controller
|
|||
}
|
||||
} // @codeCoverageIgnore
|
||||
|
||||
public function model(Request $request) {
|
||||
$this->validate($request, [
|
||||
'tid' => 'required|integer',
|
||||
'model' => 'required|in:steve,alex,cape'
|
||||
]);
|
||||
|
||||
$t = Texture::find($request->input('tid'));
|
||||
|
||||
if (! $t)
|
||||
return json(trans('skinlib.non-existent'), 1);
|
||||
|
||||
if ($t->uploader != $this->user->uid && !$this->user->isAdmin())
|
||||
return json(trans('skinlib.no-permission'), 1);
|
||||
|
||||
$duplicate = Texture::where('hash', $t->hash)
|
||||
->where('type', $request->input('model'))
|
||||
->where('tid', '<>', $t->tid)
|
||||
->first();
|
||||
|
||||
if ($duplicate && $duplicate->public) {
|
||||
return json(trans('skinlib.model.duplicate', ['tid' => $duplicate->tid]), 1);
|
||||
}
|
||||
|
||||
$t->type = $request->input('model');
|
||||
$t->save();
|
||||
|
||||
return json(trans('skinlib.model.success', ['model' => request('model')]), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check Uploaded Files
|
||||
*
|
||||
|
|
|
|||
|
|
@ -506,3 +506,15 @@ if (! function_exists('report')) {
|
|||
app(Illuminate\Contracts\Debug\ExceptionHandler::class)->report($exception);
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('can_moderate_texture')) {
|
||||
|
||||
function can_moderate_texture($user, $texture) {
|
||||
if (! $user) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Only uploader and admins can moderate textures
|
||||
return ($texture->uploader == $user->uid || $user->isAdmin());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -503,6 +503,57 @@ describe('tests for "operations" module', () => {
|
|||
expect(showAjaxError).toBeCalled();
|
||||
});
|
||||
|
||||
it('change texture model', async () => {
|
||||
const fetch = jest.fn()
|
||||
.mockReturnValueOnce(Promise.resolve({ errno: 0, msg: 'success' }))
|
||||
.mockReturnValueOnce(Promise.resolve({ errno: 1, msg: 'warning' }))
|
||||
.mockReturnValueOnce(Promise.reject());
|
||||
window.fetch = fetch;
|
||||
const url = jest.fn(path => path);
|
||||
window.url = url;
|
||||
const trans = jest.fn(key => key);
|
||||
window.trans = trans;
|
||||
const swal = jest.fn()
|
||||
.mockImplementationOnce(() => Promise.reject())
|
||||
.mockImplementationOnce(() => Promise.resolve('alex'));
|
||||
window.swal = swal;
|
||||
const modal = jest.fn();
|
||||
const toastr = {
|
||||
success: jest.fn(),
|
||||
warning: jest.fn()
|
||||
};
|
||||
window.toastr = toastr;
|
||||
const showAjaxError = jest.fn();
|
||||
window.showAjaxError = showAjaxError;
|
||||
|
||||
document.body.innerHTML = '<div id="model"></div>';
|
||||
const changeTextureModel = require(modulePath).changeTextureModel;
|
||||
|
||||
await changeTextureModel(1, 'steve');
|
||||
expect(fetch).not.toBeCalled();
|
||||
|
||||
await changeTextureModel(1, 'steve');
|
||||
expect(swal).toBeCalledWith(expect.objectContaining({
|
||||
text: trans('skinlib.setNewTextureModel'),
|
||||
input: 'select',
|
||||
inputValue: 'steve',
|
||||
}));
|
||||
expect(fetch).toBeCalledWith({
|
||||
type: 'POST',
|
||||
url: 'skinlib/model',
|
||||
dataType: 'json',
|
||||
data: { tid: 1, model: 'alex' }
|
||||
});
|
||||
expect($('div').text()).toBe('alex');
|
||||
expect(toastr.success).toBeCalledWith('success');
|
||||
|
||||
await changeTextureModel(1, 'steve');
|
||||
expect(toastr.warning).toBeCalledWith('warning');
|
||||
|
||||
await changeTextureModel(1, 'steve');
|
||||
expect(showAjaxError).toBeCalled();
|
||||
});
|
||||
|
||||
it('update texture status', () => {
|
||||
window.trans = jest.fn(key => key);
|
||||
document.body.innerHTML = `
|
||||
|
|
|
|||
|
|
@ -130,6 +130,47 @@ async function changeTextureName(tid, oldName) {
|
|||
}
|
||||
}
|
||||
|
||||
async function changeTextureModel(tid, oldModel) {
|
||||
const models = {
|
||||
steve: 'steve',
|
||||
alex: 'alex',
|
||||
cape: trans('general.cape')
|
||||
};
|
||||
|
||||
let newTextureModel = '';
|
||||
|
||||
try {
|
||||
newTextureModel = await swal({
|
||||
text: trans('skinlib.setNewTextureModel'),
|
||||
input: 'select',
|
||||
inputValue: oldModel,
|
||||
inputOptions: models,
|
||||
showCancelButton: true,
|
||||
inputClass: 'form-control'
|
||||
});
|
||||
} catch (error) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const { errno, msg } = await fetch({
|
||||
type: 'POST',
|
||||
url: url('skinlib/model'),
|
||||
dataType: 'json',
|
||||
data: { tid: tid, model: newTextureModel }
|
||||
});
|
||||
|
||||
if (errno === 0) {
|
||||
$('#model').text(models[newTextureModel]);
|
||||
toastr.success(msg);
|
||||
} else {
|
||||
toastr.warning(msg);
|
||||
}
|
||||
} catch (error) {
|
||||
showAjaxError(error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update button action & likes of texture.
|
||||
*
|
||||
|
|
@ -231,6 +272,7 @@ if (process.env.NODE_ENV === 'test') {
|
|||
ajaxAddToCloset,
|
||||
removeFromCloset,
|
||||
changeTextureName,
|
||||
changeTextureModel,
|
||||
updateTextureStatus,
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,6 +47,9 @@
|
|||
setNewTextureName: 'Please enter the new texture name:',
|
||||
emptyNewTextureName: 'Empty new texture name.',
|
||||
|
||||
// Change Model
|
||||
setNewTextureModel: 'Please select a new texture model:',
|
||||
|
||||
// Skinlib
|
||||
filter: {
|
||||
skin: '(Any Model)',
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ show:
|
|||
|
||||
detail: Details
|
||||
name: Texture Name
|
||||
edit-name: Edit Name
|
||||
edit: Edit
|
||||
model: Applicable Model
|
||||
download-raw: Click to download raw texture
|
||||
size: File Size
|
||||
|
|
@ -85,10 +85,14 @@ privacy:
|
|||
change-privacy: Change Privacy
|
||||
set-as-private: Set as Private
|
||||
set-as-public: Set as Public
|
||||
success: The texture was setted to :privacy successfully.
|
||||
success: The texture was set to :privacy successfully.
|
||||
|
||||
rename:
|
||||
success: The texture was renamed to :name successfully.
|
||||
|
||||
model:
|
||||
success: The texture's model was changed to :model successfully.
|
||||
duplicate: "The same texture available for the chosen model already exists in skinlib (TID: :tid). You can add it to your closet directly."
|
||||
|
||||
no-permission: You aren't the uploader of this texture.
|
||||
non-existent: Non-existent texture.
|
||||
|
|
|
|||
|
|
@ -67,6 +67,9 @@
|
|||
setNewTextureName: '请输入新的材质名称:',
|
||||
emptyNewTextureName: '你还没有输入新名称啊',
|
||||
|
||||
// Change Model
|
||||
setNewTextureModel: '请选择新的材质适用模型:',
|
||||
|
||||
// Upload
|
||||
emptyTextureName: '给你的材质起个名字吧',
|
||||
emptyTextureType: '请选择材质的类型',
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ show:
|
|||
|
||||
detail: 详细信息
|
||||
name: 名称
|
||||
edit-name: 修改名称
|
||||
edit: 修改
|
||||
model: 适用模型
|
||||
download-raw: 右键另存为即可下载原始皮肤文件
|
||||
size: 文件大小
|
||||
|
|
@ -89,5 +89,9 @@ privacy:
|
|||
rename:
|
||||
success: 材质名称已被成功设置为 :name
|
||||
|
||||
model:
|
||||
success: 材质的适用模型已被修改为 :model
|
||||
duplicate: 已经有人上传过适用于该模型的相同材质了,直接去皮肤库收藏使用吧(TID::tid)
|
||||
|
||||
no-permission: 你不是这个材质的上传者哦
|
||||
non-existent: 材质不存在
|
||||
|
|
|
|||
|
|
@ -48,10 +48,11 @@
|
|||
<tbody>
|
||||
<tr>
|
||||
<td>{{ trans('skinlib.show.name') }}</td>
|
||||
<td id="name">{{ $texture->name }}
|
||||
@if (!is_null($user) && ($texture->uploader == $user->uid || $user->isAdmin()))
|
||||
<td>
|
||||
<span id="name">{{ $texture->name }}</span>
|
||||
@if (can_moderate_texture($user, $texture))
|
||||
<small>
|
||||
<a style="cursor: pointer" onclick="changeTextureName({{ $texture->tid }}, '{{ $texture->name }}');">{{ trans('skinlib.show.edit-name') }}</a>
|
||||
<a style="cursor: pointer" onclick="changeTextureName({{ $texture->tid }}, '{{ $texture->name }}');">{{ trans('skinlib.show.edit') }}</a>
|
||||
</small>
|
||||
@endif
|
||||
</td>
|
||||
|
|
@ -59,10 +60,11 @@
|
|||
<tr>
|
||||
<td>{{ trans('skinlib.show.model') }}</td>
|
||||
<td>
|
||||
@if ($texture->type == 'cape')
|
||||
{{ trans('general.cape') }}
|
||||
@else
|
||||
{{ $texture->type }}
|
||||
<span id="model">{{ $texture->type == 'cape' ? trans('general.cape') : $texture->type }}</span>
|
||||
@if (can_moderate_texture($user, $texture))
|
||||
<small>
|
||||
<a style="cursor: pointer" onclick="changeTextureModel({{ $texture->tid }}, '{{ $texture->type }}');">{{ trans('skinlib.show.edit') }}</a>
|
||||
</small>
|
||||
@endif
|
||||
</td>
|
||||
</tr>
|
||||
|
|
|
|||
|
|
@ -86,6 +86,7 @@ Route::group(['prefix' => 'skinlib'], function ()
|
|||
Route::post('/upload', 'SkinlibController@handleUpload');
|
||||
|
||||
Route::post('/rename', 'SkinlibController@rename');
|
||||
Route::post('/model', 'SkinlibController@model');
|
||||
Route::post('/privacy', 'SkinlibController@privacy');
|
||||
Route::post('/delete', 'SkinlibController@delete');
|
||||
});
|
||||
|
|
|
|||
|
|
@ -933,4 +933,73 @@ class SkinlibControllerTest extends TestCase
|
|||
]);
|
||||
$this->assertEquals('new_name', Texture::find($texture->tid)->name);
|
||||
}
|
||||
|
||||
public function testChangeModel()
|
||||
{
|
||||
$uploader = factory(User::class)->create();
|
||||
$other = factory(User::class)->create();
|
||||
$texture = factory(Texture::class)->create(['uploader' => $uploader->uid]);
|
||||
|
||||
// Non-existed texture
|
||||
$this->actAs($uploader)
|
||||
->post('/skinlib/model', [
|
||||
'tid' => -1,
|
||||
'model' => 'alex'
|
||||
])
|
||||
->seeJson([
|
||||
'errno' => 1,
|
||||
'msg' => trans('skinlib.non-existent')
|
||||
]);
|
||||
|
||||
// Other user should not be able to change model
|
||||
$this->actAs($other)
|
||||
->post('/skinlib/model', [
|
||||
'tid' => $texture->tid,
|
||||
'model' => 'alex'
|
||||
])
|
||||
->seeJson([
|
||||
'errno' => 1,
|
||||
'msg' => trans('skinlib.no-permission')
|
||||
]);
|
||||
|
||||
// Administrators should be able to change model
|
||||
$this->actAs('admin')
|
||||
->post('/skinlib/model', [
|
||||
'tid' => $texture->tid,
|
||||
'model' => 'alex'
|
||||
])
|
||||
->seeJson([
|
||||
'errno' => 0,
|
||||
'msg' => trans('skinlib.model.success', ['model' => 'alex'])
|
||||
]);
|
||||
$this->assertEquals('alex', Texture::find($texture->tid)->type);
|
||||
|
||||
// Uploader should be able to change model
|
||||
$this->actAs($uploader)
|
||||
->post('/skinlib/model', [
|
||||
'tid' => $texture->tid,
|
||||
'model' => 'steve'
|
||||
])
|
||||
->seeJson([
|
||||
'errno' => 0,
|
||||
'msg' => trans('skinlib.model.success', ['model' => 'steve'])
|
||||
]);
|
||||
$this->assertEquals('steve', Texture::find($texture->tid)->type);
|
||||
|
||||
$duplicate = factory(Texture::class, 'alex')->create([
|
||||
'uploader' => $other->uid,
|
||||
'hash' => $texture->hash
|
||||
]);
|
||||
|
||||
// Should fail if there is already a texture with same hash and chosen model
|
||||
$this->actAs($uploader)
|
||||
->post('/skinlib/model', [
|
||||
'tid' => $texture->tid,
|
||||
'model' => 'alex'
|
||||
])
|
||||
->seeJson([
|
||||
'errno' => 1,
|
||||
'msg' => trans('skinlib.model.duplicate', ['tid' => $duplicate->tid])
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user