diff --git a/src/main/resources/update/gitbucket-core_4.35.xml b/src/main/resources/update/gitbucket-core_4.35.xml index 687419a..bc64857 100644 --- a/src/main/resources/update/gitbucket-core_4.35.xml +++ b/src/main/resources/update/gitbucket-core_4.35.xml @@ -11,4 +11,11 @@ + + + + + + + diff --git a/src/main/scala/gitbucket/core/controller/AccountController.scala b/src/main/scala/gitbucket/core/controller/AccountController.scala index b0aae0d..556c717 100644 --- a/src/main/scala/gitbucket/core/controller/AccountController.scala +++ b/src/main/scala/gitbucket/core/controller/AccountController.scala @@ -82,6 +82,8 @@ case class PersonalTokenForm(note: String) + case class SyntaxHighlighterThemeForm(theme: String) + val newForm = mapping( "userName" -> trim(label("User name", text(required, maxlength(100), identifier, uniqueUserName, reservedNames))), "password" -> trim(label("Password", text(required, maxlength(20)))), @@ -122,6 +124,10 @@ "note" -> trim(label("Token", text(required, maxlength(100)))) )(PersonalTokenForm.apply) + val syntaxHighlighterThemeForm = mapping( + "highlighterTheme" -> trim(label("Theme", text(required))) + )(SyntaxHighlighterThemeForm.apply) + case class NewGroupForm( groupName: String, description: Option[String], @@ -442,6 +448,29 @@ redirect(s"/${userName}/_application") }) + /** + * Display the user preference settings page + */ + get("/:userName/_preferences")(oneselfOnly { + val userName = params("userName") + val currentTheme = getAccountPreference(userName) match { + case Some(accountHighlighter) => accountHighlighter.highlighterTheme + case _ => "github-v2" + } + getAccountByUserName(userName).map { x => + html.preferences(x, currentTheme) + } getOrElse NotFound() + }) + + /** + * Update the syntax highlighter setting of user + */ + post("/:userName/_preferences/highlighter", syntaxHighlighterThemeForm)(oneselfOnly { form => + val userName = params("userName") + addOrUpdateAccountPreference(userName, form.theme) + redirect(s"/${userName}/_preferences") + }) + get("/:userName/_hooks")(managersOnly { val userName = params("userName") getAccountByUserName(userName).map { account => diff --git a/src/main/scala/gitbucket/core/controller/RepositoryViewerController.scala b/src/main/scala/gitbucket/core/controller/RepositoryViewerController.scala index a65b9d2..da73ca8 100644 --- a/src/main/scala/gitbucket/core/controller/RepositoryViewerController.scala +++ b/src/main/scala/gitbucket/core/controller/RepositoryViewerController.scala @@ -631,6 +631,7 @@ val blobRoute = get("/:owner/:repository/blob/*")(referrersOnly { repository => val (id, path) = repository.splitPath(multiParams("splat").head) val raw = params.get("raw").getOrElse("false").toBoolean + val highlighterTheme = getSyntaxHighlighterTheme() Using.resource(Git.open(getRepositoryDir(repository.owner, repository.name))) { git => val revCommit = JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(id)) @@ -650,13 +651,25 @@ hasWritePermission = hasDeveloperRole(repository.owner, repository.name, context.loginAccount), isBlame = request.paths(2) == "blame", isLfsFile = isLfsFile(git, objectId), - tabSize = info.tabSize + tabSize = info.tabSize, + highlighterTheme = highlighterTheme ) } } getOrElse NotFound() } }) + private def getSyntaxHighlighterTheme()(implicit context: Context): String = { + context.loginAccount match { + case Some(account) => + getAccountPreference(account.userName) match { + case Some(x) => x.highlighterTheme + case _ => "github-v2" + } + case _ => "github-v2" + } + } + private def isLfsFile(git: Git, objectId: ObjectId): Boolean = { JGitUtil.getObjectLoaderFromId(git, objectId)(JGitUtil.isLfsPointer).getOrElse(false) } diff --git a/src/main/scala/gitbucket/core/model/AccountPreference.scala b/src/main/scala/gitbucket/core/model/AccountPreference.scala new file mode 100644 index 0000000..6704fcf --- /dev/null +++ b/src/main/scala/gitbucket/core/model/AccountPreference.scala @@ -0,0 +1,21 @@ +package gitbucket.core.model + +trait AccountPreferenceComponent { self: Profile => + import profile.api._ + + lazy val AccountPreferences = TableQuery[AccountPreferences] + + class AccountPreferences(tag: Tag) extends Table[AccountPreference](tag, "ACCOUNT_PREFERENCE") { + val userName = column[String]("USER_NAME", O PrimaryKey) + val highlighterTheme = column[String]("HIGHLIGHTER_THEME") + def * = + (userName, highlighterTheme) <> (AccountPreference.tupled, AccountPreference.unapply) + + def byPrimaryKey(userName: String): Rep[Boolean] = this.userName === userName.bind + } +} + +case class AccountPreference( + userName: String, + highlighterTheme: String = "prettify" +) diff --git a/src/main/scala/gitbucket/core/model/Profile.scala b/src/main/scala/gitbucket/core/model/Profile.scala index 4351808..0226e03 100644 --- a/src/main/scala/gitbucket/core/model/Profile.scala +++ b/src/main/scala/gitbucket/core/model/Profile.scala @@ -70,5 +70,6 @@ with ReleaseTagComponent with ReleaseAssetComponent with AccountExtraMailAddressComponent + with AccountPreferenceComponent object Profile extends CoreProfile diff --git a/src/main/scala/gitbucket/core/service/AccountService.scala b/src/main/scala/gitbucket/core/service/AccountService.scala index af75b8c..3c256c8 100644 --- a/src/main/scala/gitbucket/core/service/AccountService.scala +++ b/src/main/scala/gitbucket/core/service/AccountService.scala @@ -1,7 +1,7 @@ package gitbucket.core.service import org.slf4j.LoggerFactory -import gitbucket.core.model.{Account, AccountExtraMailAddress, GroupMember} +import gitbucket.core.model.{Account, AccountExtraMailAddress, AccountPreference, GroupMember} import gitbucket.core.model.Profile._ import gitbucket.core.model.Profile.profile.blockingApi._ import gitbucket.core.model.Profile.dateColumnType @@ -310,6 +310,33 @@ Collaborators.filter(_.collaboratorName === userName.bind).sortBy(_.userName).map(_.userName).list.distinct } + /* + * For account preference + */ + def getAccountPreference(userName: String)( + implicit s: Session + ): Option[AccountPreference] = { + AccountPreferences filter (_.byPrimaryKey(userName)) firstOption + } + + def addAccountPreference(userName: String, highlighterTheme: String)(implicit s: Session): Unit = { + AccountPreferences insert AccountPreference(userName = userName, highlighterTheme = highlighterTheme) + } + + def updateAccountPreference(userName: String, highlighterTheme: String)(implicit s: Session): Unit = { + AccountPreferences + .filter(_.byPrimaryKey(userName)) + .map(t => t.highlighterTheme) + .update(highlighterTheme) + } + + def addOrUpdateAccountPreference(userName: String, highlighterTheme: String)(implicit s: Session): Unit = { + getAccountPreference(userName) match { + case Some(_) => updateAccountPreference(userName, highlighterTheme) + case _ => addAccountPreference(userName, highlighterTheme) + } + } + } object AccountService extends AccountService diff --git a/src/main/twirl/gitbucket/core/account/menu.scala.html b/src/main/twirl/gitbucket/core/account/menu.scala.html index b7ed72d..6603136 100644 --- a/src/main/twirl/gitbucket/core/account/menu.scala.html +++ b/src/main/twirl/gitbucket/core/account/menu.scala.html @@ -41,6 +41,11 @@ Service Hooks + @gitbucket.core.plugin.PluginRegistry().getAccountSettingMenus.map { menu => @menu(context).map { link =>