Merge remote-tracking branch 'upstream/develop' into api-tags
This commit is contained in:
commit
a6d060b0e4
|
@ -47,6 +47,7 @@ These endpoints use the [Mastodon API entities](https://docs.joinmastodon.org/en
|
|||
- [`POST /api/v1/accounts/:id/unmute`](https://docs.joinmastodon.org/methods/accounts/)
|
||||
- [`GET /api/v1/accounts/relationships`](https://docs.joinmastodon.org/methods/accounts/)
|
||||
- [`GET /api/v1/accounts/search`](https://docs.joinmastodon.org/methods/accounts)
|
||||
- [`PATCH /api/v1/accounts/update_credentials`](https://docs.joinmastodon.org/methods/accounts/#update_credentials)
|
||||
- [`GET /api/v1/accounts/verify_credentials`](https://docs.joinmastodon.org/methods/accounts)
|
||||
- [`POST /api/v1/apps`](https://docs.joinmastodon.org/methods/apps/)
|
||||
- [`GET /api/v1/apps/verify_credentials`](https://docs.joinmastodon.org/methods/apps/)
|
||||
|
@ -138,7 +139,6 @@ These endpoints use the [Mastodon API entities](https://docs.joinmastodon.org/en
|
|||
|
||||
These emdpoints are planned to be implemented somewhere in the future.
|
||||
|
||||
- [`PATCH /api/v1/accounts/update_credentials`](https://docs.joinmastodon.org/methods/accounts/)
|
||||
- [`POST /api/v1/accounts/:id/remove_from_followers`](https://github.com/mastodon/mastodon/pull/16864)
|
||||
- [`GET /api/v1/accounts/familiar_followers`](https://github.com/mastodon/mastodon/pull/17700)
|
||||
- [`GET /api/v1/accounts/lookup`](https://github.com/mastodon/mastodon/pull/15740)
|
||||
|
|
160
mod/fbrowser.php
160
mod/fbrowser.php
|
@ -1,160 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2022, the Friendica project
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @package Friendica\modules
|
||||
* @subpackage FileBrowser
|
||||
* @author Fabio Comuni <fabrixxm@kirgroup.com>
|
||||
*/
|
||||
|
||||
use Friendica\App;
|
||||
use Friendica\Core\Renderer;
|
||||
use Friendica\Core\System;
|
||||
use Friendica\Database\DBA;
|
||||
use Friendica\DI;
|
||||
use Friendica\Model\Photo;
|
||||
use Friendica\Util\Images;
|
||||
use Friendica\Util\Strings;
|
||||
|
||||
/**
|
||||
* @param App $a
|
||||
* @return string
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
*/
|
||||
function fbrowser_content(App $a)
|
||||
{
|
||||
if (!DI::userSession()->getLocalUserId()) {
|
||||
System::exit();
|
||||
}
|
||||
|
||||
if (DI::args()->getArgc() == 1) {
|
||||
System::exit();
|
||||
}
|
||||
|
||||
// Needed to match the correct template in a module that uses a different theme than the user/site/default
|
||||
$theme = Strings::sanitizeFilePathItem($_GET['theme'] ?? '');
|
||||
if ($theme && is_file("view/theme/$theme/config.php")) {
|
||||
$a->setCurrentTheme($theme);
|
||||
}
|
||||
|
||||
$template_file = "filebrowser.tpl";
|
||||
|
||||
$o = '';
|
||||
|
||||
switch (DI::args()->getArgv()[1]) {
|
||||
case "image":
|
||||
$path = ['' => DI::l10n()->t('Photos')];
|
||||
$albums = false;
|
||||
$sql_extra = "";
|
||||
$sql_extra2 = " ORDER BY created DESC LIMIT 0, 10";
|
||||
|
||||
if (DI::args()->getArgc() == 2) {
|
||||
$photos = DBA::toArray(DBA::p("SELECT distinct(`album`) AS `album` FROM `photo` WHERE `uid` = ? AND NOT `photo-type` IN (?, ?)",
|
||||
DI::userSession()->getLocalUserId(),
|
||||
Photo::CONTACT_AVATAR,
|
||||
Photo::CONTACT_BANNER
|
||||
));
|
||||
|
||||
$albums = array_column($photos, 'album');
|
||||
}
|
||||
|
||||
if (DI::args()->getArgc() == 3) {
|
||||
$album = DI::args()->getArgv()[2];
|
||||
$sql_extra = sprintf("AND `album` = '%s' ", DBA::escape($album));
|
||||
$sql_extra2 = "";
|
||||
$path[$album] = $album;
|
||||
}
|
||||
|
||||
$r = DBA::toArray(DBA::p("SELECT `resource-id`, ANY_VALUE(`id`) AS `id`, ANY_VALUE(`filename`) AS `filename`, ANY_VALUE(`type`) AS `type`,
|
||||
min(`scale`) AS `hiq`, max(`scale`) AS `loq`, ANY_VALUE(`desc`) AS `desc`, ANY_VALUE(`created`) AS `created`
|
||||
FROM `photo` WHERE `uid` = ? $sql_extra AND NOT `photo-type` IN (?, ?)
|
||||
GROUP BY `resource-id` $sql_extra2",
|
||||
DI::userSession()->getLocalUserId(),
|
||||
Photo::CONTACT_AVATAR,
|
||||
Photo::CONTACT_BANNER
|
||||
));
|
||||
|
||||
function _map_files1($rr)
|
||||
{
|
||||
$a = DI::app();
|
||||
$types = Images::supportedTypes();
|
||||
$ext = $types[$rr['type']];
|
||||
$filename_e = $rr['filename'];
|
||||
|
||||
// Take the largest picture that is smaller or equal 640 pixels
|
||||
$photo = Photo::selectFirst(['scale'], ["`resource-id` = ? AND `height` <= ? AND `width` <= ?", $rr['resource-id'], 640, 640], ['order' => ['scale']]);
|
||||
$scale = $photo['scale'] ?? $rr['loq'];
|
||||
|
||||
return [
|
||||
DI::baseUrl() . '/photos/' . $a->getLoggedInUserNickname() . '/image/' . $rr['resource-id'],
|
||||
$filename_e,
|
||||
DI::baseUrl() . '/photo/' . $rr['resource-id'] . '-' . $scale . '.'. $ext,
|
||||
$rr['desc']
|
||||
];
|
||||
}
|
||||
$files = array_map("_map_files1", $r);
|
||||
|
||||
$tpl = Renderer::getMarkupTemplate($template_file);
|
||||
|
||||
$o = Renderer::replaceMacros($tpl, [
|
||||
'$type' => 'image',
|
||||
'$path' => $path,
|
||||
'$folders' => $albums,
|
||||
'$files' => $files,
|
||||
'$cancel' => DI::l10n()->t('Cancel'),
|
||||
'$nickname' => $a->getLoggedInUserNickname(),
|
||||
'$upload' => DI::l10n()->t('Upload')
|
||||
]);
|
||||
|
||||
break;
|
||||
case "file":
|
||||
if (DI::args()->getArgc()==2) {
|
||||
$files = DBA::selectToArray('attach', ['id', 'filename', 'filetype'], ['uid' => DI::userSession()->getLocalUserId()]);
|
||||
|
||||
function _map_files2($rr)
|
||||
{
|
||||
list($m1, $m2) = explode("/", $rr['filetype']);
|
||||
$filetype = ( (file_exists("images/icons/$m1.png"))?$m1:"zip");
|
||||
$filename_e = $rr['filename'];
|
||||
|
||||
return [DI::baseUrl() . '/attach/' . $rr['id'], $filename_e, DI::baseUrl() . '/images/icons/16/' . $filetype . '.png'];
|
||||
}
|
||||
$files = array_map("_map_files2", $files);
|
||||
|
||||
|
||||
$tpl = Renderer::getMarkupTemplate($template_file);
|
||||
$o = Renderer::replaceMacros($tpl, [
|
||||
'$type' => 'file',
|
||||
'$path' => ['' => DI::l10n()->t('Files')],
|
||||
'$folders' => false,
|
||||
'$files' => $files,
|
||||
'$cancel' => DI::l10n()->t('Cancel'),
|
||||
'$nickname' => $a->getLoggedInUserNickname(),
|
||||
'$upload' => DI::l10n()->t('Upload')
|
||||
]);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (!empty($_GET['mode'])) {
|
||||
return $o;
|
||||
} else {
|
||||
System::httpExit($o);
|
||||
}
|
||||
}
|
|
@ -85,6 +85,8 @@ class Arguments
|
|||
|
||||
/**
|
||||
* @return string The module name based on the arguments
|
||||
* @deprecated 2022.12 - With the new (sub-)routes, it's not trustworthy anymore, use the ModuleClass instead
|
||||
* @see Router::getModuleClass()
|
||||
*/
|
||||
public function getModuleName(): string
|
||||
{
|
||||
|
|
|
@ -40,6 +40,7 @@ use Friendica\Module\HTTPException\MethodNotAllowed;
|
|||
use Friendica\Module\HTTPException\PageNotFound;
|
||||
use Friendica\Module\Special\Options;
|
||||
use Friendica\Network\HTTPException;
|
||||
use Friendica\Network\HTTPException\InternalServerErrorException;
|
||||
use Friendica\Network\HTTPException\MethodNotAllowedException;
|
||||
use Friendica\Network\HTTPException\NotFoundException;
|
||||
use Friendica\Util\Router\FriendicaGroupCountBased;
|
||||
|
@ -114,6 +115,9 @@ class Router
|
|||
/** @var array */
|
||||
private $server;
|
||||
|
||||
/** @var string|null */
|
||||
protected $moduleClass = null;
|
||||
|
||||
/**
|
||||
* @param array $server The $_SERVER variable
|
||||
* @param string $baseRoutesFilepath The path to a base routes file to leverage cache, can be empty
|
||||
|
@ -216,7 +220,7 @@ class Router
|
|||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function isGroup(array $config)
|
||||
private function isGroup(array $config): bool
|
||||
{
|
||||
return
|
||||
is_array($config) &&
|
||||
|
@ -252,21 +256,39 @@ class Router
|
|||
*
|
||||
* @return RouteCollector|null
|
||||
*/
|
||||
public function getRouteCollector()
|
||||
public function getRouteCollector(): ?RouteCollector
|
||||
{
|
||||
return $this->routeCollector;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Friendica\BaseModule-extending class name if a route rule matched
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @throws InternalServerErrorException
|
||||
* @throws MethodNotAllowedException
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function getModuleClass(): string
|
||||
{
|
||||
if (empty($this->moduleClass)) {
|
||||
$this->determineModuleClass();
|
||||
}
|
||||
|
||||
return $this->moduleClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the relevant module class name for the given page URI or NULL if no route rule matched.
|
||||
*
|
||||
* @return string A Friendica\BaseModule-extending class name if a route rule matched
|
||||
* @return void
|
||||
*
|
||||
* @throws HTTPException\InternalServerErrorException
|
||||
* @throws HTTPException\MethodNotAllowedException If a rule matched but the method didn't
|
||||
* @throws HTTPException\NotFoundException If no rule matched
|
||||
*/
|
||||
private function getModuleClass(): string
|
||||
private function determineModuleClass(): void
|
||||
{
|
||||
$cmd = $this->args->getCommand();
|
||||
$cmd = '/' . ltrim($cmd, '/');
|
||||
|
@ -277,21 +299,19 @@ class Router
|
|||
|
||||
// Check if the HTTP method is OPTIONS and return the special Options Module with the possible HTTP methods
|
||||
if ($this->args->getMethod() === static::OPTIONS) {
|
||||
$moduleClass = Options::class;
|
||||
$this->parameters = ['allowedMethods' => $dispatcher->getOptions($cmd)];
|
||||
$this->moduleClass = Options::class;
|
||||
$this->parameters = ['allowedMethods' => $dispatcher->getOptions($cmd)];
|
||||
} else {
|
||||
$routeInfo = $dispatcher->dispatch($this->args->getMethod(), $cmd);
|
||||
if ($routeInfo[0] === Dispatcher::FOUND) {
|
||||
$moduleClass = $routeInfo[1];
|
||||
$this->parameters = $routeInfo[2];
|
||||
$this->moduleClass = $routeInfo[1];
|
||||
$this->parameters = $routeInfo[2];
|
||||
} elseif ($routeInfo[0] === Dispatcher::METHOD_NOT_ALLOWED) {
|
||||
throw new HTTPException\MethodNotAllowedException($this->l10n->t('Method not allowed for this module. Allowed method(s): %s', implode(', ', $routeInfo[1])));
|
||||
} else {
|
||||
throw new HTTPException\NotFoundException($this->l10n->t('Page not found.'));
|
||||
}
|
||||
}
|
||||
|
||||
return $moduleClass;
|
||||
}
|
||||
|
||||
public function getModule(?string $module_class = null): ICanHandleRequests
|
||||
|
|
|
@ -568,7 +568,15 @@ class Worker
|
|||
|
||||
// Set the workerLogger as new default logger
|
||||
if ($method_call) {
|
||||
call_user_func_array(sprintf('Friendica\Worker\%s::execute', $funcname), $argv);
|
||||
try {
|
||||
call_user_func_array(sprintf('Friendica\Worker\%s::execute', $funcname), $argv);
|
||||
} catch (\TypeError $e) {
|
||||
// No need to defer a worker queue entry if the arguments are invalid
|
||||
Logger::notice('Wrong worker arguments', ['class' => $funcname, 'argv' => $argv, 'queue' => $queue, 'message' => $e->getMessage()]);
|
||||
} catch (\Throwable $e) {
|
||||
Logger::error('Uncaught exception in worker execution', ['class' => get_class($e), 'message' => $e->getMessage(), 'code' => $e->getCode(), 'file' => $e->getFile() . ':' . $e->getLine(), 'trace' => $e->getTraceAsString()]);
|
||||
Worker::defer();
|
||||
}
|
||||
} else {
|
||||
$funcname($argv, count($argv));
|
||||
}
|
||||
|
|
|
@ -76,16 +76,17 @@ class Status extends BaseFactory
|
|||
}
|
||||
|
||||
/**
|
||||
* @param int $uriId Uri-ID of the item
|
||||
* @param int $uid Item user
|
||||
* @param int $uriId Uri-ID of the item
|
||||
* @param int $uid Item user
|
||||
* @param bool $reblog Check for reblogged post
|
||||
*
|
||||
* @return \Friendica\Object\Api\Mastodon\Status
|
||||
* @throws HTTPException\InternalServerErrorException
|
||||
* @throws ImagickException|HTTPException\NotFoundException
|
||||
*/
|
||||
public function createFromUriId(int $uriId, int $uid = 0): \Friendica\Object\Api\Mastodon\Status
|
||||
public function createFromUriId(int $uriId, int $uid = 0, bool $reblog = true): \Friendica\Object\Api\Mastodon\Status
|
||||
{
|
||||
$fields = ['uri-id', 'uid', 'author-id', 'author-uri-id', 'author-link', 'starred', 'app', 'title', 'body', 'raw-body', 'content-warning', 'question-id',
|
||||
$fields = ['uri-id', 'uid', 'author-id', 'author-uri-id', 'author-link', 'causer-uri-id', 'post-reason', 'starred', 'app', 'title', 'body', 'raw-body', 'content-warning', 'question-id',
|
||||
'created', 'network', 'thr-parent-id', 'parent-author-id', 'language', 'uri', 'plink', 'private', 'vid', 'gravity', 'featured', 'has-media', 'quote-uri-id'];
|
||||
$item = Post::selectFirst($fields, ['uri-id' => $uriId, 'uid' => [0, $uid]], ['order' => ['uid' => true]]);
|
||||
if (!$item) {
|
||||
|
@ -95,7 +96,10 @@ class Status extends BaseFactory
|
|||
}
|
||||
throw new HTTPException\NotFoundException('Item with URI ID ' . $uriId . ' not found' . ($uid ? ' for user ' . $uid : '.'));
|
||||
}
|
||||
$account = $this->mstdnAccountFactory->createFromUriId($item['author-uri-id'], $uid);
|
||||
|
||||
$is_reshare = $reblog && !is_null($item['causer-uri-id']) && ($item['post-reason'] == Item::PR_ANNOUNCEMENT);
|
||||
|
||||
$account = $this->mstdnAccountFactory->createFromUriId($is_reshare ? $item['causer-uri-id']:$item['author-uri-id'], $uid);
|
||||
|
||||
$count_announce = Post::countPosts([
|
||||
'thr-parent-id' => $uriId,
|
||||
|
@ -183,6 +187,10 @@ class Status extends BaseFactory
|
|||
$reshare = [];
|
||||
}
|
||||
|
||||
if ($is_reshare) {
|
||||
$reshare = $this->createFromUriId($uriId, $uid, false)->toArray();
|
||||
}
|
||||
|
||||
return new \Friendica\Object\Api\Mastodon\Status($item, $account, $counts, $userAttributes, $sensitive, $application, $mentions, $tags, $card, $attachments, $reshare, $poll);
|
||||
}
|
||||
|
||||
|
|
|
@ -3420,8 +3420,7 @@ class Contact
|
|||
["(NOT `unsearchable` OR `nurl` IN (SELECT `nurl` FROM `owner-view` WHERE `publish` OR `net-publish`))
|
||||
AND (`addr` LIKE ? OR `name` LIKE ? OR `nick` LIKE ?)", $search, $search, $search]);
|
||||
|
||||
$contacts = self::selectToArray([], $condition, $params);
|
||||
return $contacts;
|
||||
return self::selectToArray([], $condition, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1213,7 +1213,7 @@ class GServer
|
|||
|
||||
if (!empty($data['url'])) {
|
||||
$serverdata['platform'] = strtolower($data['platform']);
|
||||
$serverdata['version'] = $data['version'];
|
||||
$serverdata['version'] = $data['version'] ?? 'N/A';
|
||||
}
|
||||
|
||||
if (!empty($data['plugins'])) {
|
||||
|
@ -2172,7 +2172,7 @@ class GServer
|
|||
foreach ($servers['instances'] as $server) {
|
||||
$url = (is_null($server['https_score']) ? 'http' : 'https') . '://' . $server['name'];
|
||||
self::add($url);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -385,6 +385,9 @@ class Item
|
|||
Post\ThreadUser::update($item['uri-id'], $item['uid'], ['hidden' => true]);
|
||||
}
|
||||
|
||||
DI::notify()->deleteForItem($item['uri-id']);
|
||||
DI::notification()->deleteForItem($item['uri-id']);
|
||||
|
||||
Logger::info('Item has been marked for deletion.', ['id' => $item_id]);
|
||||
|
||||
return true;
|
||||
|
|
|
@ -173,6 +173,64 @@ class Photo
|
|||
return $photo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all browsable albums for a given user
|
||||
*
|
||||
* @param int $uid The given user
|
||||
*
|
||||
* @return array An array of albums
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function getBrowsableAlbumsForUser(int $uid): array
|
||||
{
|
||||
$photos = DBA::toArray(
|
||||
DBA::p(
|
||||
"SELECT DISTINCT(`album`) AS `album` FROM `photo` WHERE `uid` = ? AND NOT `photo-type` IN (?, ?)",
|
||||
$uid,
|
||||
static::CONTACT_AVATAR,
|
||||
static::CONTACT_BANNER
|
||||
)
|
||||
);
|
||||
|
||||
return array_column($photos, 'album');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns browsable photos for a given user (optional and a given album)
|
||||
*
|
||||
* @param int $uid The given user id
|
||||
* @param string|null $album (optional) The given album
|
||||
*
|
||||
* @return array All photos of the user/album
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function getBrowsablePhotosForUser(int $uid, string $album = null): array
|
||||
{
|
||||
$values = [
|
||||
$uid,
|
||||
Photo::CONTACT_AVATAR,
|
||||
Photo::CONTACT_BANNER
|
||||
];
|
||||
|
||||
if (!empty($album)) {
|
||||
$sqlExtra = "AND `album` = ? ";
|
||||
$values[] = $album;
|
||||
$sqlExtra2 = "";
|
||||
} else {
|
||||
$sqlExtra = '';
|
||||
$sqlExtra2 = ' ORDER BY created DESC LIMIT 0, 10';
|
||||
}
|
||||
|
||||
return DBA::toArray(
|
||||
DBA::p(
|
||||
"SELECT `resource-id`, ANY_VALUE(`id`) AS `id`, ANY_VALUE(`filename`) AS `filename`, ANY_VALUE(`type`) AS `type`,
|
||||
min(`scale`) AS `hiq`, max(`scale`) AS `loq`, ANY_VALUE(`desc`) AS `desc`, ANY_VALUE(`created`) AS `created`
|
||||
FROM `photo` WHERE `uid` = ? AND NOT `photo-type` IN (?, ?) $sqlExtra
|
||||
GROUP BY `resource-id` $sqlExtra2",
|
||||
$values
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if photo with given conditions exists
|
||||
*
|
||||
|
|
|
@ -195,7 +195,7 @@ class Delayed
|
|||
|
||||
$id = Item::insert($item, $notify, $preparation_mode == self::PREPARED);
|
||||
|
||||
Logger::notice('Post stored', ['id' => $id, 'uid' => $item['uid'], 'cid' => $item['contact-id']]);
|
||||
Logger::notice('Post stored', ['id' => $id, 'uid' => $item['uid'], 'cid' => $item['contact-id'] ?? 'N/A']);
|
||||
|
||||
if (empty($uri) && !empty($item['uri'])) {
|
||||
$uri = $item['uri'];
|
||||
|
|
|
@ -21,8 +21,12 @@
|
|||
|
||||
namespace Friendica\Module\Api\Mastodon\Accounts;
|
||||
|
||||
use Friendica\App\Router;
|
||||
use Friendica\Core\Logger;
|
||||
use Friendica\DI;
|
||||
use Friendica\Model\Contact;
|
||||
use Friendica\Model\Photo;
|
||||
use Friendica\Model\Profile;
|
||||
use Friendica\Model\User;
|
||||
use Friendica\Module\BaseApi;
|
||||
|
||||
/**
|
||||
|
@ -35,8 +39,72 @@ class UpdateCredentials extends BaseApi
|
|||
self::checkAllowedScope(self::SCOPE_WRITE);
|
||||
$uid = self::getCurrentUserID();
|
||||
|
||||
Logger::info('Patch data', ['data' => $request]);
|
||||
$owner = User::getOwnerDataById($uid);
|
||||
|
||||
$this->response->unsupported(Router::PATCH, $request);
|
||||
$request = $this->getRequest([
|
||||
'bot' => ($owner['contact-type'] == Contact::TYPE_NEWS),
|
||||
'discoverable' => $owner['net-publish'],
|
||||
'display_name' => $owner['name'],
|
||||
'fields_attributes' => [],
|
||||
'locked' => $owner['manually-approve'],
|
||||
'note' => $owner['about'],
|
||||
'avatar' => [],
|
||||
'header' => [],
|
||||
], $request);
|
||||
|
||||
$user = [];
|
||||
$profile = [];
|
||||
|
||||
if ($request['bot']) {
|
||||
$user['account-type'] = Contact::TYPE_NEWS;
|
||||
$user['page-flags'] = User::PAGE_FLAGS_SOAPBOX;
|
||||
} elseif ($owner['contact-type'] == Contact::TYPE_NEWS) {
|
||||
$user['account-type'] = Contact::TYPE_PERSON;
|
||||
} else {
|
||||
$user['account-type'] = $owner['contact-type'];
|
||||
}
|
||||
|
||||
$profile['net-publish'] = $request['discoverable'];
|
||||
|
||||
if (!empty($request['display_name'])) {
|
||||
$user['username'] = $request['display_name'];
|
||||
}
|
||||
|
||||
if ($user['account-type'] == Contact::TYPE_COMMUNITY) {
|
||||
$user['page-flags'] = $request['locked'] ? User::PAGE_FLAGS_PRVGROUP : User::PAGE_FLAGS_COMMUNITY;
|
||||
} elseif ($user['account-type'] == Contact::TYPE_PERSON) {
|
||||
if ($request['locked']) {
|
||||
$user['page-flags'] = User::PAGE_FLAGS_NORMAL;
|
||||
} elseif ($owner['page-flags'] == User::PAGE_FLAGS_NORMAL) {
|
||||
$user['page-flags'] = User::PAGE_FLAGS_SOAPBOX;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($request['note'])) {
|
||||
$profile['about'] = $request['note'];
|
||||
}
|
||||
|
||||
Logger::debug('Patch data', ['data' => $request, 'files' => $_FILES]);
|
||||
|
||||
Logger::info('Update profile and user', ['uid' => $uid, 'user' => $user, 'profile' => $profile]);
|
||||
|
||||
if (!empty($request['avatar'])) {
|
||||
Photo::uploadAvatar(1, $request['avatar']);
|
||||
}
|
||||
|
||||
if (!empty($request['header'])) {
|
||||
Photo::uploadBanner(1, $request['header']);
|
||||
}
|
||||
|
||||
User::update($user, $uid);
|
||||
Profile::update($profile, $uid);
|
||||
|
||||
$cdata = Contact::getPublicAndUserContactID($owner['id'], $uid);
|
||||
if (empty($cdata)) {
|
||||
DI::mstdnError()->InternalError();
|
||||
}
|
||||
|
||||
$account = DI::mstdnAccount()->createFromContactId($cdata['user'], $uid);
|
||||
$this->response->exitWithJson($account->toArray());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ use Friendica\Core\System;
|
|||
use Friendica\Database\DBA;
|
||||
use Friendica\DI;
|
||||
use Friendica\Model\Contact;
|
||||
use Friendica\Model\Item;
|
||||
use Friendica\Model\Post;
|
||||
use Friendica\Model\Tag;
|
||||
use Friendica\Module\BaseApi;
|
||||
|
@ -67,10 +68,24 @@ class Search extends BaseApi
|
|||
|
||||
if (empty($request['type']) || ($request['type'] == 'accounts')) {
|
||||
$result['accounts'] = self::searchAccounts($uid, $request['q'], $request['resolve'], $limit, $request['offset'], $request['following']);
|
||||
|
||||
if (!is_array($result['accounts'])) {
|
||||
// Curbing the search if we got an exact result
|
||||
$request['type'] = 'accounts';
|
||||
$result['accounts'] = [$result['accounts']];
|
||||
}
|
||||
}
|
||||
|
||||
if ((empty($request['type']) || ($request['type'] == 'statuses')) && (strpos($request['q'], '@') == false)) {
|
||||
$result['statuses'] = self::searchStatuses($uid, $request['q'], $request['account_id'], $request['max_id'], $request['min_id'], $limit, $request['offset']);
|
||||
|
||||
if (!is_array($result['statuses'])) {
|
||||
// Curbing the search if we got an exact result
|
||||
$request['type'] = 'statuses';
|
||||
$result['statuses'] = [$result['statuses']];
|
||||
}
|
||||
}
|
||||
|
||||
if ((empty($request['type']) || ($request['type'] == 'hashtags')) && (strpos($request['q'], '@') == false)) {
|
||||
$result['hashtags'] = self::searchHashtags($request['q'], $request['exclude_unreviewed'], $limit, $request['offset'], $this->parameters['version']);
|
||||
}
|
||||
|
@ -78,31 +93,59 @@ class Search extends BaseApi
|
|||
System::jsonExit($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $uid
|
||||
* @param string $q
|
||||
* @param bool $resolve
|
||||
* @param int $limit
|
||||
* @param int $offset
|
||||
* @param bool $following
|
||||
* @return array|\Friendica\Object\Api\Mastodon\Account Object if result is absolute (exact account match), list if not
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
* @throws \Friendica\Network\HTTPException\NotFoundException
|
||||
* @throws \ImagickException
|
||||
*/
|
||||
private static function searchAccounts(int $uid, string $q, bool $resolve, int $limit, int $offset, bool $following)
|
||||
{
|
||||
$accounts = [];
|
||||
|
||||
if ((strrpos($q, '@') > 0) || Network::isValidHttpUrl($q)) {
|
||||
$id = Contact::getIdForURL($q, 0, $resolve ? null : false);
|
||||
|
||||
if (!empty($id)) {
|
||||
$accounts[] = DI::mstdnAccount()->createFromContactId($id, $uid);
|
||||
}
|
||||
if (
|
||||
(strrpos($q, '@') > 0 || Network::isValidHttpUrl($q))
|
||||
&& $id = Contact::getIdForURL($q, 0, $resolve ? null : false)
|
||||
) {
|
||||
return DI::mstdnAccount()->createFromContactId($id, $uid);
|
||||
}
|
||||
|
||||
if (empty($accounts)) {
|
||||
$contacts = Contact::searchByName($q, '', $following ? $uid : 0, $limit, $offset);
|
||||
foreach ($contacts as $contact) {
|
||||
$accounts[] = DI::mstdnAccount()->createFromContactId($contact['id'], $uid);
|
||||
}
|
||||
DBA::close($contacts);
|
||||
$accounts = [];
|
||||
foreach (Contact::searchByName($q, '', $following ? $uid : 0, $limit, $offset) as $contact) {
|
||||
$accounts[] = DI::mstdnAccount()->createFromContactId($contact['id'], $uid);
|
||||
}
|
||||
|
||||
return $accounts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $uid
|
||||
* @param string $q
|
||||
* @param string $account_id
|
||||
* @param int $max_id
|
||||
* @param int $min_id
|
||||
* @param int $limit
|
||||
* @param int $offset
|
||||
* @return array|\Friendica\Object\Api\Mastodon\Status Object is result is absolute (exact post match), list if not
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
* @throws \Friendica\Network\HTTPException\NotFoundException
|
||||
* @throws \ImagickException
|
||||
*/
|
||||
private static function searchStatuses(int $uid, string $q, string $account_id, int $max_id, int $min_id, int $limit, int $offset)
|
||||
{
|
||||
if (Network::isValidHttpUrl($q)) {
|
||||
$q = Network::convertToIdn($q);
|
||||
// If the user-specific search failed, we search and probe a public post
|
||||
$item_id = Item::fetchByLink($q, $uid) ?: Item::fetchByLink($q);
|
||||
if ($item_id && $item = Post::selectFirst(['uri-id'], ['id' => $item_id])) {
|
||||
return DI::mstdnStatus()->createFromUriId($item['uri-id'], $uid);
|
||||
}
|
||||
}
|
||||
|
||||
$params = ['order' => ['uri-id' => true], 'limit' => [$offset, $limit]];
|
||||
|
||||
if (substr($q, 0, 1) == '#') {
|
||||
|
@ -148,7 +191,7 @@ class Search extends BaseApi
|
|||
return $statuses;
|
||||
}
|
||||
|
||||
private static function searchHashtags(string $q, bool $exclude_unreviewed, int $limit, int $offset, int $version)
|
||||
private static function searchHashtags(string $q, bool $exclude_unreviewed, int $limit, int $offset, int $version): array
|
||||
{
|
||||
$q = ltrim($q, '#');
|
||||
|
||||
|
|
|
@ -37,7 +37,6 @@ class Attach extends BaseModule
|
|||
*/
|
||||
protected function rawContent(array $request = [])
|
||||
{
|
||||
$a = DI::app();
|
||||
if (empty($this->parameters['item'])) {
|
||||
throw new \Friendica\Network\HTTPException\BadRequestException();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2022, the Friendica project
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Friendica\Module\Media\Attachment;
|
||||
|
||||
use Friendica\App;
|
||||
use Friendica\BaseModule;
|
||||
use Friendica\Core\L10n;
|
||||
use Friendica\Core\Renderer;
|
||||
use Friendica\Core\Session\Capability\IHandleUserSessions;
|
||||
use Friendica\Core\System;
|
||||
use Friendica\Model\Attach;
|
||||
use Friendica\Module\Response;
|
||||
use Friendica\Network\HTTPException\UnauthorizedException;
|
||||
use Friendica\Util\Profiler;
|
||||
use Friendica\Util\Strings;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
* Browser for Attachments
|
||||
*/
|
||||
class Browser extends BaseModule
|
||||
{
|
||||
/** @var IHandleUserSessions */
|
||||
protected $session;
|
||||
/** @var App */
|
||||
protected $app;
|
||||
|
||||
public function __construct(L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, IHandleUserSessions $session, App $app, array $server, array $parameters = [])
|
||||
{
|
||||
parent::__construct($l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
|
||||
|
||||
$this->session = $session;
|
||||
$this->app = $app;
|
||||
}
|
||||
|
||||
protected function content(array $request = []): string
|
||||
{
|
||||
if (!$this->session->getLocalUserId()) {
|
||||
throw new UnauthorizedException($this->t('You need to be logged in to access this page.'));
|
||||
}
|
||||
|
||||
// Needed to match the correct template in a module that uses a different theme than the user/site/default
|
||||
$theme = Strings::sanitizeFilePathItem($request['theme'] ?? '');
|
||||
if ($theme && is_file("view/theme/$theme/config.php")) {
|
||||
$this->app->setCurrentTheme($theme);
|
||||
}
|
||||
|
||||
$files = Attach::selectToArray(['id', 'filename', 'filetype'], ['uid' => $this->session->getLocalUserId()]);
|
||||
|
||||
$fileArray = array_map([$this, 'map_files'], $files);
|
||||
|
||||
$tpl = Renderer::getMarkupTemplate('media/browser.tpl');
|
||||
$output = Renderer::replaceMacros($tpl, [
|
||||
'$type' => 'attachment',
|
||||
'$path' => ['' => $this->t('Files')],
|
||||
'$folders' => false,
|
||||
'$files' => $fileArray,
|
||||
'$cancel' => $this->t('Cancel'),
|
||||
'$nickname' => $this->app->getLoggedInUserNickname(),
|
||||
'$upload' => $this->t('Upload'),
|
||||
]);
|
||||
|
||||
if (empty($request['mode'])) {
|
||||
System::httpExit($output);
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
protected function map_files(array $record): array
|
||||
{
|
||||
list($m1, $m2) = explode('/', $record['filetype']);
|
||||
$filetype = file_exists(sprintf('images/icons/%s.png', $m1) ? $m1 : 'text');
|
||||
|
||||
return [
|
||||
sprintf('%s/attach/%s', $this->baseUrl, $record['id']),
|
||||
$record['filename'],
|
||||
sprintf('%s/images/icon/16/%s.png', $this->baseUrl, $filetype),
|
||||
];
|
||||
}
|
||||
}
|
|
@ -19,7 +19,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
namespace Friendica\Module\Profile\Attachment;
|
||||
namespace Friendica\Module\Media\Attachment;
|
||||
|
||||
use Friendica\App;
|
||||
use Friendica\Core\Config\Capability\IManageConfigValues;
|
||||
|
@ -73,30 +73,12 @@ class Upload extends \Friendica\BaseModule
|
|||
$this->response->setType(Response::TYPE_JSON, 'application/json');
|
||||
}
|
||||
|
||||
$nick = $this->parameters['nickname'];
|
||||
$owner = User::getOwnerDataByNick($nick);
|
||||
$owner = User::getOwnerDataById($this->userSession->getLocalUserId());
|
||||
if (!$owner) {
|
||||
$this->logger->warning('owner is not a valid record:', ['owner' => $owner, 'nick' => $nick]);
|
||||
$this->logger->warning('Owner not found.', ['uid' => $this->userSession->getLocalUserId()]);
|
||||
return $this->return(401, $this->t('Invalid request.'));
|
||||
}
|
||||
|
||||
$can_post = false;
|
||||
$contact_id = 0;
|
||||
$page_owner_uid = $owner['uid'];
|
||||
$community_page = $owner['page-flags'] == User::PAGE_FLAGS_COMMUNITY;
|
||||
|
||||
if ($this->userSession->getLocalUserId() && $this->userSession->getLocalUserId() == $page_owner_uid) {
|
||||
$can_post = true;
|
||||
} elseif ($community_page && !empty($this->userSession->getRemoteContactID($page_owner_uid))) {
|
||||
$contact_id = $this->userSession->getRemoteContactID($page_owner_uid);
|
||||
$can_post = $this->database->exists('contact', ['blocked' => false, 'pending' => false, 'id' => $contact_id, 'uid' => $page_owner_uid]);
|
||||
}
|
||||
|
||||
if (!$can_post) {
|
||||
$this->logger->warning('User does not have required permissions', ['contact_id' => $contact_id, 'page_owner_uid' => $page_owner_uid]);
|
||||
return $this->return(403, $this->t('Permission denied.'), true);
|
||||
}
|
||||
|
||||
if (empty($_FILES['userfile'])) {
|
||||
$this->logger->warning('No file uploaded (empty userfile)');
|
||||
return $this->return(401, $this->t('Invalid request.'), true);
|
||||
|
@ -126,7 +108,7 @@ class Upload extends \Friendica\BaseModule
|
|||
return $this->return(401, $msg);
|
||||
}
|
||||
|
||||
$newid = Attach::storeFile($tempFileName, $page_owner_uid, $fileName, '<' . $owner['id'] . '>');
|
||||
$newid = Attach::storeFile($tempFileName, $owner['uid'], $fileName, '<' . $owner['id'] . '>');
|
||||
|
||||
@unlink($tempFileName);
|
||||
|
|
@ -0,0 +1,125 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2022, the Friendica project
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Friendica\Module\Media\Photo;
|
||||
|
||||
use Friendica\App;
|
||||
use Friendica\BaseModule;
|
||||
use Friendica\Core\L10n;
|
||||
use Friendica\Core\Renderer;
|
||||
use Friendica\Core\Session\Capability\IHandleUserSessions;
|
||||
use Friendica\Core\System;
|
||||
use Friendica\Model\Photo;
|
||||
use Friendica\Module\Response;
|
||||
use Friendica\Network\HTTPException\UnauthorizedException;
|
||||
use Friendica\Util\Images;
|
||||
use Friendica\Util\Profiler;
|
||||
use Friendica\Util\Strings;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
* Browser for Photos
|
||||
*/
|
||||
class Browser extends BaseModule
|
||||
{
|
||||
/** @var IHandleUserSessions */
|
||||
protected $session;
|
||||
/** @var App */
|
||||
protected $app;
|
||||
|
||||
public function __construct(L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, IHandleUserSessions $session, App $app, array $server, array $parameters = [])
|
||||
{
|
||||
parent::__construct($l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
|
||||
|
||||
$this->session = $session;
|
||||
$this->app = $app;
|
||||
}
|
||||
|
||||
protected function content(array $request = []): string
|
||||
{
|
||||
if (!$this->session->getLocalUserId()) {
|
||||
throw new UnauthorizedException($this->t('You need to be logged in to access this page.'));
|
||||
}
|
||||
|
||||
// Needed to match the correct template in a module that uses a different theme than the user/site/default
|
||||
$theme = Strings::sanitizeFilePathItem($request['theme'] ?? '');
|
||||
if ($theme && is_file("view/theme/$theme/config.php")) {
|
||||
$this->app->setCurrentTheme($theme);
|
||||
}
|
||||
|
||||
$album = $this->parameters['album'] ?? null;
|
||||
|
||||
$photos = Photo::getBrowsablePhotosForUser($this->session->getLocalUserId(), $album);
|
||||
$albums = $album ? false : Photo::getBrowsableAlbumsForUser($this->session->getLocalUserId());
|
||||
|
||||
$path = [
|
||||
'' => $this->t('Photos'),
|
||||
];
|
||||
if (!empty($album)) {
|
||||
$path[$album] = $album;
|
||||
}
|
||||
|
||||
$photosArray = array_map([$this, 'map_files'], $photos);
|
||||
|
||||
$tpl = Renderer::getMarkupTemplate('media/browser.tpl');
|
||||
$output = Renderer::replaceMacros($tpl, [
|
||||
'$type' => 'photo',
|
||||
'$path' => $path,
|
||||
'$folders' => $albums,
|
||||
'$files' => $photosArray,
|
||||
'$cancel' => $this->t('Cancel'),
|
||||
'$nickname' => $this->app->getLoggedInUserNickname(),
|
||||
'$upload' => $this->t('Upload'),
|
||||
]);
|
||||
|
||||
if (empty($request['mode'])) {
|
||||
System::httpExit($output);
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
protected function map_files(array $record): array
|
||||
{
|
||||
$types = Images::supportedTypes();
|
||||
$ext = $types[$record['type']];
|
||||
$filename_e = $record['filename'];
|
||||
|
||||
// Take the largest picture that is smaller or equal 640 pixels
|
||||
$photo = Photo::selectFirst(
|
||||
['scale'],
|
||||
[
|
||||
"`resource-id` = ? AND `height` <= ? AND `width` <= ?",
|
||||
$record['resource-id'],
|
||||
640,
|
||||
640
|
||||
],
|
||||
['order' => ['scale']]);
|
||||
$scale = $photo['scale'] ?? $record['loq'];
|
||||
|
||||
return [
|
||||
sprintf('%s/photos/%s/image/%s', $this->baseUrl, $this->app->getLoggedInUserNickname(), $record['resource-id']),
|
||||
$filename_e,
|
||||
sprintf('%s/photo/%s-%s.%s', $this->baseUrl, $record['resource-id'], $scale, $ext),
|
||||
$record['desc'],
|
||||
];
|
||||
}
|
||||
}
|
|
@ -19,7 +19,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
namespace Friendica\Module\Profile\Photos;
|
||||
namespace Friendica\Module\Media\Photo;
|
||||
|
||||
use Friendica\App;
|
||||
use Friendica\Core\Config\Capability\IManageConfigValues;
|
||||
|
@ -76,36 +76,11 @@ class Upload extends \Friendica\BaseModule
|
|||
|
||||
$album = trim($request['album'] ?? '');
|
||||
|
||||
if (empty($_FILES['media'])) {
|
||||
$user = $this->database->selectFirst('owner-view', ['id', 'uid', 'nickname', 'page-flags'], ['nickname' => $this->parameters['nickname'], 'blocked' => false]);
|
||||
} else {
|
||||
$user = $this->database->selectFirst('owner-view', ['id', 'uid', 'nickname', 'page-flags'], ['uid' => BaseApi::getCurrentUserID() ?: null, 'blocked' => false]);
|
||||
}
|
||||
$owner = User::getOwnerDataById($this->userSession->getLocalUserId());
|
||||
|
||||
if (!$this->database->isResult($user)) {
|
||||
$this->logger->warning('User is not valid', ['nickname' => $this->parameters['nickname'], 'user' => $user]);
|
||||
return $this->return(404, $this->t('User not found.'));
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup permissions structures
|
||||
*/
|
||||
$can_post = false;
|
||||
$visitor = 0;
|
||||
$contact_id = 0;
|
||||
$page_owner_uid = $user['uid'];
|
||||
|
||||
if ($this->userSession->getLocalUserId() && $this->userSession->getLocalUserId() == $page_owner_uid) {
|
||||
$can_post = true;
|
||||
} elseif ($user['page-flags'] == User::PAGE_FLAGS_COMMUNITY && !$this->userSession->getRemoteContactID($page_owner_uid)) {
|
||||
$contact_id = $this->userSession->getRemoteContactID($page_owner_uid);
|
||||
$can_post = $this->database->exists('contact', ['blocked' => false, 'pending' => false, 'id' => $contact_id, 'uid' => $page_owner_uid]);
|
||||
$visitor = $contact_id;
|
||||
}
|
||||
|
||||
if (!$can_post) {
|
||||
$this->logger->warning('No permission to upload files', ['contact_id' => $contact_id, 'page_owner_uid' => $page_owner_uid]);
|
||||
return $this->return(403, $this->t('Permission denied.'), true);
|
||||
if (!$owner) {
|
||||
$this->logger->warning('Owner not found.', ['uid' => $this->userSession->getLocalUserId()]);
|
||||
return $this->return(401, $this->t('Invalid request.'));
|
||||
}
|
||||
|
||||
if (empty($_FILES['userfile']) && empty($_FILES['media'])) {
|
||||
|
@ -223,9 +198,9 @@ class Upload extends \Friendica\BaseModule
|
|||
$album = $this->t('Wall Photos');
|
||||
}
|
||||
|
||||
$allow_cid = '<' . $user['id'] . '>';
|
||||
$allow_cid = '<' . $owner['id'] . '>';
|
||||
|
||||
$result = Photo::store($image, $page_owner_uid, $visitor, $resource_id, $filename, $album, 0, Photo::DEFAULT, $allow_cid);
|
||||
$result = Photo::store($image, $owner['uid'], 0, $resource_id, $filename, $album, 0, Photo::DEFAULT, $allow_cid);
|
||||
if (!$result) {
|
||||
$this->logger->warning('Photo::store() failed', ['result' => $result]);
|
||||
return $this->return(401, $this->t('Image upload failed.'));
|
||||
|
@ -233,7 +208,7 @@ class Upload extends \Friendica\BaseModule
|
|||
|
||||
if ($width > 640 || $height > 640) {
|
||||
$image->scaleDown(640);
|
||||
$result = Photo::store($image, $page_owner_uid, $visitor, $resource_id, $filename, $album, 1, Photo::DEFAULT, $allow_cid);
|
||||
$result = Photo::store($image, $owner['uid'], 0, $resource_id, $filename, $album, 1, Photo::DEFAULT, $allow_cid);
|
||||
if ($result) {
|
||||
$smallest = 1;
|
||||
}
|
||||
|
@ -241,14 +216,14 @@ class Upload extends \Friendica\BaseModule
|
|||
|
||||
if ($width > 320 || $height > 320) {
|
||||
$image->scaleDown(320);
|
||||
$result = Photo::store($image, $page_owner_uid, $visitor, $resource_id, $filename, $album, 2, Photo::DEFAULT, $allow_cid);
|
||||
$result = Photo::store($image, $owner['uid'], 0, $resource_id, $filename, $album, 2, Photo::DEFAULT, $allow_cid);
|
||||
if ($result && ($smallest == 0)) {
|
||||
$smallest = 2;
|
||||
}
|
||||
}
|
||||
|
||||
$this->logger->info('upload done');
|
||||
return $this->return(200, "\n\n" . '[url=' . $this->baseUrl . '/photos/' . $user['nickname'] . '/image/' . $resource_id . '][img]' . $this->baseUrl . "/photo/$resource_id-$smallest." . $image->getExt() . "[/img][/url]\n\n");
|
||||
return $this->return(200, "\n\n" . '[url=' . $this->baseUrl . '/photos/' . $owner['nickname'] . '/image/' . $resource_id . '][img]' . $this->baseUrl . "/photo/$resource_id-$smallest." . $image->getExt() . "[/img][/url]\n\n");
|
||||
}
|
||||
|
||||
/**
|
|
@ -19,7 +19,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
namespace Friendica\Module\Profile\Photos;
|
||||
namespace Friendica\Module\Profile;
|
||||
|
||||
use Friendica\App;
|
||||
use Friendica\Content\Pager;
|
||||
|
@ -40,7 +40,7 @@ use Friendica\Util\Images;
|
|||
use Friendica\Util\Profiler;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class Index extends \Friendica\Module\BaseProfile
|
||||
class Photos extends \Friendica\Module\BaseProfile
|
||||
{
|
||||
/** @var IHandleUserSessions */
|
||||
private $session;
|
|
@ -33,6 +33,7 @@ use Friendica\Navigation\Notifications\Collection;
|
|||
use Friendica\Navigation\Notifications\Entity;
|
||||
use Friendica\Navigation\Notifications\Factory;
|
||||
use Friendica\Network\HTTPException\NotFoundException;
|
||||
use Friendica\Protocol\Activity;
|
||||
use Friendica\Util\DateTimeFormat;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
|
@ -268,4 +269,23 @@ class Notification extends BaseRepository
|
|||
|
||||
return $this->db->delete(self::$table_name, $condition);
|
||||
}
|
||||
|
||||
public function deleteForItem(int $itemUriId): bool
|
||||
{
|
||||
$conditionTarget = [
|
||||
'vid' => Verb::getID(Activity::POST),
|
||||
'target-uri-id' => $itemUriId,
|
||||
];
|
||||
|
||||
$conditionParent = [
|
||||
'vid' => Verb::getID(Activity::POST),
|
||||
'parent-uri-id' => $itemUriId,
|
||||
];
|
||||
|
||||
$this->logger->notice('deleteForItem', ['conditionTarget' => $conditionTarget, 'conditionParent' => $conditionParent]);
|
||||
|
||||
return
|
||||
$this->db->delete(self::$table_name, $conditionTarget)
|
||||
&& $this->db->delete(self::$table_name, $conditionParent);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -807,4 +807,10 @@ class Notify extends BaseRepository
|
|||
|
||||
return $this->storeAndSend($params, $sitelink, $tsitelink, $hsitelink, $title, $subject, $preamble, $epreamble, $item['body'], $itemlink, true);
|
||||
}
|
||||
|
||||
public function deleteForItem(int $itemUriId): void
|
||||
{
|
||||
$this->db->delete('notify', ['otype' => 'item', 'uri-id' => $itemUriId]);
|
||||
$this->db->delete('notify', ['otype' => 'item', 'parent-uri-id' => $itemUriId]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,18 +31,16 @@ use Friendica\App\Router as R;
|
|||
use Friendica\Module;
|
||||
|
||||
$profileRoutes = [
|
||||
'' => [Module\Profile\Index::class, [R::GET]],
|
||||
'/attachment/upload' => [Module\Profile\Attachment\Upload::class, [ R::POST]],
|
||||
'/contacts/common' => [Module\Profile\Common::class, [R::GET]],
|
||||
'/contacts[/{type}]' => [Module\Profile\Contacts::class, [R::GET]],
|
||||
'/media' => [Module\Profile\Media::class, [R::GET]],
|
||||
'/photos' => [Module\Profile\Photos\Index::class, [R::GET ]],
|
||||
'/photos/upload' => [Module\Profile\Photos\Upload::class, [ R::POST]],
|
||||
'/profile' => [Module\Profile\Profile::class, [R::GET]],
|
||||
'/remote_follow' => [Module\Profile\RemoteFollow::class, [R::GET, R::POST]],
|
||||
'/schedule' => [Module\Profile\Schedule::class, [R::GET, R::POST]],
|
||||
'/status[/{category}[/{date1}[/{date2}]]]' => [Module\Profile\Status::class, [R::GET]],
|
||||
'/unkmail' => [Module\Profile\UnkMail::class, [R::GET, R::POST]],
|
||||
'' => [Module\Profile\Index::class, [R::GET]],
|
||||
'/contacts/common' => [Module\Profile\Common::class, [R::GET]],
|
||||
'/contacts[/{type}]' => [Module\Profile\Contacts::class, [R::GET]],
|
||||
'/media' => [Module\Profile\Media::class, [R::GET]],
|
||||
'/photos' => [Module\Profile\Photos::class, [R::GET ]],
|
||||
'/profile' => [Module\Profile\Profile::class, [R::GET]],
|
||||
'/remote_follow' => [Module\Profile\RemoteFollow::class, [R::GET, R::POST]],
|
||||
'/schedule' => [Module\Profile\Schedule::class, [R::GET, R::POST]],
|
||||
'/status[/{category}[/{date1}[/{date2}]]]' => [Module\Profile\Status::class, [R::GET]],
|
||||
'/unkmail' => [Module\Profile\UnkMail::class, [R::GET, R::POST]],
|
||||
];
|
||||
|
||||
$apiRoutes = [
|
||||
|
@ -473,6 +471,14 @@ return [
|
|||
'/magic' => [Module\Magic::class, [R::GET]],
|
||||
'/manifest' => [Module\Manifest::class, [R::GET]],
|
||||
'/friendica.webmanifest' => [Module\Manifest::class, [R::GET]],
|
||||
|
||||
'/media' => [
|
||||
'/attachment/browser' => [Module\Media\Attachment\Browser::class, [R::GET]],
|
||||
'/attachment/upload' => [Module\Media\Attachment\Upload::class, [ R::POST]],
|
||||
'/photo/browser[/{album}]' => [Module\Media\Photo\Browser::class, [R::GET]],
|
||||
'/photo/upload' => [Module\Media\Photo\Upload::class, [ R::POST]],
|
||||
],
|
||||
|
||||
'/moderation' => [
|
||||
'[/]' => [Module\Moderation\Summary::class, [R::GET]],
|
||||
|
||||
|
@ -560,7 +566,7 @@ return [
|
|||
|
||||
// Kept for backwards-compatibility
|
||||
// @TODO remove by version 2023.12
|
||||
'/photos/{nickname}' => [Module\Profile\Photos\Index::class, [R::GET]],
|
||||
'/photos/{nickname}' => [Module\Profile\Photos::class, [R::GET]],
|
||||
|
||||
'/ping' => [Module\Notifications\Ping::class, [R::GET]],
|
||||
|
||||
|
|
|
@ -345,12 +345,12 @@ img.acpopup-img {
|
|||
.fbrowser .path a:before, .fbrowser .path .btn-link:before { content: "/"; padding-right: 5px;}
|
||||
.fbrowser .folders ul { list-style-type: none; padding-left: 10px;}
|
||||
.fbrowser .list { height: auto; overflow-y: hidden; margin: 10px 0px; }
|
||||
.fbrowser.image .photo-album-image-wrapper { float: left; }
|
||||
.fbrowser.image a img, .fbrowser.image .btn-link img { height: 48px; }
|
||||
.fbrowser.image a p, .fbrowser.image .btn-link p { display: none;}
|
||||
.fbrowser.file .photo-album-image-wrapper { float:none; white-space: nowrap; }
|
||||
.fbrowser.file img { display: inline; }
|
||||
.fbrowser.file p { display: inline; white-space: nowrap; }
|
||||
.fbrowser.photo .photo-album-image-wrapper { float: left; }
|
||||
.fbrowser.photo a img, .fbrowser.photo .btn-link img { height: 48px; }
|
||||
.fbrowser.photo a p, .fbrowser.photo .btn-link p { display: none;}
|
||||
.fbrowser.attachment .photo-album-image-wrapper { float:none; white-space: nowrap; }
|
||||
.fbrowser.attachment img { display: inline; }
|
||||
.fbrowser.attachment p { display: inline; white-space: nowrap; }
|
||||
.fbrowser .upload { clear: both; padding-top: 1em;}
|
||||
.fbrowser .error { background: #ffeeee; border: 1px solid #994444; color: #994444; padding: 0.5em;}
|
||||
.fbrowser .error .close { float: right; font-weight: bold; }
|
||||
|
|
|
@ -1,144 +0,0 @@
|
|||
// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPLv3-or-later
|
||||
/**
|
||||
* Filebrowser - Friendica Communications Server
|
||||
*
|
||||
* Copyright (c) 2010-2021, the Friendica project
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This code handle user interaction for image/file upload/browser dialog.
|
||||
* Is loaded from filebrowser_plain.tpl
|
||||
*
|
||||
* To load filebrowser in colorbox, call
|
||||
*
|
||||
* Dialog.doImageBrowser(eventname, id);
|
||||
*
|
||||
* or
|
||||
*
|
||||
* Dialog.doFileBrowser(eventname, id);
|
||||
*
|
||||
* where:
|
||||
*
|
||||
* eventname: event name to catch return value
|
||||
* id: id returned to event handler
|
||||
*
|
||||
* When user select an item, an event in fired in parent page, on body element
|
||||
* The event is named
|
||||
*
|
||||
* fbrowser.<type>.[<eventname>]
|
||||
*
|
||||
* <type> will be one of "image" or "file", and the event handler will
|
||||
* get the following params:
|
||||
*
|
||||
* filemane: filename of item choosed by user
|
||||
* embed: bbcode to embed element into posts
|
||||
* id: id from caller code
|
||||
*
|
||||
* example:
|
||||
*
|
||||
* // open dialog for select an image for a textarea with id "myeditor"
|
||||
* var id="myeditor";
|
||||
* Dialog.doImageBrowser("example", id);
|
||||
*
|
||||
* // setup event handler to get user selection
|
||||
* $("body").on("fbrowser.image.example", function(event, filename, bbcode, id) {
|
||||
* // close colorbox
|
||||
* $.colorbox.close();
|
||||
* // replace textxarea text with bbcode
|
||||
* $(id).value = bbcode;
|
||||
* });
|
||||
**/
|
||||
|
||||
var FileBrowser = {
|
||||
nickname : "",
|
||||
type : "",
|
||||
event: "",
|
||||
id : null,
|
||||
|
||||
init: function(nickname, type) {
|
||||
FileBrowser.nickname = nickname;
|
||||
FileBrowser.type = type;
|
||||
FileBrowser.event = "fbrowser."+type;
|
||||
if (location['hash']!=="") {
|
||||
var h = location['hash'].replace("#","");
|
||||
FileBrowser.event = FileBrowser.event + "." + h.split("-")[0];
|
||||
FileBrowser.id = h.split("-")[1];
|
||||
}
|
||||
|
||||
console.log("FileBrowser:", nickname, type,FileBrowser.event, FileBrowser.id );
|
||||
|
||||
$(".error a.close").on("click", function(e) {
|
||||
e.preventDefault();
|
||||
$(".error").addClass("hidden");
|
||||
});
|
||||
|
||||
$(".folders a, .path a").on("click", function(e){
|
||||
e.preventDefault();
|
||||
location.href = baseurl + "/fbrowser/" + FileBrowser.type + "/" + encodeURIComponent(this.dataset.folder) + "?mode=minimal" + location['hash'];
|
||||
});
|
||||
|
||||
$(".photo-album-photo-link").on('click', function(e){
|
||||
e.preventDefault();
|
||||
|
||||
var embed = "";
|
||||
if (FileBrowser.type == "image") {
|
||||
embed = "[url="+this.dataset.link+"][img="+this.dataset.img+"]"+this.dataset.alt+"[/img][/url]";
|
||||
}
|
||||
if (FileBrowser.type=="file") {
|
||||
// attachment links are "baseurl/attach/id"; we need id
|
||||
embed = "[attachment]"+this.dataset.link.split("/").pop()+"[/attachment]";
|
||||
}
|
||||
console.log(FileBrowser.event, this.dataset.filename, embed, FileBrowser.id);
|
||||
parent.$("body").trigger(FileBrowser.event, [
|
||||
this.dataset.filename,
|
||||
embed,
|
||||
FileBrowser.id
|
||||
]);
|
||||
|
||||
});
|
||||
|
||||
if ($("#upload-image").length)
|
||||
var image_uploader = new window.AjaxUpload(
|
||||
'upload-image',
|
||||
{ action: 'profile/' + FileBrowser.nickname + '/photos/upload?response=json',
|
||||
name: 'userfile',
|
||||
responseType: 'json',
|
||||
onSubmit: function(file,ext) { $('#profile-rotator').show(); $(".error").addClass('hidden'); },
|
||||
onComplete: function(file,response) {
|
||||
if (response['error']!= undefined) {
|
||||
$(".error span").html(response['error']);
|
||||
$(".error").removeClass('hidden');
|
||||
$('#profile-rotator').hide();
|
||||
return;
|
||||
}
|
||||
location = baseurl + "/fbrowser/image/?mode=minimal"+location['hash'];
|
||||
location.reload(true);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
if ($("#upload-file").length)
|
||||
var file_uploader = new window.AjaxUpload(
|
||||
'upload-file',
|
||||
{ action: 'profile/' + FileBrowser.nickname + '/attachment/upload?response=json',
|
||||
name: 'userfile',
|
||||
responseType: 'json',
|
||||
onSubmit: function(file,ext) { $('#profile-rotator').show(); $(".error").addClass('hidden'); },
|
||||
onComplete: function(file,response) {
|
||||
if (response['error']!= undefined) {
|
||||
$(".error span").html(response['error']);
|
||||
$(".error").removeClass('hidden');
|
||||
$('#profile-rotator').hide();
|
||||
return;
|
||||
}
|
||||
location = baseurl + "/fbrowser/file/?mode=minimal"+location['hash'];
|
||||
location.reload(true);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
// @license-end
|
|
@ -166,7 +166,7 @@ $(function() {
|
|||
|
||||
/* event from comment textarea button popups */
|
||||
/* insert returned bbcode at cursor position or replace selected text */
|
||||
$("body").on("fbrowser.image.comment", function(e, filename, bbcode, id) {
|
||||
$('body').on('fbrowser.photo.comment', function(e, filename, bbcode, id) {
|
||||
$.colorbox.close();
|
||||
var textarea = document.getElementById("comment-edit-text-" +id);
|
||||
var start = textarea.selectionStart;
|
||||
|
@ -1069,7 +1069,7 @@ var Dialog = {
|
|||
* to the event handler
|
||||
*/
|
||||
doImageBrowser : function (name, id) {
|
||||
var url = Dialog._get_url("image",name,id);
|
||||
var url = Dialog._get_url('photo', name, id);
|
||||
return Dialog.show(url);
|
||||
},
|
||||
|
||||
|
@ -1086,7 +1086,7 @@ var Dialog = {
|
|||
* to the event handler
|
||||
*/
|
||||
doFileBrowser : function (name, id) {
|
||||
var url = Dialog._get_url("file",name,id);
|
||||
var url = Dialog._get_url('attachment', name, id);
|
||||
return Dialog.show(url);
|
||||
},
|
||||
|
||||
|
@ -1095,7 +1095,7 @@ var Dialog = {
|
|||
if (id !== undefined) {
|
||||
hash = hash + "-" + id;
|
||||
}
|
||||
return baseurl + "/fbrowser/"+type+"/?mode=minimal#"+hash;
|
||||
return 'media/' + type + '/browser?mode=minimal#' + hash;
|
||||
},
|
||||
|
||||
_get_size: function() {
|
||||
|
|
|
@ -0,0 +1,156 @@
|
|||
// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPLv3-or-later
|
||||
/**
|
||||
* Filebrowser - Friendica Communications Server
|
||||
*
|
||||
* Copyright (c) 2010-2021, the Friendica project
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This code handle user interaction for image/file upload/browser dialog.
|
||||
* Is loaded from filebrowser_plain.tpl
|
||||
*
|
||||
* To load filebrowser in colorbox, call
|
||||
*
|
||||
* Dialog.doImageBrowser(eventname, id);
|
||||
*
|
||||
* or
|
||||
*
|
||||
* Dialog.doFileBrowser(eventname, id);
|
||||
*
|
||||
* where:
|
||||
*
|
||||
* eventname: event name to catch return value
|
||||
* id: id returned to event handler
|
||||
*
|
||||
* When user select an item, an event in fired in parent page, on body element
|
||||
* The event is named
|
||||
*
|
||||
* fbrowser.<type>.[<eventname>]
|
||||
*
|
||||
* <type> will be one of "image" or "file", and the event handler will
|
||||
* get the following params:
|
||||
*
|
||||
* filename: filename of item chosen by user
|
||||
* embed: bbcode to embed element into posts
|
||||
* id: id from caller code
|
||||
*
|
||||
* example:
|
||||
*
|
||||
* // open dialog for select an image for a textarea with id "myeditor"
|
||||
* var id="myeditor";
|
||||
* Dialog.doImageBrowser("example", id);
|
||||
*
|
||||
* // setup event handler to get user selection
|
||||
* $("body").on("fbrowser.image.example", function(event, filename, bbcode, id) {
|
||||
* // close colorbox
|
||||
* $.colorbox.close();
|
||||
* // replace textarea text with bbcode
|
||||
* $(id).value = bbcode;
|
||||
* });
|
||||
**/
|
||||
const Browser = {
|
||||
nickname: '',
|
||||
type: '',
|
||||
event: '',
|
||||
id: null,
|
||||
|
||||
init: function (nickname, type) {
|
||||
Browser.nickname = nickname;
|
||||
Browser.type = type;
|
||||
Browser.event = 'fbrowser.' + type;
|
||||
if (location['hash'] !== '') {
|
||||
const h = location['hash'].replace('#', '');
|
||||
Browser.event = Browser.event + '.' + h.split('-')[0];
|
||||
Browser.id = h.split('-')[1];
|
||||
}
|
||||
|
||||
$('.error a.close').on('click', function (e) {
|
||||
e.preventDefault();
|
||||
$('.error').addClass('hidden');
|
||||
});
|
||||
|
||||
$('.folders a, .path a').on('click', function (e) {
|
||||
e.preventDefault();
|
||||
location.href = Browser._getUrl("minimal", location['hash'], this.dataset.folder);
|
||||
location.reload();
|
||||
});
|
||||
|
||||
$(".photo-album-photo-link").on('click', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
let embed = '';
|
||||
if (Browser.type === "photo") {
|
||||
embed = '[url=' + this.dataset.link + '][img=' + this.dataset.img + ']' + this.dataset.alt + '[/img][/url]';
|
||||
}
|
||||
if (Browser.type === "attachment") {
|
||||
embed = '[attachment]' + this.dataset.link + '[/attachment]';
|
||||
}
|
||||
parent.$('body').trigger(Browser.event, [
|
||||
this.dataset.filename,
|
||||
embed,
|
||||
Browser.id
|
||||
]);
|
||||
|
||||
});
|
||||
|
||||
if ($('#upload-photo').length) {
|
||||
new window.AjaxUpload(
|
||||
'upload-photo',
|
||||
{
|
||||
action: 'media/photo/upload?response=json',
|
||||
name: 'userfile',
|
||||
responseType: 'json',
|
||||
onSubmit: function (file, ext) {
|
||||
$('#profile-rotator').show();
|
||||
$('.error').addClass('hidden');
|
||||
},
|
||||
onComplete: function (file, response) {
|
||||
if (response['error'] !== undefined) {
|
||||
$('.error span').html(response['error']);
|
||||
$('.error').removeClass('hidden');
|
||||
$('#profile-rotator').hide();
|
||||
return;
|
||||
}
|
||||
location.href = Browser._getUrl("minimal", location['hash']);
|
||||
location.reload();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
if ($('#upload-attachment').length) {
|
||||
new window.AjaxUpload(
|
||||
'upload-attachment',
|
||||
{
|
||||
action: 'media/attachment/upload?response=json',
|
||||
name: 'userfile',
|
||||
responseType: 'json',
|
||||
onSubmit: function (file, ext) {
|
||||
$('#profile-rotator').show();
|
||||
$('.error').addClass('hidden');
|
||||
},
|
||||
onComplete: function (file, response) {
|
||||
if (response['error'] !== undefined) {
|
||||
$('.error span').html(response['error']);
|
||||
$('.error').removeClass('hidden');
|
||||
$('#profile-rotator').hide();
|
||||
return;
|
||||
}
|
||||
location.href = Browser._getUrl("minimal", location['hash']);
|
||||
location.reload();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
_getUrl: function (mode, hash, folder) {
|
||||
let folderValue = folder !== undefined ? folder : Browser.folder;
|
||||
let folderUrl = folderValue !== undefined ? '/' + encodeURIComponent(folderValue) : '';
|
||||
return 'media/' + Browser.type + '/browser' + folderUrl + '?mode=' + mode + hash;
|
||||
}
|
||||
};
|
||||
// @license-end
|
|
@ -8,7 +8,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: 2022.12-dev\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2022-11-23 18:16+0100\n"
|
||||
"POT-Creation-Date: 2022-11-27 00:36+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
|
@ -18,36 +18,13 @@ msgstr ""
|
|||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
|
||||
#: mod/fbrowser.php:61 src/Content/Nav.php:195 src/Module/BaseProfile.php:64
|
||||
#: view/theme/frio/theme.php:242
|
||||
msgid "Photos"
|
||||
msgstr ""
|
||||
|
||||
#: mod/fbrowser.php:119 mod/fbrowser.php:146 mod/photos.php:997
|
||||
#: mod/photos.php:1098 src/Content/Conversation.php:389
|
||||
#: src/Module/Contact/Follow.php:173 src/Module/Contact/Revoke.php:109
|
||||
#: src/Module/Contact/Unfollow.php:126 src/Module/Post/Edit.php:164
|
||||
#: src/Module/Post/Tag/Remove.php:109 src/Module/Profile/RemoteFollow.php:134
|
||||
#: src/Module/Security/TwoFactor/SignOut.php:125
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#: mod/fbrowser.php:121 mod/fbrowser.php:148
|
||||
#: src/Module/Settings/Profile/Photo/Index.php:128
|
||||
msgid "Upload"
|
||||
msgstr ""
|
||||
|
||||
#: mod/fbrowser.php:143
|
||||
msgid "Files"
|
||||
msgstr ""
|
||||
|
||||
#: mod/item.php:129 mod/item.php:133
|
||||
msgid "Unable to locate original post."
|
||||
msgstr ""
|
||||
|
||||
#: mod/item.php:179 mod/item.php:184 mod/item.php:853 mod/message.php:69
|
||||
#: mod/item.php:179 mod/item.php:184 mod/item.php:855 mod/message.php:69
|
||||
#: mod/message.php:114 mod/notes.php:44 mod/photos.php:159 mod/photos.php:884
|
||||
#: src/Module/Attach.php:56 src/Module/BaseApi.php:94
|
||||
#: src/Module/Attach.php:55 src/Module/BaseApi.php:94
|
||||
#: src/Module/BaseNotifications.php:98 src/Module/BaseSettings.php:52
|
||||
#: src/Module/Calendar/Event/API.php:88 src/Module/Calendar/Event/Form.php:84
|
||||
#: src/Module/Calendar/Event/Show.php:54 src/Module/Calendar/Export.php:62
|
||||
|
@ -62,9 +39,8 @@ msgstr ""
|
|||
#: src/Module/Notifications/Notification.php:76
|
||||
#: src/Module/Notifications/Notification.php:107
|
||||
#: src/Module/OStatus/Repair.php:60 src/Module/OStatus/Subscribe.php:66
|
||||
#: src/Module/Post/Edit.php:76 src/Module/Profile/Attachment/Upload.php:97
|
||||
#: src/Module/Profile/Common.php:55 src/Module/Profile/Contacts.php:55
|
||||
#: src/Module/Profile/Photos/Upload.php:108 src/Module/Profile/Schedule.php:39
|
||||
#: src/Module/Post/Edit.php:76 src/Module/Profile/Common.php:55
|
||||
#: src/Module/Profile/Contacts.php:55 src/Module/Profile/Schedule.php:39
|
||||
#: src/Module/Profile/Schedule.php:56 src/Module/Profile/UnkMail.php:69
|
||||
#: src/Module/Profile/UnkMail.php:121 src/Module/Profile/UnkMail.php:132
|
||||
#: src/Module/Register.php:77 src/Module/Register.php:90
|
||||
|
@ -84,23 +60,23 @@ msgstr ""
|
|||
msgid "Permission denied."
|
||||
msgstr ""
|
||||
|
||||
#: mod/item.php:328 mod/item.php:333
|
||||
#: mod/item.php:330 mod/item.php:335
|
||||
msgid "Empty post discarded."
|
||||
msgstr ""
|
||||
|
||||
#: mod/item.php:671
|
||||
#: mod/item.php:673
|
||||
msgid "Post updated."
|
||||
msgstr ""
|
||||
|
||||
#: mod/item.php:681 mod/item.php:686
|
||||
#: mod/item.php:683 mod/item.php:688
|
||||
msgid "Item wasn't stored."
|
||||
msgstr ""
|
||||
|
||||
#: mod/item.php:697
|
||||
#: mod/item.php:699
|
||||
msgid "Item couldn't be fetched."
|
||||
msgstr ""
|
||||
|
||||
#: mod/item.php:829 src/Module/Admin/Themes/Details.php:39
|
||||
#: mod/item.php:831 src/Module/Admin/Themes/Details.php:39
|
||||
#: src/Module/Admin/Themes/Index.php:59 src/Module/Debug/ItemBody.php:42
|
||||
#: src/Module/Debug/ItemBody.php:57 src/Module/Item/Feed.php:80
|
||||
msgid "Item not found."
|
||||
|
@ -414,31 +390,28 @@ msgstr ""
|
|||
#: src/Module/HCard.php:51 src/Module/Profile/Common.php:40
|
||||
#: src/Module/Profile/Common.php:51 src/Module/Profile/Contacts.php:39
|
||||
#: src/Module/Profile/Contacts.php:49 src/Module/Profile/Media.php:38
|
||||
#: src/Module/Profile/Photos/Index.php:77
|
||||
#: src/Module/Profile/Photos/Upload.php:87
|
||||
#: src/Module/Profile/RemoteFollow.php:71 src/Module/Profile/Status.php:58
|
||||
#: src/Module/Register.php:267
|
||||
#: src/Module/Profile/Photos.php:77 src/Module/Profile/RemoteFollow.php:71
|
||||
#: src/Module/Profile/Status.php:58 src/Module/Register.php:267
|
||||
msgid "User not found."
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:107 src/Module/BaseProfile.php:67
|
||||
#: src/Module/Profile/Photos/Index.php:169
|
||||
#: src/Module/Profile/Photos.php:169
|
||||
msgid "Photo Albums"
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:108 src/Module/Profile/Photos/Index.php:170
|
||||
#: src/Module/Profile/Photos/Index.php:187
|
||||
#: mod/photos.php:108 src/Module/Profile/Photos.php:170
|
||||
#: src/Module/Profile/Photos.php:187
|
||||
msgid "Recent Photos"
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:110 mod/photos.php:1066
|
||||
#: src/Module/Profile/Photos/Index.php:172
|
||||
#: src/Module/Profile/Photos/Index.php:189
|
||||
#: mod/photos.php:110 mod/photos.php:1066 src/Module/Profile/Photos.php:172
|
||||
#: src/Module/Profile/Photos.php:189
|
||||
msgid "Upload New Photos"
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:128 src/Module/BaseSettings.php:74
|
||||
#: src/Module/Profile/Photos/Index.php:153
|
||||
#: src/Module/Profile/Photos.php:153
|
||||
msgid "everybody"
|
||||
msgstr ""
|
||||
|
||||
|
@ -472,7 +445,7 @@ msgid "%1$s was tagged in %2$s by %3$s"
|
|||
msgstr ""
|
||||
|
||||
#: mod/photos.php:630 mod/photos.php:633 mod/photos.php:660
|
||||
#: src/Module/Profile/Photos/Upload.php:213
|
||||
#: src/Module/Media/Photo/Upload.php:188
|
||||
#: src/Module/Settings/Profile/Photo/Index.php:59
|
||||
#, php-format
|
||||
msgid "Image exceeds size limit of %s"
|
||||
|
@ -496,19 +469,19 @@ msgstr ""
|
|||
msgid "Image file is empty."
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:683 src/Module/Profile/Photos/Upload.php:179
|
||||
#: src/Module/Profile/Photos/Upload.php:180
|
||||
#: mod/photos.php:683 src/Module/Media/Photo/Upload.php:154
|
||||
#: src/Module/Media/Photo/Upload.php:155
|
||||
#: src/Module/Settings/Profile/Photo/Index.php:68
|
||||
msgid "Unable to process image."
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:709 src/Module/Profile/Photos/Upload.php:231
|
||||
#: mod/photos.php:709 src/Module/Media/Photo/Upload.php:206
|
||||
#: src/Module/Settings/Profile/Photo/Index.php:95
|
||||
msgid "Image upload failed."
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:795 src/Module/Conversation/Community.php:187
|
||||
#: src/Module/Directory.php:48 src/Module/Profile/Photos/Index.php:72
|
||||
#: src/Module/Directory.php:48 src/Module/Profile/Photos.php:72
|
||||
#: src/Module/Search/Index.php:64
|
||||
msgid "Public access denied."
|
||||
msgstr ""
|
||||
|
@ -517,7 +490,7 @@ msgstr ""
|
|||
msgid "No photos selected"
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:869 src/Module/Profile/Photos/Index.php:92
|
||||
#: mod/photos.php:869 src/Module/Profile/Photos.php:92
|
||||
msgid "Access to this item is restricted."
|
||||
msgstr ""
|
||||
|
||||
|
@ -550,6 +523,16 @@ msgstr ""
|
|||
msgid "Delete Album"
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:997 mod/photos.php:1098 src/Content/Conversation.php:389
|
||||
#: src/Module/Contact/Follow.php:173 src/Module/Contact/Revoke.php:109
|
||||
#: src/Module/Contact/Unfollow.php:126
|
||||
#: src/Module/Media/Attachment/Browser.php:78
|
||||
#: src/Module/Media/Photo/Browser.php:88 src/Module/Post/Edit.php:164
|
||||
#: src/Module/Post/Tag/Remove.php:109 src/Module/Profile/RemoteFollow.php:134
|
||||
#: src/Module/Security/TwoFactor/SignOut.php:125
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:1023
|
||||
msgid "Edit Album"
|
||||
msgstr ""
|
||||
|
@ -566,7 +549,7 @@ msgstr ""
|
|||
msgid "Show Oldest First"
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:1051 src/Module/Profile/Photos/Index.php:140
|
||||
#: mod/photos.php:1051 src/Module/Profile/Photos.php:140
|
||||
msgid "View Photo"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1686,6 +1669,11 @@ msgstr ""
|
|||
msgid "Your profile page"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Nav.php:195 src/Module/BaseProfile.php:64
|
||||
#: src/Module/Media/Photo/Browser.php:74 view/theme/frio/theme.php:242
|
||||
msgid "Photos"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Nav.php:195 view/theme/frio/theme.php:242
|
||||
msgid "Your photos"
|
||||
msgstr ""
|
||||
|
@ -3180,7 +3168,7 @@ msgstr ""
|
|||
msgid "[no subject]"
|
||||
msgstr ""
|
||||
|
||||
#: src/Model/Photo.php:1086 src/Module/Profile/Photos/Upload.php:223
|
||||
#: src/Model/Photo.php:1139 src/Module/Media/Photo/Upload.php:198
|
||||
msgid "Wall Photos"
|
||||
msgstr ""
|
||||
|
||||
|
@ -5265,7 +5253,7 @@ msgstr ""
|
|||
msgid "Applications"
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/Attach.php:50 src/Module/Attach.php:62
|
||||
#: src/Module/Attach.php:49 src/Module/Attach.php:61
|
||||
msgid "Item was not found."
|
||||
msgstr ""
|
||||
|
||||
|
@ -5894,10 +5882,10 @@ msgid "The contact could not be added."
|
|||
msgstr ""
|
||||
|
||||
#: src/Module/Contact/MatchInterests.php:94
|
||||
#: src/Module/Profile/Attachment/Upload.php:80
|
||||
#: src/Module/Profile/Attachment/Upload.php:102
|
||||
#: src/Module/Profile/Photos/Upload.php:113
|
||||
#: src/Module/Profile/Photos/Upload.php:162
|
||||
#: src/Module/Media/Attachment/Upload.php:80
|
||||
#: src/Module/Media/Attachment/Upload.php:85
|
||||
#: src/Module/Media/Photo/Upload.php:83 src/Module/Media/Photo/Upload.php:88
|
||||
#: src/Module/Media/Photo/Upload.php:137
|
||||
msgid "Invalid request."
|
||||
msgstr ""
|
||||
|
||||
|
@ -7129,6 +7117,38 @@ msgstr ""
|
|||
msgid "A Decentralized Social Network"
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/Media/Attachment/Browser.php:58
|
||||
#: src/Module/Media/Photo/Browser.php:59
|
||||
msgid "You need to be logged in to access this page."
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/Media/Attachment/Browser.php:75
|
||||
msgid "Files"
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/Media/Attachment/Browser.php:80
|
||||
#: src/Module/Media/Photo/Browser.php:90
|
||||
#: src/Module/Settings/Profile/Photo/Index.php:128
|
||||
msgid "Upload"
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/Media/Attachment/Upload.php:100
|
||||
msgid "Sorry, maybe your upload is bigger than the PHP configuration allows"
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/Media/Attachment/Upload.php:100
|
||||
msgid "Or - did you try to upload an empty file?"
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/Media/Attachment/Upload.php:107
|
||||
#, php-format
|
||||
msgid "File exceeds size limit of %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/Media/Attachment/Upload.php:117
|
||||
msgid "File upload failed."
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/Moderation/BaseUsers.php:72
|
||||
msgid "List of all users"
|
||||
msgstr ""
|
||||
|
@ -8134,28 +8154,11 @@ msgstr ""
|
|||
msgid "Remove"
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/Profile/Attachment/Upload.php:117
|
||||
msgid "Sorry, maybe your upload is bigger than the PHP configuration allows"
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/Profile/Attachment/Upload.php:117
|
||||
msgid "Or - did you try to upload an empty file?"
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/Profile/Attachment/Upload.php:124
|
||||
#, php-format
|
||||
msgid "File exceeds size limit of %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/Profile/Attachment/Upload.php:134
|
||||
msgid "File upload failed."
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/Profile/Contacts.php:119
|
||||
msgid "No contacts."
|
||||
msgstr ""
|
||||
|
||||
#: src/Module/Profile/Photos/Index.php:146
|
||||
#: src/Module/Profile/Photos.php:146
|
||||
msgid "View Album"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -61,11 +61,11 @@ function enableOnUser(){
|
|||
**/
|
||||
|
||||
/* callback */
|
||||
$('body').on('fbrowser.image.main', function(e, filename, embedcode, id) {
|
||||
$('body').on('fbrowser.photo.main', function(e, filename, embedcode, id) {
|
||||
$.colorbox.close();
|
||||
addeditortext(embedcode);
|
||||
});
|
||||
$('body').on('fbrowser.file.main', function(e, filename, embedcode, id) {
|
||||
$('body').on('fbrowser.attachment.main', function(e, filename, embedcode, id) {
|
||||
$.colorbox.close();
|
||||
addeditortext(embedcode);
|
||||
});
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
<!--
|
||||
This is the template used by mod/fbrowser.php
|
||||
-->
|
||||
<script type="text/javascript" src="{{$baseurl}}/view/js/ajaxupload.js?v={{$smarty.const.FRIENDICA_VERSION}}"></script>
|
||||
<script type="text/javascript" src="{{$baseurl}}/view/js/filebrowser.js?v={{$smarty.const.FRIENDICA_VERSION}}"></script>
|
||||
<script type="text/javascript" src="view/js/ajaxupload.js?v={{$smarty.const.FRIENDICA_VERSION}}"></script>
|
||||
<script type="text/javascript" src="view/js/module/media/browser.js?v={{$smarty.const.FRIENDICA_VERSION}}"></script>
|
||||
<script>
|
||||
$(function() {
|
||||
FileBrowser.init("{{$nickname}}", "{{$type}}");
|
||||
Browser.init("{{$nickname}}", "{{$type}}");
|
||||
});
|
||||
</script>
|
||||
<div class="fbrowser {{$type}}">
|
||||
|
@ -33,7 +33,7 @@
|
|||
{{foreach $files as $f}}
|
||||
<div class="photo-album-image-wrapper">
|
||||
<a href="#" class="photo-album-photo-link" data-link="{{$f.0}}" data-filename="{{$f.1}}" data-img="{{$f.2}}" data-alt="{{$f.3}}">
|
||||
<img src="{{$f.2}}">
|
||||
<img alt="{{$f.3}}" src="{{$f.1}}">
|
||||
<p>{{$f.1}}</p>
|
||||
</a>
|
||||
</div>
|
|
@ -1563,10 +1563,10 @@ textarea.comment-edit-text:focus + .comment-edit-form .preview {
|
|||
max-height: calc(100vh - 220px);
|
||||
}
|
||||
}
|
||||
.fbrowser.image .photo-album-image-wrapper {
|
||||
.fbrowser.photo .photo-album-image-wrapper {
|
||||
box-shadow: 2px 2px 5px 0px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.fbrowser.image .photo-album-image-wrapper .caption {
|
||||
.fbrowser.photo .photo-album-image-wrapper .caption {
|
||||
pointer-events: none;
|
||||
}
|
||||
.fbrowser .profile-rotator-wrapper {
|
||||
|
|
|
@ -1,264 +0,0 @@
|
|||
// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPLv3-or-later
|
||||
/**
|
||||
* Filebrowser - Friendica Communications Server
|
||||
*
|
||||
* Copyright (c) 2010-2021, the Friendica project
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This code handle user interaction for image/file upload/browser dialog.
|
||||
* Is loaded from filebrowser_plain.tpl
|
||||
*
|
||||
* To load filebrowser in colorbox, call
|
||||
*
|
||||
* Dialog.doImageBrowser(eventname, id);
|
||||
*
|
||||
* or
|
||||
*
|
||||
* Dialog.doFileBrowser(eventname, id);
|
||||
*
|
||||
* where:
|
||||
*
|
||||
* eventname: event name to catch return value
|
||||
* id: id returned to event handler
|
||||
*
|
||||
* When user select an item, an event in fired in parent page, on body element
|
||||
* The event is named
|
||||
*
|
||||
* fbrowser.<type>.[<eventname>]
|
||||
*
|
||||
* <type> will be one of "image" or "file", and the event handler will
|
||||
* get the following params:
|
||||
*
|
||||
* filemane: filename of item choosed by user
|
||||
* embed: bbcode to embed element into posts
|
||||
* id: id from caller code
|
||||
*
|
||||
* example:
|
||||
*
|
||||
* // open dialog for select an image for a textarea with id "myeditor"
|
||||
* var id="myeditor";
|
||||
* Dialog.doImageBrowser("example", id);
|
||||
*
|
||||
* // setup event handler to get user selection
|
||||
* $("body").on("fbrowser.image.example", function(event, filename, bbcode, id) {
|
||||
* // close colorbox
|
||||
* $.colorbox.close();
|
||||
* // replace textxarea text with bbcode
|
||||
* $(id).value = bbcode;
|
||||
* });
|
||||
**/
|
||||
|
||||
/*
|
||||
* IMPORTANT
|
||||
*
|
||||
* This is a modified version to work with
|
||||
* the frio theme.and bootstrap modals
|
||||
*
|
||||
* The origninal file is under:
|
||||
* js/filebrowser.js
|
||||
*
|
||||
*/
|
||||
|
||||
var FileBrowser = {
|
||||
nickname: "",
|
||||
type: "",
|
||||
event: "",
|
||||
folder: "",
|
||||
id: null,
|
||||
|
||||
init: function (nickname, type, hash) {
|
||||
FileBrowser.nickname = nickname;
|
||||
FileBrowser.type = type;
|
||||
FileBrowser.event = "fbrowser." + type;
|
||||
|
||||
if (hash !== "") {
|
||||
var h = hash.replace("#", "");
|
||||
var destination = h.split("-")[0];
|
||||
FileBrowser.id = h.split("-")[1];
|
||||
FileBrowser.event = FileBrowser.event + "." + destination;
|
||||
if (destination === "comment") {
|
||||
// Get the comment textimput field
|
||||
var commentElm = document.getElementById("comment-edit-text-" + FileBrowser.id);
|
||||
}
|
||||
}
|
||||
|
||||
console.log("FileBrowser: " + nickname, type, FileBrowser.event, FileBrowser.id);
|
||||
|
||||
FileBrowser.postLoad();
|
||||
|
||||
$(".error .close").on("click", function (e) {
|
||||
e.preventDefault();
|
||||
$(".error").addClass("hidden");
|
||||
});
|
||||
|
||||
// Click on album link
|
||||
$(".fbrowser").on("click", ".folders button, .path button", function (e) {
|
||||
e.preventDefault();
|
||||
var url =
|
||||
baseurl +
|
||||
"/fbrowser/" +
|
||||
FileBrowser.type +
|
||||
"/" +
|
||||
encodeURIComponent(this.dataset.folder) +
|
||||
"?mode=none&theme=frio";
|
||||
FileBrowser.folder = this.dataset.folder;
|
||||
|
||||
FileBrowser.loadContent(url);
|
||||
});
|
||||
|
||||
//Embed on click
|
||||
$(".fbrowser").on("click", ".photo-album-photo-link", function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
var embed = "";
|
||||
if (FileBrowser.type === "image") {
|
||||
embed = "[url=" + this.dataset.link + "][img=" + this.dataset.img + "]" + this.dataset.alt + "[/img][/url]";
|
||||
}
|
||||
if (FileBrowser.type === "file") {
|
||||
// attachment links are "baseurl/attach/id"; we need id
|
||||
embed = "[attachment]" + this.dataset.link.split("/").pop() + "[/attachment]";
|
||||
}
|
||||
|
||||
// Delete prefilled Text of the comment input
|
||||
// Note: not the best solution but function commentOpenUI don't
|
||||
// work as expected (we need a way to wait until commentOpenUI would be finished).
|
||||
// As for now we insert pieces of this function here
|
||||
if (commentElm !== null && typeof commentElm !== "undefined") {
|
||||
if (commentElm.value === "") {
|
||||
$("#comment-edit-text-" + FileBrowser.id)
|
||||
.addClass("comment-edit-text-full")
|
||||
.removeClass("comment-edit-text-empty");
|
||||
$("#comment-edit-submit-wrapper-" + FileBrowser.id).show();
|
||||
$("#comment-edit-text-" + FileBrowser.id).attr("tabindex", "9");
|
||||
$("#comment-edit-submit-" + FileBrowser.id).attr("tabindex", "10");
|
||||
}
|
||||
}
|
||||
|
||||
console.log(FileBrowser.event, this.dataset.filename, embed, FileBrowser.id);
|
||||
|
||||
$("body").trigger(FileBrowser.event, [this.dataset.filename, embed, FileBrowser.id, this.dataset.img]);
|
||||
|
||||
// Close model
|
||||
$("#modal").modal("hide");
|
||||
// Update autosize for this textarea
|
||||
autosize.update($(".text-autosize"));
|
||||
});
|
||||
|
||||
// EventListener for switching between image and file mode
|
||||
$(".fbrowser").on("click", ".fbswitcher .btn", function (e) {
|
||||
e.preventDefault();
|
||||
FileBrowser.type = this.getAttribute("data-mode");
|
||||
$(".fbrowser")
|
||||
.removeClass()
|
||||
.addClass("fbrowser " + FileBrowser.type);
|
||||
url = baseurl + "/fbrowser/" + FileBrowser.type + "?mode=none&theme=frio";
|
||||
|
||||
FileBrowser.loadContent(url);
|
||||
});
|
||||
},
|
||||
|
||||
// Initialize the AjaxUpload for the upload buttons
|
||||
uploadButtons: function () {
|
||||
if ($("#upload-image").length) {
|
||||
//AjaxUpload for images
|
||||
var image_uploader = new window.AjaxUpload("upload-image", {
|
||||
action:
|
||||
"profile/" +
|
||||
FileBrowser.nickname +
|
||||
"/photos/upload?response=json&album=" +
|
||||
encodeURIComponent(FileBrowser.folder),
|
||||
name: "userfile",
|
||||
responseType: "json",
|
||||
onSubmit: function (file, ext) {
|
||||
$(".fbrowser-content").hide();
|
||||
$(".fbrowser .profile-rotator-wrapper").show();
|
||||
$(".error").addClass("hidden");
|
||||
},
|
||||
onComplete: function (file, response) {
|
||||
if (response["error"] != undefined) {
|
||||
$(".error span").html(response["error"]);
|
||||
$(".error").removeClass("hidden");
|
||||
$(".fbrowser .profile-rotator-wrapper").hide();
|
||||
$(".fbrowser-content").show();
|
||||
return;
|
||||
}
|
||||
|
||||
// load new content to fbrowser window
|
||||
FileBrowser.loadContent(
|
||||
baseurl +
|
||||
"/fbrowser/" +
|
||||
FileBrowser.type +
|
||||
"/" +
|
||||
encodeURIComponent(FileBrowser.folder) +
|
||||
"?mode=none&theme=frio",
|
||||
);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if ($("#upload-file").length) {
|
||||
//AjaxUpload for files
|
||||
var file_uploader = new window.AjaxUpload("upload-file", {
|
||||
action: "profile/" + FileBrowser.nickname + "/attachment/upload?response=json",
|
||||
name: "userfile",
|
||||
responseType: "json",
|
||||
onSubmit: function (file, ext) {
|
||||
$(".fbrowser-content").hide();
|
||||
$(".fbrowser .profile-rotator-wrapper").show();
|
||||
$(".error").addClass("hidden");
|
||||
},
|
||||
onComplete: function (file, response) {
|
||||
if (response["error"] != undefined) {
|
||||
$(".error span").html(response["error"]);
|
||||
$(".error").removeClass("hidden");
|
||||
$(".fbrowser .profile-rotator-wrapper").hide();
|
||||
$(".fbrowser-content").show();
|
||||
return;
|
||||
}
|
||||
|
||||
var url = baseurl + "/fbrowser/" + FileBrowser.type + "?mode=none&theme=frio";
|
||||
// Load new content to fbrowser window
|
||||
FileBrowser.loadContent(url);
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
// Stuff which should be executed if ne content was loaded
|
||||
postLoad: function () {
|
||||
FileBrowser.initGallery();
|
||||
$(".fbrowser .fbswitcher .btn").removeClass("active");
|
||||
$(".fbrowser .fbswitcher [data-mode=" + FileBrowser.type + "]").addClass("active");
|
||||
// We need to add the AjaxUpload to the button
|
||||
FileBrowser.uploadButtons();
|
||||
},
|
||||
|
||||
// Load new content (e.g. change photo album)
|
||||
loadContent: function (url) {
|
||||
$(".fbrowser-content").hide();
|
||||
$(".fbrowser .profile-rotator-wrapper").show();
|
||||
|
||||
// load new content to fbrowser window
|
||||
$(".fbrowser").load(url, function (responseText, textStatus) {
|
||||
$(".profile-rotator-wrapper").hide();
|
||||
if (textStatus === "success") {
|
||||
$(".fbrowser_content").show();
|
||||
FileBrowser.postLoad();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// Initialize justified Gallery
|
||||
initGallery: function () {
|
||||
$(".fbrowser.image .fbrowser-content-container").justifiedGallery({
|
||||
rowHeight: 80,
|
||||
margins: 4,
|
||||
border: 0,
|
||||
});
|
||||
},
|
||||
};
|
||||
// @license-end
|
|
@ -82,7 +82,7 @@ $(document).ready(function () {
|
|||
});
|
||||
|
||||
// Insert filebrowser images into the input field (field_fileinput.tpl).
|
||||
$("body").on("fbrowser.image.input", function (e, filename, embedcode, id, img) {
|
||||
$("body").on("fbrowser.photo.input", function (e, filename, embedcode, id, img) {
|
||||
// Select the clicked button by it's attribute.
|
||||
var elm = $("[image-input='select']");
|
||||
// Select the input field which belongs to this button.
|
||||
|
@ -132,12 +132,12 @@ Dialog.show = function (url, title) {
|
|||
Dialog._get_url = function (type, name, id) {
|
||||
var hash = name;
|
||||
if (id !== undefined) hash = hash + "-" + id;
|
||||
return "fbrowser/" + type + "/?mode=none&theme=frio#" + hash;
|
||||
return 'media/' + type + '/browser?mode=none&theme=frio#' + hash;
|
||||
};
|
||||
|
||||
// Does load the filebrowser into the jot modal.
|
||||
Dialog.showJot = function () {
|
||||
var type = "image";
|
||||
var type = "photo";
|
||||
var name = "main";
|
||||
|
||||
var url = Dialog._get_url(type, name);
|
||||
|
@ -159,15 +159,15 @@ Dialog._load = function (url) {
|
|||
let filebrowser = document.getElementById("filebrowser");
|
||||
|
||||
// Try to fetch the hash form the url.
|
||||
let match = url.match(/fbrowser\/[a-z]+\/.*(#.*)/);
|
||||
let match = url.match(/media\/[a-z]+\/.*(#.*)/);
|
||||
if (!filebrowser || match === null) {
|
||||
return; //not fbrowser
|
||||
}
|
||||
|
||||
// Initialize the filebrowser.
|
||||
loadScript("view/js/ajaxupload.js");
|
||||
loadScript("view/theme/frio/js/filebrowser.js", function () {
|
||||
FileBrowser.init(filebrowser.dataset.nickname, filebrowser.dataset.type, match[1]);
|
||||
loadScript("view/theme/frio/js/module/media/browser.js", function () {
|
||||
Browser.init(filebrowser.dataset.nickname, filebrowser.dataset.type, match[1]);
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,250 @@
|
|||
// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPLv3-or-later
|
||||
/**
|
||||
* Filebrowser - Friendica Communications Server
|
||||
*
|
||||
* Copyright (c) 2010-2021, the Friendica project
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This code handle user interaction for photo/file upload/browser dialog.
|
||||
* Is loaded from filebrowser_plain.tpl
|
||||
*
|
||||
* To load filebrowser in colorbox, call
|
||||
*
|
||||
* Dialog.doImageBrowser(eventname, id);
|
||||
*
|
||||
* or
|
||||
*
|
||||
* Dialog.doFileBrowser(eventname, id);
|
||||
*
|
||||
* where:
|
||||
*
|
||||
* eventname: event name to catch return value
|
||||
* id: id returned to event handler
|
||||
*
|
||||
* When user select an item, an event in fired in parent page, on body element
|
||||
* The event is named
|
||||
*
|
||||
* fbrowser.<type>.[<eventname>]
|
||||
*
|
||||
* <type> will be one of "image" or "file", and the event handler will
|
||||
* get the following params:
|
||||
*
|
||||
* filename: filename of item chosen by user
|
||||
* embed: bbcode to embed element into posts
|
||||
* id: id from caller code
|
||||
*
|
||||
* example:
|
||||
*
|
||||
* // open dialog for select an image for a textarea with id "myeditor"
|
||||
* var id="myeditor";
|
||||
* Dialog.doImageBrowser("example", id);
|
||||
*
|
||||
* // setup event handler to get user selection
|
||||
* $("body").on("fbrowser.image.example", function(event, filename, bbcode, id) {
|
||||
* // close colorbox
|
||||
* $.colorbox.close();
|
||||
* // replace textarea text with bbcode
|
||||
* $(id).value = bbcode;
|
||||
* });
|
||||
**/
|
||||
|
||||
/*
|
||||
* IMPORTANT
|
||||
*
|
||||
* This is a modified version to work with
|
||||
* the frio theme and Bootstrap modals
|
||||
*
|
||||
* The original file is under:
|
||||
* js/module/media/browser.js
|
||||
*
|
||||
*/
|
||||
|
||||
var Browser = {
|
||||
nickname: '',
|
||||
type: '',
|
||||
event: '',
|
||||
folder: '',
|
||||
id: null,
|
||||
|
||||
init: function (nickname, type, hash) {
|
||||
Browser.nickname = nickname;
|
||||
Browser.type = type;
|
||||
Browser.event = 'fbrowser.' + type;
|
||||
|
||||
if (hash !== '') {
|
||||
const h = hash.replace('#', '');
|
||||
const destination = h.split('-')[0];
|
||||
Browser.id = h.split('-')[1];
|
||||
Browser.event = Browser.event + '.' + destination;
|
||||
if (destination === 'comment') {
|
||||
// Get the comment textinput field
|
||||
var commentElm = document.getElementById('comment-edit-text-' + Browser.id);
|
||||
}
|
||||
}
|
||||
|
||||
Browser.postLoad();
|
||||
|
||||
$('.error .close').on('click', function (e) {
|
||||
e.preventDefault();
|
||||
$('.error').addClass('hidden');
|
||||
});
|
||||
|
||||
// Click on album link
|
||||
$('.fbrowser').on('click', '.folders button, .path button', function (e) {
|
||||
e.preventDefault();
|
||||
let url = Browser._getUrl("none", this.dataset.folder);
|
||||
Browser.folder = this.dataset.folder;
|
||||
|
||||
Browser.loadContent(url);
|
||||
});
|
||||
|
||||
//Embed on click
|
||||
$('.fbrowser').on('click', '.photo-album-photo-link', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
let embed = '';
|
||||
if (Browser.type === 'photo') {
|
||||
embed = '[url=' + this.dataset.link + '][img=' + this.dataset.img + ']' + this.dataset.alt + '[/img][/url]';
|
||||
}
|
||||
if (Browser.type === 'attachment') {
|
||||
embed = '[attachment]' + this.dataset.link + '[/attachment]';
|
||||
}
|
||||
|
||||
// Delete prefilled Text of the comment input
|
||||
// Note: not the best solution but function commentOpenUI don't
|
||||
// work as expected (we need a way to wait until commentOpenUI would be finished).
|
||||
// As for now we insert pieces of this function here
|
||||
if (commentElm !== null && typeof commentElm !== 'undefined') {
|
||||
if (commentElm.value === '') {
|
||||
$('#comment-edit-text-' + Browser.id)
|
||||
.addClass('comment-edit-text-full')
|
||||
.removeClass('comment-edit-text-empty');
|
||||
$('#comment-edit-submit-wrapper-' + Browser.id).show();
|
||||
$('#comment-edit-text-' + Browser.id).attr('tabindex', '9');
|
||||
$('#comment-edit-submit-' + Browser.id).attr('tabindex', '10');
|
||||
}
|
||||
}
|
||||
|
||||
console.log(Browser.event, this.dataset.filename, embed, Browser.id);
|
||||
|
||||
$('body').trigger(Browser.event, [this.dataset.filename, embed, Browser.id, this.dataset.img]);
|
||||
|
||||
// Close model
|
||||
$('#modal').modal('hide');
|
||||
// Update autosize for this textarea
|
||||
autosize.update($('.text-autosize'));
|
||||
});
|
||||
|
||||
// EventListener for switching between photo and file mode
|
||||
$('.fbrowser').on('click', '.fbswitcher .btn', function (e) {
|
||||
e.preventDefault();
|
||||
Browser.type = this.getAttribute('data-mode');
|
||||
$('.fbrowser')
|
||||
.removeClass()
|
||||
.addClass('fbrowser ' + Browser.type);
|
||||
|
||||
Browser.loadContent(Browser._getUrl("none"));
|
||||
});
|
||||
},
|
||||
|
||||
// Initialize the AjaxUpload for the upload buttons
|
||||
uploadButtons: function () {
|
||||
if ($('#upload-photo').length) {
|
||||
//AjaxUpload for photos
|
||||
new window.AjaxUpload(
|
||||
'upload-photo',
|
||||
{
|
||||
action: 'media/photo/upload?response=json&album=' + encodeURIComponent(Browser.folder),
|
||||
name: 'userfile',
|
||||
responseType: 'json',
|
||||
onSubmit: function (file, ext) {
|
||||
$('.fbrowser-content').hide();
|
||||
$('.fbrowser .profile-rotator-wrapper').show();
|
||||
$('.error').addClass('hidden');
|
||||
},
|
||||
onComplete: function (file, response) {
|
||||
if (response['error'] !== undefined) {
|
||||
$('.error span').html(response['error']);
|
||||
$('.error').removeClass('hidden');
|
||||
$('.fbrowser .profile-rotator-wrapper').hide();
|
||||
$('.fbrowser-content').show();
|
||||
return;
|
||||
}
|
||||
// load new content to fbrowser window
|
||||
Browser.loadContent(Browser._getUrl("none"));
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if ($('#upload-attachment').length) {
|
||||
//AjaxUpload for files
|
||||
new window.AjaxUpload(
|
||||
'upload-attachment',
|
||||
{
|
||||
action: 'media/attachment/upload?response=json',
|
||||
name: 'userfile',
|
||||
responseType: 'json',
|
||||
onSubmit: function (file, ext) {
|
||||
$('.fbrowser-content').hide();
|
||||
$('.fbrowser .profile-rotator-wrapper').show();
|
||||
$('.error').addClass('hidden');
|
||||
},
|
||||
onComplete: function (file, response) {
|
||||
if (response["error"] !== undefined) {
|
||||
$('.error span').html(response['error']);
|
||||
$('.error').removeClass('hidden');
|
||||
$('.fbrowser .profile-rotator-wrapper').hide();
|
||||
$('.fbrowser-content').show();
|
||||
return;
|
||||
}
|
||||
// Load new content to fbrowser window
|
||||
Browser.loadContent(Browser._getUrl("none"));
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
// Stuff which should be executed if no content was loaded
|
||||
postLoad: function () {
|
||||
Browser.initGallery();
|
||||
$('.fbrowser .fbswitcher .btn').removeClass('active');
|
||||
$('.fbrowser .fbswitcher [data-mode=' + Browser.type + ']').addClass('active');
|
||||
// We need to add the AjaxUpload to the button
|
||||
Browser.uploadButtons();
|
||||
},
|
||||
|
||||
// Load new content (e.g. change photo album)
|
||||
loadContent: function (url) {
|
||||
$('.fbrowser-content').hide();
|
||||
$('.fbrowser .profile-rotator-wrapper').show();
|
||||
|
||||
// load new content to fbrowser window
|
||||
$('.fbrowser').load(url, function (responseText, textStatus) {
|
||||
$('.profile-rotator-wrapper').hide();
|
||||
if (textStatus === 'success') {
|
||||
$(".fbrowser_content").show();
|
||||
Browser.postLoad();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// Initialize justified Gallery
|
||||
initGallery: function () {
|
||||
$('.fbrowser.photo .fbrowser-content-container').justifiedGallery({
|
||||
rowHeight: 80,
|
||||
margins: 4,
|
||||
border: 0,
|
||||
});
|
||||
},
|
||||
|
||||
_getUrl: function (mode, folder) {
|
||||
let folderValue = folder !== undefined ? folder : Browser.folder;
|
||||
let folderUrl = folderValue !== undefined ? '/' + encodeURIComponent(folderValue) : '';
|
||||
return 'media/' + Browser.type + '/browser' + folderUrl + '?mode=' + mode + "&theme=frio";
|
||||
}
|
||||
};
|
||||
// @license-end
|
|
@ -6,7 +6,7 @@
|
|||
<div class="contact-entry-photo mframe" id="contact-entry-photo-{{$contact.id}}">
|
||||
|
||||
<div class="contact-photo-image-wrapper hidden-xs">
|
||||
<a href="{{if $contact.photo_menu.edit}}{{$contact.photo_menu.edit.1}}{{else}}{{$contact.url}}{{/if}}">
|
||||
<a href="{{if !empty($contact.photo_menu.edit)}}{{$contact.photo_menu.edit.1}}{{else}}{{$contact.url}}{{/if}}">
|
||||
<img class="contact-photo media-object xl" src="{{$contact.thumb}}" {{$contact.sparkle}} alt="{{$contact.name}}" />
|
||||
</a>
|
||||
</div>
|
||||
|
|
|
@ -61,13 +61,13 @@
|
|||
**/
|
||||
|
||||
/* callback */
|
||||
$('body').on('fbrowser.image.main', function(e, filename, embedcode, id) {
|
||||
$('body').on('fbrowser.photo.main', function(e, filename, embedcode, id) {
|
||||
///@todo this part isn't ideal and need to be done in a better way
|
||||
jotTextOpenUI(document.getElementById("profile-jot-text"));
|
||||
jotActive();
|
||||
addeditortext(embedcode);
|
||||
})
|
||||
.on('fbrowser.file.main', function(e, filename, embedcode, id) {
|
||||
.on('fbrowser.attachment.main', function(e, filename, embedcode, id) {
|
||||
jotTextOpenUI(document.getElementById("profile-jot-text"));
|
||||
jotActive();
|
||||
addeditortext(embedcode);
|
||||
|
|
|
@ -16,9 +16,9 @@
|
|||
{{/foreach}}
|
||||
|
||||
{{* Switch between image and file mode *}}
|
||||
<div class="fbswitcher btn-group btn-group-xs pull-right" aria-label="Switch between image and file mode">
|
||||
<button type="button" class="btn btn-default" data-mode="image" aria-label="Image Mode"><i class="fa fa-picture-o" aria-hidden="true"></i></button>
|
||||
<button type="button" class="btn btn-default" data-mode="file" aria-label="File Mode"><i class="fa fa-file-o" aria-hidden="true"></i></button>
|
||||
<div class="fbswitcher btn-group btn-group-xs pull-right" aria-label="Switch between photo and attachment mode">
|
||||
<button type="button" class="btn btn-default" data-mode="photo" aria-label="Photo Mode"><i class="fa fa-picture-o" aria-hidden="true"></i></button>
|
||||
<button type="button" class="btn btn-default" data-mode="attachment" aria-label="Attachment Mode"><i class="fa fa-file-o" aria-hidden="true"></i></button>
|
||||
</div>
|
||||
</ol>
|
||||
|
|
@ -2517,29 +2517,29 @@ footer {
|
|||
.fbrowser .list {
|
||||
padding: 10px;
|
||||
}
|
||||
.fbrowser.image .photo-album-image-wrapper {
|
||||
.fbrowser.photo .photo-album-image-wrapper {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
}
|
||||
.fbrowser.image a img {
|
||||
.fbrowser.photo a img {
|
||||
width: auto;
|
||||
height: 48px;
|
||||
}
|
||||
.fbrowser.image a p {
|
||||
.fbrowser.photo a p {
|
||||
display: none;
|
||||
}
|
||||
.fbrowser.file .photo-album-image-wrapper {
|
||||
.fbrowser.attachment .photo-album-image-wrapper {
|
||||
float: none;
|
||||
white-space: nowrap;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
.fbrowser.file img {
|
||||
.fbrowser.attachment img {
|
||||
display: inline;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
.fbrowser.file p {
|
||||
.fbrowser.attachment p {
|
||||
display: inline;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
|
|
@ -2516,29 +2516,29 @@ footer {
|
|||
.fbrowser .list {
|
||||
padding: 10px;
|
||||
}
|
||||
.fbrowser.image .photo-album-image-wrapper {
|
||||
.fbrowser.photo .photo-album-image-wrapper {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
}
|
||||
.fbrowser.image a img {
|
||||
.fbrowser.photo a img {
|
||||
width: auto;
|
||||
height: 48px;
|
||||
}
|
||||
.fbrowser.image a p {
|
||||
.fbrowser.photo a p {
|
||||
display: none;
|
||||
}
|
||||
.fbrowser.file .photo-album-image-wrapper {
|
||||
.fbrowser.attachment .photo-album-image-wrapper {
|
||||
float: none;
|
||||
white-space: nowrap;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
.fbrowser.file img {
|
||||
.fbrowser.attachment img {
|
||||
display: inline;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
.fbrowser.file p {
|
||||
.fbrowser.attachment p {
|
||||
display: inline;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
|
|
@ -2516,29 +2516,29 @@ footer {
|
|||
.fbrowser .list {
|
||||
padding: 10px;
|
||||
}
|
||||
.fbrowser.image .photo-album-image-wrapper {
|
||||
.fbrowser.photo .photo-album-image-wrapper {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
}
|
||||
.fbrowser.image a img {
|
||||
.fbrowser.photo a img {
|
||||
width: auto;
|
||||
height: 48px;
|
||||
}
|
||||
.fbrowser.image a p {
|
||||
.fbrowser.photo a p {
|
||||
display: none;
|
||||
}
|
||||
.fbrowser.file .photo-album-image-wrapper {
|
||||
.fbrowser.attachment .photo-album-image-wrapper {
|
||||
float: none;
|
||||
white-space: nowrap;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
.fbrowser.file img {
|
||||
.fbrowser.attachment img {
|
||||
display: inline;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
.fbrowser.file p {
|
||||
.fbrowser.attachment p {
|
||||
display: inline;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
|
|
@ -1673,11 +1673,11 @@ footer { height: 100px; display: table-row; }
|
|||
}
|
||||
.fbrowser .folders ul { list-style: url("icons/folder.png"); padding-left: 22px;}
|
||||
.fbrowser .list { padding: 10px; }
|
||||
.fbrowser.image .photo-album-image-wrapper { width: 48px; height: 48px; }
|
||||
.fbrowser.image a img { width: auto; height: 48px; }
|
||||
.fbrowser.image a p { display: none;}
|
||||
.fbrowser.file .photo-album-image-wrapper { float:none; white-space: nowrap; width: 100%; height: auto; }
|
||||
.fbrowser.file img { display: inline; width: 16px; height: 16px}
|
||||
.fbrowser.file p { display: inline; white-space: nowrap; }
|
||||
.fbrowser.photo .photo-album-image-wrapper { width: 48px; height: 48px; }
|
||||
.fbrowser.photo a img { width: auto; height: 48px; }
|
||||
.fbrowser.photo a p { display: none;}
|
||||
.fbrowser.attachment .photo-album-image-wrapper { float:none; white-space: nowrap; width: 100%; height: auto; }
|
||||
.fbrowser.attachment img { display: inline; width: 16px; height: 16px}
|
||||
.fbrowser.attachment p { display: inline; white-space: nowrap; }
|
||||
|
||||
.fbrowser .upload { clear: both; padding-top: 1em;}
|
||||
|
|
|
@ -3261,7 +3261,7 @@ img.photo-album-photo {
|
|||
}
|
||||
|
||||
/* upload/select popup */
|
||||
fbrowser.image .photo-album-image-wrapper { margin-left: 10px; }
|
||||
fbrowser.photo .photo-album-image-wrapper { margin-left: 10px; }
|
||||
#message-preview { margin-top: 15px; }
|
||||
#message-preview span { width: 100%; }
|
||||
#message-preview .mail-count, #message-preview .mail-delete { display:none; }
|
||||
|
|
Loading…
Reference in New Issue
Block a user