Перейти к содержанию
    

Список желаемых доработок форума

Создал новую тему для ведения истории пожеланий и доработок форума.

  • расширенная подсветка синтаксиса, в т.ч. ассемблера и т.п. языков (плагин для CKEditor на базе https://prismjs.com или его аналога);
  • формулы LaTeX (плагин для CKEditor типа https://ckeditor.com/docs/ckeditor4/latest/examples/mathjax.html);
  • добавить кнопку смены темы в шапку форума;
  • реализовать в классической теме подсветку наличия в темах ответов на свои сообщения;
  • добавить возможность реакции (like, спасибо) на посты;
  • добавить кнопки like в тему Classic;
  • убрать из темы Classic "0 участников просматривают этот форум" в непрочитанном
  • в теме Classic исправить стиль всплывающей информации о пользователе
  • Игнорирование тем
  • Цвет фона уведомления о новых событиях и сообщениях в классической теме
  • Включить опцию "Always paste as plain text." после исправления ошибки в движке. См. тему на сайте разработчиков.
  • Исправить отображение аттачей при выборе русского языка, как описано в теме:
    Спойлер

    Открыть файл system/Lang/Lang.php
    код
    $replacement = mb_substr( json_encode( $replacement ), 1, -1 );
    заменить на
    $replacement = mb_substr( json_encode( $replacement, JSON_UNESCAPED_UNICODE ), 1, -1 );

  • Исправить push-уведомления.
  • В верху странички, рядом с "Сортировка" есть кнопка "Отметить форум прочитанным". Удобно. А, вот в мобильной версии рядом с "Сортировка" ничего нет. Кнопка "Отметить форум прочитанным" - внизу страницы. Неудобно.
  • В небольшом окне (около 1200х780) сливаются слова "Последнее сообщение"  в заголовке форума (тема Neoclassic).
  • Перевод БД на UTF8MB4;
  • Проблема с цитатами в теме Electronix Classic.
  • В теме Neoclassic при отметке форума прочитанным не происходит изменения шрифта заголовков тем при просмотре активности (новых тем).
  • В теме Neoclassic кнопка "Load more activity" не рабртает. Перекидывает на верх страницы.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если говорить о расширении возможностей редактора - то хорошо бы, чтоб эти возмоожности были где-то перечислены с примерами что нажимать и что получится, и ссылка в момент редактирования на это перечисления.

Вообще нужно как-то обрисовать стиль общения под данным движком.

 

Спойлер ещё нужен? Или длинные сообщения только при цитировании не полностью показываются? 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

9 минут назад, _4afc_ сказал:

Если говорить о расширении возможностей редактора - то хорошо бы, чтоб эти возмоожности были где-то перечислены с примерами что нажимать и что получится, и ссылка в момент редактирования на это перечисления.

Руководство, конечно, написать можно. Но не сейчас, т.к. пока апгрейд ещё не был полностью завершён.
С другой стороны я не очень понимаю сложностей использования этого редактора, т.к. по своей природе он следует общепринятым редакторам типа Word/LibreOffice Writer и люди ими пользуются не изучая заранее руководство.

9 минут назад, _4afc_ сказал:

Спойлер ещё нужен? Или длинные сообщения только при цитировании не полностью показываются? 

Спойлер нужен, т.к. без него портянки кода будут засорять сообщения:

Спойлер
// SPDX-License-Identifier: GPL-2.0
#include <linux/sched/signal.h>
#include <linux/errno.h>
#include <linux/dcache.h>
#include <linux/path.h>
#include <linux/fdtable.h>
#include <linux/namei.h>
#include <linux/pid.h>
#include <linux/ptrace.h>
#include <linux/security.h>
#include <linux/file.h>
#include <linux/seq_file.h>
#include <linux/fs.h>

#include <linux/proc_fs.h>

#include "../mount.h"
#include "internal.h"
#include "fd.h"

static int seq_show(struct seq_file *m, void *v)
{
	struct files_struct *files = NULL;
	int f_flags = 0, ret = -ENOENT;
	struct file *file = NULL;
	struct task_struct *task;

	task = get_proc_task(m->private);
	if (!task)
		return -ENOENT;

	task_lock(task);
	files = task->files;
	if (files) {
		unsigned int fd = proc_fd(m->private);

		spin_lock(&files->file_lock);
		file = files_lookup_fd_locked(files, fd);
		if (file) {
			struct fdtable *fdt = files_fdtable(files);

			f_flags = file->f_flags;
			if (close_on_exec(fd, fdt))
				f_flags |= O_CLOEXEC;

			get_file(file);
			ret = 0;
		}
		spin_unlock(&files->file_lock);
	}
	task_unlock(task);
	put_task_struct(task);

	if (ret)
		return ret;

	seq_printf(m, "pos:\t%lli\nflags:\t0%o\nmnt_id:\t%i\nino:\t%lu\n",
		   (long long)file->f_pos, f_flags,
		   real_mount(file->f_path.mnt)->mnt_id,
		   file_inode(file)->i_ino);

	/* show_fd_locks() never deferences files so a stale value is safe */
	show_fd_locks(m, file, files);
	if (seq_has_overflowed(m))
		goto out;

	if (file->f_op->show_fdinfo)
		file->f_op->show_fdinfo(m, file);

out:
	fput(file);
	return 0;
}

static int proc_fdinfo_access_allowed(struct inode *inode)
{
	bool allowed = false;
	struct task_struct *task = get_proc_task(inode);

	if (!task)
		return -ESRCH;

	allowed = ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS);
	put_task_struct(task);

	if (!allowed)
		return -EACCES;

	return 0;
}

static int seq_fdinfo_open(struct inode *inode, struct file *file)
{
	int ret = proc_fdinfo_access_allowed(inode);

	if (ret)
		return ret;

	return single_open(file, seq_show, inode);
}

static const struct file_operations proc_fdinfo_file_operations = {
	.open		= seq_fdinfo_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= single_release,
};

static bool tid_fd_mode(struct task_struct *task, unsigned fd, fmode_t *mode)
{
	struct file *file;

	rcu_read_lock();
	file = task_lookup_fd_rcu(task, fd);
	if (file)
		*mode = file->f_mode;
	rcu_read_unlock();
	return !!file;
}

static void tid_fd_update_inode(struct task_struct *task, struct inode *inode,
				fmode_t f_mode)
{
	task_dump_owner(task, 0, &inode->i_uid, &inode->i_gid);

	if (S_ISLNK(inode->i_mode)) {
		unsigned i_mode = S_IFLNK;
		if (f_mode & FMODE_READ)
			i_mode |= S_IRUSR | S_IXUSR;
		if (f_mode & FMODE_WRITE)
			i_mode |= S_IWUSR | S_IXUSR;
		inode->i_mode = i_mode;
	}
	security_task_to_inode(task, inode);
}

static int tid_fd_revalidate(struct dentry *dentry, unsigned int flags)
{
	struct task_struct *task;
	struct inode *inode;
	unsigned int fd;

	if (flags & LOOKUP_RCU)
		return -ECHILD;

	inode = d_inode(dentry);
	task = get_proc_task(inode);
	fd = proc_fd(inode);

	if (task) {
		fmode_t f_mode;
		if (tid_fd_mode(task, fd, &f_mode)) {
			tid_fd_update_inode(task, inode, f_mode);
			put_task_struct(task);
			return 1;
		}
		put_task_struct(task);
	}
	return 0;
}

static const struct dentry_operations tid_fd_dentry_operations = {
	.d_revalidate	= tid_fd_revalidate,
	.d_delete	= pid_delete_dentry,
};

static int proc_fd_link(struct dentry *dentry, struct path *path)
{
	struct task_struct *task;
	int ret = -ENOENT;

	task = get_proc_task(d_inode(dentry));
	if (task) {
		unsigned int fd = proc_fd(d_inode(dentry));
		struct file *fd_file;

		fd_file = fget_task(task, fd);
		if (fd_file) {
			*path = fd_file->f_path;
			path_get(&fd_file->f_path);
			ret = 0;
			fput(fd_file);
		}
		put_task_struct(task);
	}

	return ret;
}

struct fd_data {
	fmode_t mode;
	unsigned fd;
};

static struct dentry *proc_fd_instantiate(struct dentry *dentry,
	struct task_struct *task, const void *ptr)
{
	const struct fd_data *data = ptr;
	struct proc_inode *ei;
	struct inode *inode;

	inode = proc_pid_make_inode(dentry->d_sb, task, S_IFLNK);
	if (!inode)
		return ERR_PTR(-ENOENT);

	ei = PROC_I(inode);
	ei->fd = data->fd;

	inode->i_op = &proc_pid_link_inode_operations;
	inode->i_size = 64;

	ei->op.proc_get_link = proc_fd_link;
	tid_fd_update_inode(task, inode, data->mode);

	d_set_d_op(dentry, &tid_fd_dentry_operations);
	return d_splice_alias(inode, dentry);
}

static struct dentry *proc_lookupfd_common(struct inode *dir,
					   struct dentry *dentry,
					   instantiate_t instantiate)
{
	struct task_struct *task = get_proc_task(dir);
	struct fd_data data = {.fd = name_to_int(&dentry->d_name)};
	struct dentry *result = ERR_PTR(-ENOENT);

	if (!task)
		goto out_no_task;
	if (data.fd == ~0U)
		goto out;
	if (!tid_fd_mode(task, data.fd, &data.mode))
		goto out;

	result = instantiate(dentry, task, &data);
out:
	put_task_struct(task);
out_no_task:
	return result;
}

static int proc_readfd_common(struct file *file, struct dir_context *ctx,
			      instantiate_t instantiate)
{
	struct task_struct *p = get_proc_task(file_inode(file));
	unsigned int fd;

	if (!p)
		return -ENOENT;

	if (!dir_emit_dots(file, ctx))
		goto out;

	rcu_read_lock();
	for (fd = ctx->pos - 2;; fd++) {
		struct file *f;
		struct fd_data data;
		char name[10 + 1];
		unsigned int len;

		f = task_lookup_next_fd_rcu(p, &fd);
		ctx->pos = fd + 2LL;
		if (!f)
			break;
		data.mode = f->f_mode;
		rcu_read_unlock();
		data.fd = fd;

		len = snprintf(name, sizeof(name), "%u", fd);
		if (!proc_fill_cache(file, ctx,
				     name, len, instantiate, p,
				     &data))
			goto out;
		cond_resched();
		rcu_read_lock();
	}
	rcu_read_unlock();
out:
	put_task_struct(p);
	return 0;
}

static int proc_readfd(struct file *file, struct dir_context *ctx)
{
	return proc_readfd_common(file, ctx, proc_fd_instantiate);
}

const struct file_operations proc_fd_operations = {
	.read		= generic_read_dir,
	.iterate_shared	= proc_readfd,
	.llseek		= generic_file_llseek,
};

static struct dentry *proc_lookupfd(struct inode *dir, struct dentry *dentry,
				    unsigned int flags)
{
	return proc_lookupfd_common(dir, dentry, proc_fd_instantiate);
}

/*
 * /proc/pid/fd needs a special permission handler so that a process can still
 * access /proc/self/fd after it has executed a setuid().
 */
int proc_fd_permission(struct user_namespace *mnt_userns,
		       struct inode *inode, int mask)
{
	struct task_struct *p;
	int rv;

	rv = generic_permission(&init_user_ns, inode, mask);
	if (rv == 0)
		return rv;

	rcu_read_lock();
	p = pid_task(proc_pid(inode), PIDTYPE_PID);
	if (p && same_thread_group(p, current))
		rv = 0;
	rcu_read_unlock();

	return rv;
}

const struct inode_operations proc_fd_inode_operations = {
	.lookup		= proc_lookupfd,
	.permission	= proc_fd_permission,
	.setattr	= proc_setattr,
};

static struct dentry *proc_fdinfo_instantiate(struct dentry *dentry,
	struct task_struct *task, const void *ptr)
{
	const struct fd_data *data = ptr;
	struct proc_inode *ei;
	struct inode *inode;

	inode = proc_pid_make_inode(dentry->d_sb, task, S_IFREG | S_IRUGO);
	if (!inode)
		return ERR_PTR(-ENOENT);

	ei = PROC_I(inode);
	ei->fd = data->fd;

	inode->i_fop = &proc_fdinfo_file_operations;
	tid_fd_update_inode(task, inode, 0);

	d_set_d_op(dentry, &tid_fd_dentry_operations);
	return d_splice_alias(inode, dentry);
}

static struct dentry *
proc_lookupfdinfo(struct inode *dir, struct dentry *dentry, unsigned int flags)
{
	return proc_lookupfd_common(dir, dentry, proc_fdinfo_instantiate);
}

static int proc_readfdinfo(struct file *file, struct dir_context *ctx)
{
	return proc_readfd_common(file, ctx,
				  proc_fdinfo_instantiate);
}

static int proc_open_fdinfo(struct inode *inode, struct file *file)
{
	int ret = proc_fdinfo_access_allowed(inode);

	if (ret)
		return ret;

	return 0;
}

const struct inode_operations proc_fdinfo_inode_operations = {
	.lookup		= proc_lookupfdinfo,
	.setattr	= proc_setattr,
};

const struct file_operations proc_fdinfo_operations = {
	.open		= proc_open_fdinfo,
	.read		= generic_read_dir,
	.iterate_shared	= proc_readfdinfo,
	.llseek		= generic_file_llseek,
};

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А можно, если не трудно конечно, сделать так чтобы настроить просмотр например до 50, 100, 200 и т.д. ответов в какой-то теме на одной странице? А не на по 20 (или сколько сейчас) как сейчас? Иногда не совсем (совсем не) удобно - поэтому и спросил такое.

Сейчас же (на новом движке форума) вроде есть опция настройки просмотра (с новой темы/или с коннца и т.п.)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

8 минут назад, AleksBak сказал:

А можно, если не трудно конечно, сделать так чтобы настроить просмотр например до 50, 100, 200 и т.д. ответов в какой-то теме на одной странице? А не на по 20 (или сколько сейчас) как сейчас? Иногда не совсем (совсем не) удобно - поэтому и спросил такое.

Вроде бы есть плагин https://invisioncommunity.com/files/file/10104-tb-customize-items-per-page/, который позволяет получить такой эффект, но не нравится примечание на тему возможности сломать ссылки на страницы темы. Так что пока поизучаю, но вероятность интеграции такой функции оцениваю как низкую.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А имеется ли возможность - в списке тем какого-либо раздела форума отмечать метками/значками темы, в которых имеются твои сообщения? В классической теме оформления (если это имеет значение).

На других форумах я видел такую возможность. И она, по-моему, весьма полезна.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, jcxz сказал:

А имеется ли возможность - в списке тем какого-либо раздела форума отмечать метками/значками темы, в которых имеются твои сообщения? В классической теме оформления (если это имеет значение).

Теоретически да, такая возможность есть. И в Modern/Elegant вроде это реализовано (нужно проверить). Поэтому запишу в задачи и потом изучу вопрос.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В 08.06.2022 в 12:25, makc сказал:

Теоретически да, такая возможность есть. И в Modern/Elegant вроде это реализовано (нужно проверить). Поэтому запишу в задачи и потом изучу вопрос.

Ok. Спасибо.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Предлагаю задействовать систему репутации на форуме.

Например, в виде "спасибо" под постами пользователей.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В 08.06.2022 в 15:33, Moonl1ght сказал:

Предлагаю задействовать систему репутации на форуме.

Зачем?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

7 минут назад, jcxz сказал:

Зачем?

Почему бы нет?) Скажем, в больших темах можно сразу видеть полезные сообщения, да и полезную активность того или иного пользователя.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

40 минут назад, Moonl1ght сказал:

Например, в виде "спасибо" под постами пользователей.

Думаю, в этом случае полезнее была бы фича "лайков", как в Вконтакте, например. Потому как довольно часто вижу "+1" в цитате собеседника, и этим глаз замыливается в обилии других постов. Если пост действительно несет высокую информативную нагрузку, его "залайкают" другие, тем самым человек, копающийся в теме за давностью лет, сможет оценить адекватность предлагаемого решения в обсуждении тех или иных вопросов. Я где-то такое уже видел - вроде, на формуе STM-комьюнити. Может, ошибаюсь, но точно где-то видел. Только предполагаю, что это будет проблематично сделать под соусом готового движка.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Категорически против "спасибо", "лайков" и прочей мишуры. Откровенно отвлекает от обсуждения. На форуме огромное количество хороших специалистов, которые редко пишут, но от этого ценность их сообщений нисколько не меньше. Пусть каждый лично составит "рейтинги" на основе своего опыта общения.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 часа назад, Arlleex сказал:

Думаю, в этом случае полезнее была бы фича "лайков", как в Вконтакте, например.

Она уже есть, но видимо не во всех темах:

1956264773_.thumb.png.2764be0f25aa4e83c982f5d791fcf819.png

2 часа назад, rloc сказал:

Категорически против "спасибо", "лайков" и прочей мишуры. Откровенно отвлекает от обсуждения.

Иногда это может быть полезнее, т.к. позволяет не писать односложное сообщение "Спасибо", как это делают участники чтобы поблагодарить за ценный совет. Но, повторюсь, такая возможность уже есть.

2 часа назад, Moonl1ght сказал:

Почему бы нет?) Скажем, в больших темах можно сразу видеть полезные сообщения, да и полезную активность того или иного пользователя.

Польза может быть только в возможности отфильтровать непосредственный ответ (решение) от прочего флуда. В остальном это вкусовщина.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, makc сказал:

Иногда это может быть полезнее, т.к. позволяет не писать односложное сообщение "Спасибо"...

Оу, круто! Это очень удобно именно в тех случаях, которые Вы описали.
Сейчас лайк на своем посте вижу, но не могу сам ставить - надо разбираться где это (я на теме элегант):smile:

P.S. Удобство - оно всегда кроется в мелочах, ИМХО. Дуров свой Вконтактик вылизывал 12 лет (или больше?). Не вижу ничего зазорного в экспериментах и здесь.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...