Lập trình giúp chúng ta thoải mái hơn?

Ở đây, mình nhắc đến vui vẻ thoải mái, không phải là kiếm được nhiều tiền, lòe mấy em hàng xóm bằng vài tricks, hay bla bla gì đó, mà muốn nói đến chuyện thoải mái hơn == giảm chuyện khó chịu đến với mình.

Chắc hẳn là chúng ta ít nhất tham gia 1 hoặc nhiều mạng xã hội hoặc diễn đàn nào đó. Và tất nhiên, tỷ lệ gặp những kẻ khó ưa càng cao đối với lượng thành viên càng lớn. Mình hay đọc tin ở Tinh tế, cái diễn đàn này mang tên tinh tế mà chả tinh tế chút nào, là nơi tụ tập của các thể loại fan cuồng công nghệ -_-

Và đi kèm của sự cuồng là những comment mang tính chất gây ức chế cho người đọc (facepalm). Diễn đàn này có chức năng bỏ qua comment của người trong blacklist của mình. Nhưng mà chưa đủ, mình vẫn muốn chặn nữa. Thế là mình nghĩ ngay đến 1 cái extension cho chrome.

Extension là gì?

Thế mà cũng hỏi, Google + extension là gì? phát là ra ngay. Google Chrome Extension được giới thiệu kỹ càng ở đây, nó cũng tương tự như 1 Chrome app, các bạn đọc bài Tạo Chrome app của mình ở đây cho biết thêm nếu không muốn đọc tiếng Anh, đau đầu.

Thành phần chính

Trong trường hợp này, mình chỉ cần 3 thành phần là đủ

  • manifest.json
  • thư viện jquery.js
  • file js chính của mình ten_gi_cung_duoc.js

Manifest

{
  "name": "Tên của extension",
  "version": "1.0",
  "manifest_version": 2,
  "description": "Mô tả về cái ext này",
  "permissions": [
    "tabs", "http://tinhte.vn/*", "https://tinhte.vn/*", "storage"
  ],
  "browser_action": {
    "default_title": "Silence",
    "default_icon": "icon.png"
  },
  "content_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": ["jquery.js", "ten_gi_cung_duoc.js"]
    }
  ],
}
  • name, version, description thì biết rồi nhé
  • manifest_version để là 2, tại sao ko phải là 1 à? tại vì người ta bảo bỏ 1 từ chrome 18 (chi tiết)
  • permissions: ext được sử dụng tabs, storage, chạy trên các trang có tinhte.vn, muốn chạy muôn nơi thì dùng "http://*/*", "https://*/*"
  • browser_action cho title và icon, chi tiết tại đây
  • content_scripts chi tiết tại đây, nói chung là như trên thì nó sẽ dùng jquery với cái file js của mình 😄

Jquery

Thôi cho cái link không lại bảo không nói gì.

ten_gi_cung_duoc.js

Cái này thì viết jquery thôi 😄

Trước tiên là ngó qua 1 bài post của cái trang tinhte kia phát

1.JPG

Mỗi bài comment đều có id và class là sectionMain message new, thử lấy ra tất cả các text comment bằng cách:

$('.sectionMain.message').each(function() {
    console.log($(this).find('.messageText.SelectQuoteContainer').text());
});

Cũng được, nhưng không ổn lắm vì ở đấy có chức năng Quote bài, chúng nó quote nhau thì sẽ có 1 đống html ở bên trong cái text này, ngẫm nghĩ 1 lát mình có cái này:

$('.sectionMain.message').each(function() {
    console.log($(this).find('.messageText.SelectQuoteContainer').clone().children().remove().end().text());
});

Ngon, giờ giả sử có 1 mảng những từ mà mình không muốn nó có mặt trong khi mình đọc bài, ví dụ thế này:

var muonBoQua = ['iphone vô đối', 'apple vạn tuế', 'samsung copy', 'android hơn ios']; //không chém đâu, suốt ngày nghe mấy câu này phát điên

Roài, thế này nhé, chúng ta check 1 loạt comment, thằng nào lỡ mồm nói câu nào có mấy từ trên thì xác cmn định đi:

$('.sectionMain.message').each(function() {
    var thisCommentText = $(this).find('.messageText.SelectQuoteContainer').clone().children().remove().end().text();

    muonBoQua.forEach(function(str) {
        if (thisCommentText.toLowerCase().indexOf(str) >= 0) {
            $(this).remove();
        }
    });
});

Ok, có vẻ ngon lành rồi, nhưng mà fix array list bỏ qua thế kia không ổn cho lắm, thế nên cần có thêm thành phần phụ. :v

Thành phần phụ

Thêm vào manifest.json đoạn sau:

  "background":
  {
    "scripts": ["background.js"],
    "persistent": false
  },
  "options_page": "options.html",

Tạo 1 file background.js chứa nội dung sau:

chrome.browserAction.onClicked.addListener(function (activeTab) {
    chrome.tabs.create({ url: "options.html" });
});

Cái này để làm gì ấy hả, là để ấn vào cái icon extension này trên address bar thì bật trang option.html. Còn trang option.html để làm gì thì tùy bạn :v còn mình dùng vào việc nhập và lưu những chuỗi muốn bỏ qua, thay vì fix sẵn vào code như trên kia.

Trong option.html

<input type="text" name="textMsg" class="form-control text-msg" aria-label="..." placeholder="Your custom">
<button class="insert-btn btn btn-primary">xUpdate</button>
<script src="jquery.js"></script>
<script src="options.js"></script>

Mình viết thế kia thôi, các bạn muốn trang option đẹp thì tự đi mà trang trí nhé 😄

Để lưu chuỗi này, dùng chrome.storage.sync trong chrome.storage thì dữ liệu được đồng bộ, nhưng mình không thích, mình thích dùng chrome.storage.local cơ.

Tạo 1 file option.js có nội dung sau:

    $('.insert-btn').on('click', function() {
        chrome.storage.local.get('msgList', function(result) {
            if (typeof result.msgList == 'undefined') {
                var messages = [];
            } else {
                var messages = result.msgList;
            }
            chrome.storage.local.set({'msgList': messages.concat($('.text-msg').val())});
        });
    });

Đấy là lưu, các bạn nhớ đề phòng trường hợp nhập nhiều chuỗi giống hệt nhau nhé, mình có làm 1 hàm arrayUnique() rồi nhưng không thích show 😃)

Trong file ten_gi_cung_duoc.js sửa lại 1 chút:

chrome.storage.local.get('msgList', function(result) {
    if (typeof result.msgList == 'undefined') {
        var muonBoQua = [];
    } else {
        var muonBoQua = result.msgList;
    }
});

(Nhưng mà nó không chạy ngay đâu, các bạn cần phải sửa lại 1 chút)

Cài đặt

  • Các bạn có thể vào Settings > More Tools > Extensions (Check vào ô Developer Mode) > Load Unpacked extension > chọn thư mục chứa extension vừa làm
  • Hoặc các bạn đóng gói lại (xem cách làm) rồi kéo thả cái file đóng gói đó vào chrome://extensions/

Có lẽ các bạn đọc đến đây đủ rồi, không cần đọc tiếp đoạn dưới nhé, mình không khuyến khích đọc tiếp 😄

Áp dụng tư tưởng của extension này cho 1 dịch vụ chat nhóm chẳng hạn

Ví dụ Chatwork

** Mình không khuyến khích ai đó làm việc này, bởi vì nó mang tính chất rất là tiêu cực, việc chặn tin nhắn của người nào đó trong 1 tập thể là việc vô cùng... dã man và không đúng đắn, ai đó mà biết bản thân họ bị người khác ghét và chặn tin nhắn thì chắc là đau khổ lắm**

Nghĩ cũng tội, mà thôi cũng kệ, có 1 nhà văn người Haiti đã nói rằng "người không vì mình, trời chu đất diệt", thế nên là cứ giảm chuyện khó chịu đến với mình trước đã =))

Soi qua html của trang này

2.JPG

Mỗi 1 message được gửi đến thì cái khung chat lại được render lại 1 lần, rồi đọc api của cái chatwork này thật là ngu người -_- thôi cứ táng jquery cho nó dễ ăn.

Sửa lại cái extension phía trên 1 chút, lần này không bỏ message bằng cách kiểm tra nội dung message nữa mà bằng cách kiểm tra trên người.

var muonBoQua = ['Lỗ Chí Thâm', 'Deadpool', 'Captain Boomerang', 'Green Lantern'] //mấy thằng này hay nói nhảm này

$('#_timeLine').find('._message').each(function() {
    var xxx = $(this).find('.chatName');

    if (jQuery.inArray(xxx.text(), muonBoQua) >= 0) {
        $(this).remove();
    }
});

Các bạn cần phải tính đến trường hợp người này chat 2+ message liền nhau, 1 message có .chatName và những message còn lại không có .chatName

Options

Như trên, nhưng thay vì nhập chuỗi text thì nhập tên người, hoặc, pro hơn thì chúng ta sẽ làm 1 nút, ấn vào đó sẽ tự cho người này vào danh sách đen 😄

Thêm đoạn sau:

    $('body').on('click', '.avatarSpeaker, .avatarTiny', function() {
        chrome.storage.local.get('xPeople', function(result) {
            if (typeof result.xPeople == 'undefined') {
                var xxx = [];
            } else {
                var xxx = result.xPeople;
            }

            var xName = $('.tooltipFooter').parents('._contactPanel').find('.profileTipName span').html();

            if (jQuery.inArray(xName, xxx) < 0) {
                $('.tooltipFooter').find('._profileTipButton:first').append('<div class="add-to-x-list button" data-x-name="' + xName + '">Make silence</div>');
            } else {
                $('.tooltipFooter').find('._profileTipButton:first').append('<div class="btnPrimary button" data-x-name="' + xName + '">Was Silence</div>');
            }
        });
    });

    $('body').on('click', '.add-to-x-list', function () {
        var newPerson = $(this).attr('data-x-name');
        var thisEle = $(this);

        chrome.storage.local.get('xPeople', function(result) {
            if (typeof result.xPeople == 'undefined') {
                var xxx = [];
            } else {
                var xxx = result.xPeople;
            }

            xxx.push(newPerson);
            chrome.storage.local.set({'xPeople': xxx});
            thisEle.addClass('btnPrimary').removeClass('add-to-x-list').html('Was Silence');
        });
    });

Được thế này

3.JPG

Vấn đề

  • Cần phải giải quyết là mỗi lần chat thì các message lại bị render lại, chúng ta lười + muốn ăn nhanh nên dùng Jquery, do đó cần có biện pháp để remove các msg lại sau mỗi lần render
  • Khi remove msg cần tính đến trường hợp người này chat 2+ message liền nhau, 1 message có .chatName và những message còn lại không có .chatName
  • Các vấn đề liên quan tới đạo đức, tính chất tiêu cực của sự việc (facepalm) mình làm xong cái này cũng thấy dằn vặt ghê gớm lắm -_-

Kết luận

Bỏ qua các vấn đề trên thì các bạn có thể tải và dùng thử extension này tại đây

All Rights Reserved