I want to load a local html file through chrome custom tab, is that workable? - chrome-custom-tabs

Currently I put my html file in assets, and I load it in WebView. Can I load it through chrome custom tab?

Actually there is a way.
in AndroidManifest.xml
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_paths" />
</provider>
define provider paths
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path
name="external_files"
path="." />
</paths>
And then just extract your local file to external dir
val file = File(activity.externalCacheDir, "hello.html")
val bytes = resources.openRawResource(R.raw.hello).use { it.readBytes() }
FileOutputStream(file).use { it.write(bytes) }
val uri = FileProvider.getUriForFile(activity, "${activity.packageName}.provider", file)
CustomTabsIntent.Builder()
.build()
.also { it.intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) }
.launchUrl(activity, uri)

No, it is not possible to open file:// URLs in customtabs.

Related

Configuring Firebase Dynamic Links with React Navigation

I am struggling to configure Firebase Dynamic Links with React Navigation. The dynamic link triggers successfully the App. However, it does not navigate to the correct route (screen.) I am working on Android, and have not, yet, started the more difficult (for me) iOS configuration. I am sure I got one (or more) of the configuration options wrong. I would greatly appreciate your effort and time to help.
The following works and navigates to the correct route:
adb shell am start -W -a android.intent.action.VIEW -d casualjob://InvitedEmployee com.casualjob.
The following starts the app, but does NOT navigate to the correct route:
npx uri-scheme open "https://casualjobsyd.page.link/app?link=https%3A%2F%2Fbuildwebsitepro.com.au%2Fcasualjob%2FInvitedEmployee" --android.
The link preview https://casualjobsyd.page.link/app?d=1 returns the dynamic link tree successfully.
The following command returns the correct json: https://casualjobsyd.page.link/.well-known/assetlinks.json
Firebase Console Configuration:
Dynamic Link Name: https://casualjobsyd.page.link
The Short Dynamic Link: https://casualjobsyd.page.link/app
Deep Link: https://buildwebsitepro.com.au/casualjob
AndroidManifest.xml
...
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode"
android:launchMode="singleTask"
android:windowSoftInputMode="adjustResize"
android:exported="true"
>
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="casualjob"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="http" android:host="casualjobsyd.page.link/app"/>
<data android:scheme="https" android:host="casualjobsyd.page.link/app"/>
</intent-filter>
</activity>
...
Dynamic Links are generated using the following code:
const link = await dynamicLinks().buildLink({
link: "https://buildwebsitepro.com.au/casualjob/",
domainUriPrefix: "https://casualjobsyd.page.link/app",
});
const linkSentToUser = link + "InvitedEmployee";
// result of the above is: "https://casualjobsyd.page.link/app?link=https%3A%2F%2Fbuildwebsitepro.com.au%2Fcasualjob%2FInvitedEmployee"
React Navigation Dynamic Linking Configuration:
const linking = {
prefixes: ["casualjob://", "https://casualjobsyd.page.link/app", ],
config: config,
async getInitialURL() {
const { isAvailable } = utils().playServicesAvailability;
if (isAvailable) {
const initialLink = await dynamicLinks().getInitialLink();
if (initialLink) {
return initialLink.url;
}
}
const url = await Linking.getInitialURL();
return url;
},
subscribe(listener) {
const unsubscribeFirebase = dynamicLinks().onLink(({ url }) => {
listener(url);
});
const linkingSubscription = Linking.addEventListener("url", ({ url }) => {
listener(url);
});
return () => {
unsubscribeFirebase();
linkingSubscription.remove();
};
},
};
I figured it out. The most important change is the need to add every Deep link to the Firebase Console. For the example above, I had to change the following.
The Deep Link defined on Firebase Console was: https://buildwebsitepro.com.au/casualjob
The Deep Link defined on Firebase Console should be: https://buildwebsitepro.com.au/casualjob/InvitedEmployee
Other changes need to be applied as well.
const linking = {
// The 2nd element below should be changed to look like the following.
prefixes: ["casualjob://", "https://casualjobsyd.page.link/app", ],
// ...
}
I learnt that my Androidmanifest.xml was wrong. The following is recommended by the documentation, although it did not seem to be necessary!?
<!-- Note that the android:host must be set to the domain of "your deep link," and NOT the "Dynamic Links" domain -->
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="https" android:host="buildwebsitepro.com.au" android:pathPrefix="/casualjob/" />
</intent-filter>
<!-- android:autoVerify="true" is required below -->
<!-- Note that the android:host must be set to your "Dynamic Links" domain, and not the domain of "your deep link." -->
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="https" android:host="casualjobsyd.page.link/app"/>
<data android:scheme="http" android:host="casualjobsyd.page.link/app"/>
</intent-filter>

Xamarin swap single ResourceDictionary programmatically

I'm currently trying to get custom themes working with a Xamarin App and I've found a way I can make this work the way I want it to, but it seems terribly inefficient, so figured I'd ask to see if you lot had better answers.
So here's the issue, I want to build a screen where users can change themes (there will be many, not just light/dark), and I want to swap out the current theme ResourceDictionary and replace it with the new chosen theme's ResourceDictionary. The problem is I also want the App to have other global ResourceDictionaries, and every tutorial I find recommends calling Resources.MergedDictionaries.Clear(), but that then gets rid of my other ResourceDictionaries.
Here is my Xaml, I don't want to replace DefaultButton.xaml or LinkButton.xaml, I only want to replace LightTheme.xaml.
<?xml version="1.0" encoding="utf-8" ?>
<Application xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="myTestApp.App">
<Application.Resources>
<ResourceDictionary Source="Themes/ResourceDictionaries/LightTheme.xaml" />
<ResourceDictionary Source="Styles/DefaultButton.xaml" />
<ResourceDictionary Source="Styles/LinkButton.xaml" />
</Application.Resources>
</Application>
Then in my App class I have
public void ChangeTheme(ThemeOptions theme)
{
ResourceDictionary newRes;
switch (theme)
{
case ThemeOptions.Light:
newRes = new LightTheme();
break;
case ThemeOptions.Dark:
newRes = new DarkTheme();
break;
default:
newRes = new LightTheme();
break;
}
Resources.MergedDictionaries.Clear();
Resources.Add(newRes);
}
Now obviously the DefaultButton.xaml and LinkButton.xaml ResourceDictionaries have now been cleared. I can add them back, but it seems terribly inefficient over just finding and removing the Theme. Is there an easy way to simply identify the ResourceDictionary I want to overwrite and replace that?
I believe I may have discovered the answer to my problem, but not to the original question. I created a "BundledSiteStyles" ResourceDictionary, and simply added that as a MergedDictionary to each of my themes. Then the App.xaml file only loads a theme and all the styling comes along for the ride.
So my App.xaml has no ResourceDictionaries added, then programmatically on startup I get the active theme and call my ChangeTheme function
public void ChangeTheme(ThemeOptions theme)
{
switch (theme)
{
case ThemeOptions.Light:
Resources = new LightTheme();
break;
case ThemeOptions.Dark:
Resources = new DarkTheme();
break;
default:
Resources = new LightTheme();
break;
}
}
Here is my LightTheme.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ResourceDictionary xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="myTestApp.Themes.ResourceDictionaries.LightTheme">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="../../Styles/BundledSiteStyles.xaml" />
</ResourceDictionary.MergedDictionaries>
<Color x:Key="LinkButtonBackgroundColor">Transparent</Color>
<Color x:Key="LinkButtonTextColor">Blue</Color>
<!-- Add more colours here -->
</ResourceDictionary>
And here is my BundledSiteStyles.xaml
<ResourceDictionary xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="myTestApp.Styles.BundledSiteStyles">
<ResourceDictionary.MergedDictionaries>
<!-- Add global ResourceDictionaries Here -->
<ResourceDictionary Source="DefaultButton.xaml" />
<ResourceDictionary Source="LinkButton.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
If there is a more efficient/correct way of doing this, please let me know, but for now it seems to work.
Assuming all the themes have the same keys, you can replace it by iterating through its keys, and replacing those entries in the merged dictionary.
I haven't tested, but should be something like this:
var resources = Application.Current.Resources;
foreach (var key in themes.Keys)
resources[key] = themes[key];

How to create/define a sub resource via XML in API-Platform?

I am trying to create a sub resource via XML using Api Platform.
When I define the sub resource via a annotation on the entity, everything works as expected:
Entity/SocialProfile/SocialProfile.php
/**
* #ApiSubresource()
*
* #ORM\OneToMany(
* targetEntity="SoapSyliusSocialPlugin\Entity\Follow\Follow",
* mappedBy="follower",
* cascade={ "persist", "remove" }
* )
*/
protected $following;
Everything works as expected and I can then access the sub resource via the below path:
/api/v2/social-profiles/35471/followings
But when I try define this route/endpoint via .xml like the below:
Resources/config/api_resources/SocialProfile.xml
<?xml version="1.0" ?>
<resources xmlns="https://api-platform.com/schema/metadata"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://api-platform.com/schema/metadata https://api-platform.com/schema/metadata/metadata-2.0.xsd"
>
<resource class="SoapSyliusSocialPlugin\Entity\SocialProfile\SocialProfile" shortName="SocialProfile">
<attribute name="validation_groups">sylius</attribute>
<subresourceOperations>
<subresourceOperation name="api_social_profiles_followings_get_subresource">
<attribute name="method">GET</attribute>
</subresourceOperation>
</subresourceOperations>
<property name="following" writable="false" readable="true">
<subresource resourceClass="SoapSyliusSocialPlugin\Entity\Follow\Follow" />
</property>
</resource>
</resources>
I am getting a:
404 No route found
I have tested my SocialProfile.xml file with a itemOperation & everything is working as expected.
I have updated my Resources/config/api_resources/SocialProfile.xml to look like the below, but I am still receiving a
404 route not found
<?xml version="1.0" ?>
<resources xmlns="https://api-platform.com/schema/metadata"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://api-platform.com/schema/metadata https://api-platform.com/schema/metadata/metadata-2.0.xsd"
>
<resource class="SoapSyliusSocialPlugin\Entity\SocialProfile\SocialProfile" shortName="SocialProfile">
<attribute name="validation_groups">sylius</attribute>
<itemOperations></itemOperations>
<property name="following" writable="false" readable="true">
<subresource resourceClass="SoapSyliusSocialPlugin\Entity\Follow\Follow" collection="true"/>
</property>
</resource>
</resources>
The configuration for the entity holding the subresource (SocialProfile, in this example).
<?xml version="1.0" ?>
<resources xmlns="https://api-platform.com/schema/metadata"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://api-platform.com/schema/metadata https://api-platform.com/schema/metadata/metadata-2.0.xsd"
>
<resource class="SoapSyliusSocialPlugin\Entity\SocialProfile\SocialProfile" shortName="SocialProfile">
<attribute name="validation_groups">sylius</attribute>
<property name="following" writable="false" readable="true">
<subresource resourceClass="SoapSyliusSocialPlugin\Entity\Follow\Follow" />
</property>
</resource>
</resources>
To configure things like normalization groups for the subresource, you do it in the other end of the relationship:
<?xml version="1.0" ?>
<resources xmlns="https://api-platform.com/schema/metadata"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://api-platform.com/schema/metadata https://api-platform.com/schema/metadata/metadata-2.0.xsd"
>
<resource class="SoapSyliusSocialPlugin\Entity\Follow\Follow" shortName="Follow">
<subresourceOperations>
<subresourceOperation name="api_social_profiles_followings_get_subresource">
<attribute name="method">GET</attribute>
</subresourceOperation>
</subresourceOperations>
</resource>
</resources>
Try with this. I have a few setup this way and working. If there is something wrong above should be because something does not match your class/resource names exactly, but you should be able to tweak that to fix it.
Note that in the second version of the configuration in your question you removed all itemOperations. You should have at least the basic get item operation so the library is able to build IRIs.

Stop Firebase Dynamic Links from redirecting to browser when opened from within app

We want a user to complete their profile, so an in-app message pops up and if they accept, it redirects them to the edit profile page. It's working, but it redirects to the browser, comes back the app, and then completes the navigation to the profile page. Is there a way to cut out the browser redirect?
I tried setting the intent-filter in the AndroidManifest.xml
<intent-filter>
<data android:host="#string/firebaseDynamicLinkDomain" android:scheme="http"/>
<data android:host="#string/firebaseDynamicLinkDomain" android:scheme="https"/>
</intent-filter>
Here's where we initialize
export const initialize = async () => {
try {
disposeOnLink = dynamicLinks().onLink(handleLink);
} catch (e) {
throw e;
}
};
and then handle the link
const handleLink = (link: string) => {
if (link.url === 'https://mykomae.page.link/edit-profile') {
navigateToEditProfile('profile');
}
};
So it's functional but it looks awful and I'm hoping to avoid this behavior.
This has been a while since you posted but I think you might be missing an intent filter. Just replace example.com with your domain and it should work.
https://firebase.google.com/docs/dynamic-links/android/receive#add-an-intent-filter-for-deep-links
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data
android:host="example.com"
android:scheme="https"/>
</intent-filter>

How to customize the Document List in Alfresco?

In the repository there be will different document lists.i.e there will be Data dictionary, user homes,Guest homes etc. when I change the view to "detailed view", it displays Favorite, like, comments links. where will I have to modify if I dont want to show them. Can you tell in which file i have to comment the code for not displaying those links. Thank you in Advance.
I wanted a "modular" answer to this question, this answer is to show how I handled this issue.
Context: Alfresco 4.2.f, project Maven from the org.alfresco.maven.archetype:alfresco-amp-archetype:1.1.1 archetype, I put everything in the embedded JAR when possible.
Create a module extension for share (see this blog for more details). Here is my extension file:
src/main/resources/alfresco/site-data/extensions/my-custom-extension.xml
<extension>
<modules>
<module>
<id>Main module of my custom extension</id>
<version>${project.version}</version>
<auto-deploy>true</auto-deploy>
<customizations>
<customization>
<!-- Order matters here! target before source, always! -->
<targetPackageRoot>org.alfresco</targetPackageRoot>
<sourcePackageRoot>my-custom.main</sourcePackageRoot>
</customization>
</customizations>
</module>
</modules>
</extension>
In the documentlibrary component of your module package, create this FTL in order to declare a javascript:
src/main/resources/alfresco/site-webscripts/my-custom/main/components/documentlibrary/documentlist-v2.get.html.ftl
<#-- Add a Javascript declaration -->
<#markup id="my-custom-js" target="js" action="after">
<#script type="text/javascript" group="documentlibrary"
src="${url.context}/res/my-custom/main/components/documentlibrary/documentlist.js"/>
</#>
In the resources (META-INF), under documentlibrary component, create the Javascript:
src/main/resources/META-INF/my-custom/main/components/documentlibrary/documentlist.js
YAHOO.lang.augmentObject(Alfresco.DocumentList.prototype, {
// Possible values: i18nLabel, lockBanner, syncFailed, syncTransientError
// date, size, name, version, description, tags, categories
myCustomDisabledRenderers: ["description", "version", "tags"],
// Possible values: favourites, likes, comments, quickShare
myCustomDisabledSocials: ["favourites", "comments", "likes", "quickShare"],
myCustomIsSocialDisabled: function(propertyName) {
return Alfresco.util.arrayContains(
this.myCustomDisabledSocials, propertyName);
},
myCustomIsRendererDisabled: function(propertyName) {
if (Alfresco.util.arrayContains(
this.myCustomDisabledRenderers, propertyName)) {
return true;
}
// Disable the social renderer when all the social features are
// disabled
if (propertyName === "social" && this.myCustomDisabledSocials.length == 4) {
return true;
}
return false;
},
/** Helper function to disable socials
* propertyName must be one of "favourites", "comments", "likes", "quickShare"
*/
myCustomDisableSocial: function(propertyName) {
if (!Alfresco.util.arrayContains(
this.myCustomDisabledSocials, propertyName)) {
this.myCustomDisabledSocials.push(propertyName);
}
},
// Custom registerRenderer for social features, originally defined in:
// webapps/share/components/documentlibrary/documentlist.js:2134
myCustomSocialRegisterRenderer: function(record) {
var jsNode = record.jsNode;
var html = "";
// Current usage of the separator variable allow to change the order
// of the different social features (the 'if' blocks below) without
// changing their content
var separator = "";
/* Favourite / Likes / Comments */
if (!this.myCustomIsSocialDisabled("favourites")) {
html += '<span class="item item-social' + separator + '">' +
Alfresco.DocumentList.generateFavourite(this, record) +
'</span>';
separator = " item-separator";
}
if (!this.myCustomIsSocialDisabled("likes")) {
html += '<span class="item item-social' + separator + '">' +
Alfresco.DocumentList.generateLikes(this, record) +
'</span>';
separator = " item-separator";
}
if (!this.myCustomIsSocialDisabled("comments") &&
jsNode.permissions.user.CreateChildren) {
html += '<span class="item item-social' + separator + '">' +
Alfresco.DocumentList.generateComments(this, record) +
'</span>';
separator = " item-separator";
}
if (!this.myCustomIsSocialDisabled("quickShare") && !record.node.isContainer &&
Alfresco.constants.QUICKSHARE_URL) {
html += '<span class="item' + separator + '">' +
Alfresco.DocumentList.generateQuickShare(this, record) +
'</span>';
separator = " item-separator";
}
return html;
},
// Overwrite registerRenderer which was originally defined in:
// webapps/share/components/documentlibrary/documentlist.js:1789
registerRenderer: function DL_registerRenderer(propertyName, renderer) {
if (Alfresco.util.isValueSet(propertyName) &&
Alfresco.util.isValueSet(renderer) &&
!this.myCustomIsRendererDisabled(propertyName)) {
if (propertyName === "social") {
this.renderers[propertyName] = this.myCustomSocialRegisterRenderer;
} else {
this.renderers[propertyName] = renderer;
}
return true;
}
return false;
}
}, true);
Then you can disable the links by updating myCustomDisabledRenderers and/or mySocialDisabledRenderers.
This way also allows you to create a module that disable (for example) the "comments on documents" or "likes on document" feature independently in only 6 easy steps!
Example, how to make a module that only disable comments on documents in 6 steps
Important: first remove the "comment disabling" from the documentlist.js of the main module.
myCustomDisabledSocials: ["favourites", "likes", "quickShare"],
Create a new module "my-custom.nocomment" with the same structure.
<extension>
<modules>
<module>
<id>Main module of my custom extension</id>
[...]
</module>
<module>
<id>No comment module of my custom extension</id>
<version>${project.version}</version>
<customizations>
<customization>
<targetPackageRoot>org.alfresco</targetPackageRoot>
<sourcePackageRoot>my-custom.nocomment</sourcePackageRoot>
</customization>
</customizations>
</module>
</modules>
</extension>
Add the FTL...
src/main/resources/alfresco/site-webscripts/my-custom/nocomment/components/documentlibrary/documentlist-v2.get.html.ftl
<#-- Add a Javascript declaration -->
<#markup id="my-custom-js" target="js" action="after">
<#script type="text/javascript" group="documentlibrary"
src="${url.context}/res/my-custom/nocomment/components/documentlibrary/documentlist.js"/>
</#>
then the Javascript...
src/main/resources/META-INF/my-custom/nocomment/components/documentlibrary/documentlist.js
Alfresco.DocumentList.prototype.myCustomDisableSocial("comment");
and then I'm happy, clap along if you feel like everything's just got smooth!
Notes:
The nocomment module depends on the main module.
It is important for the nocomment module to be loaded after the main module (in http://localhost:8080/share/page/modules/deploy).
In order for the nocomment module to be complete, you also need to disable comments from the document details page, see below.
Disable comments from the document details page
Even if, this one is documented elsewhere, I spent so much time searching around these few days that I feel like I need to be as comprehensive as possible.
src/main/resources/alfresco/site-data/extensions/my-custom-extension.xml
Add this to your my-custom.nocomment module declaration and you will get rid of the comments form and list from the document details page.
[...]
<module>
<id>No comment module of my custom extension</id>
[...]
<components>
<component>
<region-id>comments</region-id>
<source-id>document-details</source-id>
<scope>template</scope>
<sub-components>
<sub-component id="default">
<evaluations>
<evaluation id="guaranteedToHide">
<render>false</render>
</evaluation>
</evaluations>
</sub-component>
</sub-components>
</component>
</components>
</module>
[...]
src/main/resources/alfresco/site-webscripts/my-custom/nocomment/components/node-details/node-header.get.js
This is for disabling the button on the header of the document details page.
// Disable comments
for (var i = 0; i < model.widgets.length; i++) {
if (model.widgets[i].id == "NodeHeader") {
model.widgets[i].options.showComments = false;
}
}
// And since it does not work, disable comments this way too
model.showComments = "false";
Note: I did not test these snippets, they have been taken from my project after "anonymization" (basically renaming the module). Let me know if you find mistakes.
What you are looking for is more than likely generated by client-side JavaScript. You should use share-config-custom.xml to set Share to development mode, like this:
<alfresco-config>
<!-- Put Share Client in debug mode -->
<config replace="true">
<flags>
<client-debug>true</client-debug>
<client-debug-autologging>false</client-debug-autologging>
</flags>
</config>
</alfresco-config>
Then, use firebug or your browser's developer console to step through the client-side JavaScript. You should be able to find the point where the document library elements are rendered.
You can override Alfresco's client-side JavaScript components with your own components. Please put them in your own namespace to avoid collisions with Alfresco's.
I did it by commenting the {social} line in file share-documentlibrary-config.xml in share/src/alfresco/share-document-config
...
<metadata-templates>
<!-- Default (fallback) -->
<template id="default">
<line index="10" id="date">{date}{size}</line>
<line index="20" id="description" view="detailed">{description}</line>
<line index="30" id="tags" view="detailed">{tags}</line>
<line index="40" id="categories" view="detailed" evaluator="evaluator.doclib.metadata.hasCategories">{categories}</line> -->
<!-- <line index="50" id="social" view="detailed">{social}</line> -->
</template>
...
It works!
I'm not sure if I understand well your question - you're trying to hide some columns from particular view in alfresco explorer? If so, you need to edit /jsp/browse/browse.jsp file, but I think that's not a good idea. Maybe implementing your own NodePropertyResolver should be better way, have look at my older blogpost on this topic: http://www.shmoula.cz/adding-columns-to-custom-browse-jsp/
It looks like all of it is in: \opt\alfresco-4.0.d\tomcat\webapps\share\components\documentlibrary\documentlist.js
I think the trick is in this.registerRenderer("social"...) to return html before line 1981 (after favorites before likes) supposing you want to keep at least faorite

Resources